CVS update: /common/system/platform/mac/, /common/system/pub/platform/mac/

CVS update: /common/system/platform/mac/, /common/system/pub/platform/mac/

bobclark at helixcommunity.org bobclark at helixcommunity.org
Sat Jan 25 02:29:03 PST 2003


User: bobclark
Date: 03/01/24 18:29:03

Modified
 /common/system/platform/mac/
  carbthrd.cpp
 /common/system/pub/platform/mac/
  carbthrd.h

Log
 adding manual events and other enhancements to carbon synchronization classes

File Changes:

Directory: /common/system/platform/mac/
=======================================

File [changed]: carbthrd.cpp
Url: https://common.helixcommunity.org/source/browse/common/system/platform/mac/carbthrd.cpp.diff?r1=1.2&r2=1.3
Delta lines:  +195 -2
---------------------
--- carbthrd.cpp	18 Nov 2002 21:02:56 -0000	1.2
+++ carbthrd.cpp	25 Jan 2003 02:29:03 -0000	1.3
@@ -41,6 +41,8 @@
 HXCarbonThread::HXCarbonThread()
   : m_mpTaskID(NULL)
   , m_mpQueueID(NULL)
+  , m_pQueueMutex(NULL)
+  , m_pQueuePostSemaphore(kInvalidID)
   , m_mpInternalTerminationNotificationQueueID(NULL)
 {
     // xxxbobclark there's a kludgey main app thread wrapper thingie
@@ -48,8 +50,9 @@
     // HXCarbonThread gets used without HXCarbonThread::CreateThread()
     // being called... but it requires m_mpQueueID. So we create it in
     // the ctor.
+    HXMutex::MakeMutex(m_pQueueMutex);
+    ::MPCreateSemaphore(INT_MAX, 0, &m_pQueuePostSemaphore);
     OSStatus osResult = MPCreateQueue(&m_mpQueueID);
-    
 }
 
 HXCarbonThread::~HXCarbonThread()
@@ -59,6 +62,8 @@
     // xxxbobclark should I remove the queue here if it exists?
     HX_ASSERT(m_mpQueueID == NULL);
     HX_ASSERT(m_mpTaskID == NULL);
+    HX_ASSERT(m_pQueueMutex == NULL);
+    HX_ASSERT(m_pQueuePostSemaphore == kInvalidID);
 }
 
 HX_RESULT
@@ -180,6 +185,14 @@
 	m_mpQueueID = NULL;
     }
     
+    HX_DELETE(m_pQueueMutex);
+    
+    if (m_pQueuePostSemaphore != kInvalidID)
+    {
+	::MPDeleteSemaphore(m_pQueuePostSemaphore);
+	m_pQueuePostSemaphore = kInvalidID;
+    }
+    
     if (osStatus != noErr) retval = HXR_FAIL;
     
     return retval;
@@ -212,8 +225,11 @@
     
     HX_ASSERT(m_mpQueueID != NULL);
     
+    m_pQueueMutex->Lock();
     OSStatus osStatus = ::MPNotifyQueue(m_mpQueueID, (void*)pMsg->m_ulMessage,
 			(void*)pMsg->m_pParam1, (void*)pMsg->m_pParam2);
+    ::MPSignalSemaphore(m_pQueuePostSemaphore);
+    m_pQueueMutex->Unlock();
     
     if (osStatus != noErr)
     {
@@ -236,7 +252,15 @@
     void* param2;
     void* param3;
     
-    OSStatus osStatus = ::MPWaitOnQueue(m_mpQueueID, &param1, &param2, &param3, kDurationForever);
+    OSStatus osStatus = ::MPWaitOnSemaphore(m_pQueuePostSemaphore, kDurationForever);
+    
+    if (osStatus == noErr)
+    {
+	m_pQueueMutex->Lock();
+	osStatus = ::MPWaitOnQueue(m_mpQueueID, &param1, &param2, &param3, kDurationImmediate);
+	HX_ASSERT(osStatus == noErr);
+	m_pQueueMutex->Unlock();
+    }
     
     if (osStatus == noErr)
     {
@@ -271,7 +295,9 @@
     void* param2;
     void* param3;
     
+    m_pQueueMutex->Lock();
     OSStatus osStatus = ::MPWaitOnQueue(m_mpQueueID, &param1, &param2, &param3, kDurationImmediate);
+    m_pQueueMutex->Unlock();
     
     if (osStatus == noErr)
     {
@@ -298,6 +324,93 @@
 }
 
 HX_RESULT
+HXCarbonThread::PeekMessageMatching( HXThreadMessage* pMsg,
+                                      HXThreadMessage* pMatch,
+                                      BOOL bRemoveMessage )
+{
+    // we're going to create a temp queue, copy each message from the main queue into it until we find
+    // a matching message, then copy the rest
+	
+    HX_ASSERT(m_mpQueueID != kInvalidID);
+    HX_RESULT retval = HXR_OK;
+    
+    HX_ASSERT(pMsg);
+    if (!pMsg) return HXR_FAIL;
+    
+    HX_ASSERT(pMatch);
+    if (!pMatch) return HXR_FAIL;
+    
+    void* param1;
+    void* param2;
+    void* param3;
+    
+    OSStatus osResult;
+    
+    m_pQueueMutex->Lock();
+
+    // create a temp queue, all messages will be copied into this queue 
+    // (except matching message if bRemoveMessage == TRUE)
+    MPQueueID tempQ;
+    osResult = ::MPCreateQueue(&tempQ);
+    HX_ASSERT(tempQ != kInvalidID);
+
+    BOOL foundAMatch = FALSE;
+    
+    const BOOL bSkipMessage  = (pMatch->m_ulMessage == 0);
+    const BOOL bSkipParam1   = (pMatch->m_pParam1 == NULL);
+    const BOOL bSkipParam2   = (pMatch->m_pParam2 == NULL);
+    while((osResult = ::MPWaitOnQueue(m_mpQueueID, &param1, &param2, &param3, kDurationImmediate)) == noErr)
+    {        
+        // does it match?
+        if( ( bSkipMessage || pMatch->m_ulMessage == (UINT32) param1 ) &&
+            ( bSkipParam1  || pMatch->m_pParam1 == param2 ) &&
+            ( bSkipParam2  || pMatch->m_pParam2 == param3 ) )
+        {
+            foundAMatch = TRUE;
+            break;
+        }
+        
+        // copy it into the temp queue
+        ::MPNotifyQueue(tempQ, param1, param2, param3);
+    }
+    
+    if( foundAMatch )
+    {
+	// copy the found message to the out variable
+	pMsg->m_ulMessage = (UINT32)param1;
+	pMsg->m_pParam1 = param2;
+	pMsg->m_pParam2 = param3;
+		
+	// if we aren't supposed to remove it, re-post it
+	if( !bRemoveMessage )
+	{
+	    ::MPNotifyQueue(tempQ, param1, param2, param3);
+	}
+		
+	// now copy any remaining messages
+        while((osResult = ::MPWaitOnQueue(m_mpQueueID, &param1, &param2, &param3, kDurationImmediate)) == noErr)
+        {
+            ::MPNotifyQueue(tempQ, param1, param2, param3);
+        }
+        
+        retval = HXR_OK;
+    }
+    else
+    {
+        pMsg->m_ulMessage = 0;
+        retval = HXR_FAIL;
+    }
+    
+    // now that the original queue is empty, throw it away and keep the copy that we made
+    ::MPDeleteQueue(m_mpQueueID);
+    m_mpQueueID = tempQ;
+
+    m_pQueueMutex->Unlock();
+
+    return retval;
+}
+
+HX_RESULT
 HXCarbonThread::DispatchMessage(HXThreadMessage* pMsg)
 {
     HX_RESULT retval = HXR_NOTIMPL;
@@ -385,6 +498,86 @@
     
     return retval;
 }
+
+// HXCarbonManualEvent
+
+HXCarbonManualEvent::HXCarbonManualEvent(const char* pEventName)
+ : m_pMutex(NULL)
+ , m_bIsSignalled(FALSE)
+ , m_InternalSemaphoreID(NULL)
+{
+    HXMutex::MakeMutex(m_pMutex);
+    OSStatus osStatus = ::MPCreateSemaphore(1, 0, &m_InternalSemaphoreID);
+}
+
+HXCarbonManualEvent::~HXCarbonManualEvent()
+{
+    OSStatus osStatus = ::MPDeleteSemaphore(m_InternalSemaphoreID);
+    m_InternalSemaphoreID = NULL;
+    HX_DELETE(m_pMutex);
+}
+
+HX_RESULT
+HXCarbonManualEvent::SignalEvent()
+{
+    m_pMutex->Lock();
+    m_bIsSignalled = TRUE;
+    ::MPSignalSemaphore(m_InternalSemaphoreID); // in case we're waiting.
+    m_pMutex->Unlock();
+    
+    return HXR_OK;
+}
+
+HX_RESULT
+HXCarbonManualEvent::ResetEvent()
+{
+    m_pMutex->Lock();
+    m_bIsSignalled = FALSE;
+    ::MPWaitOnSemaphore(m_InternalSemaphoreID, kDurationImmediate); // just clear it out...
+    m_pMutex->Unlock();
+    return HXR_OK;
+}
+
+HX_RESULT
+HXCarbonManualEvent::Wait(UINT32 uTimeoutPeriod)
+{
+    BOOL bDone = FALSE;
+    
+    HX_RESULT retVal = HXR_OK;
+    
+    while (!bDone)
+    {
+	m_pMutex->Lock();
+	BOOL bIsSignalled = m_bIsSignalled;
+	m_pMutex->Unlock();
+	if (bIsSignalled)
+	{
+	    bDone = TRUE;
+	}
+	else
+	{
+	    // xxxbobclark rely on MP semaphore
+	    
+	    Duration timeout = ( uTimeoutPeriod == ALLFS ) ? kDurationForever : ( uTimeoutPeriod * kDurationMillisecond );
+	    
+	    OSStatus osStatus = ::MPWaitOnSemaphore(m_InternalSemaphoreID, timeout);
+	    bDone = TRUE;
+	    if (osStatus == kMPTimeoutErr)
+	    {
+		retVal = HXR_WOULD_BLOCK;
+	    }
+	}
+    }
+
+    return retVal;
+}
+
+void*
+HXCarbonManualEvent::GetEventHandle	(void)
+{
+    return (void*)this;
+}
+
 
 // HXCarbonMutex
 

Directory: /common/system/pub/platform/mac/
===========================================

File [changed]: carbthrd.h
Url: https://common.helixcommunity.org/source/browse/common/system/pub/platform/mac/carbthrd.h.diff?r1=1.2&r2=1.3
Delta lines:  +23 -5
--------------------
--- carbthrd.h	18 Nov 2002 21:02:56 -0000	1.2
+++ carbthrd.h	25 Jan 2003 02:29:03 -0000	1.3
@@ -41,11 +41,6 @@
 #ifndef _HX_CARBON_THREAD
 #define _HX_CARBON_THREAD
 
-// NOTE WELL:  Mac Threads are cooperative and not interrupt-safe.
-// So be sure each thread calls YieldTimeSlice to allow other threads
-// to run, and do not call any of the yielding or blocking methods 
-// (YieldTimeSlice, Lock, Wait, GetMessage) at interrupt or deferred-task time.
-
 class HXCarbonThread : public HXThread
 {
 public:
@@ -79,10 +74,14 @@
 
     virtual HX_RESULT	PeekMessage(HXThreadMessage* pMsg, UINT32 ulMsgFilterMix = 0, UINT32 ulMsgFilterMax = 0, BOOL bRemoveMessage = TRUE);
 
+    virtual HX_RESULT	PeekMessageMatching(HXThreadMessage* pMsg, HXThreadMessage* pMatch, BOOL bRemoveMessage);
+
     virtual HX_RESULT	DispatchMessage(HXThreadMessage* pMsg);
 
 private:
 
+    HXMutex*	m_pQueueMutex;
+    MPSemaphoreID	m_pQueuePostSemaphore;
     MPTaskID	m_mpTaskID;
     MPQueueID	m_mpQueueID;
     MPQueueID	m_mpInternalTerminationNotificationQueueID;
@@ -106,6 +105,25 @@
 
     MPSemaphoreID	m_mpSemaphoreID;
     BOOL		m_IsManuallyReset;
+};
+
+class HXCarbonManualEvent : public HXEvent
+{
+public:
+
+			HXCarbonManualEvent(const char* pEventName = NULL);
+    virtual		~HXCarbonManualEvent(void);
+    
+    virtual HX_RESULT	SignalEvent	(void);
+    virtual HX_RESULT	ResetEvent	(void);
+    virtual void*	GetEventHandle	(void);
+    virtual HX_RESULT	Wait		(UINT32 uTimeoutPeriod = ALLFS);
+    
+private:
+
+    HXMutex*		m_pMutex;
+    BOOL		m_bIsSignalled;
+    MPSemaphoreID	m_InternalSemaphoreID;
 };
 
 class HXCarbonMutex : public HXMutex




---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe at common.helixcommunity.org
For additional commands, e-mail: cvs-help at common.helixcommunity.org




More information about the Common-cvs mailing list
 

Site Map   |   Terms of Use   |   Privacy Policy   |   Contact Us

Copyright © 1995-2007 RealNetworks, Inc. All rights reserved. RealNetworks and Helix are trademarks of RealNetworks.
All other trademarks or registered trademarks are the property of their respective holders.