aglMessagePump.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "aglMessagePump.h"
00019 #include "global.h"
00020
00021 #include <eq/base/debug.h>
00022 #include <eq/base/log.h>
00023
00024 namespace eq
00025 {
00026 AGLMessagePump::AGLMessagePump()
00027 : _receiverQueue( 0 )
00028 , _needGlobalLock( true )
00029 {
00030 const OSStatus status = CreateEvent( 0, 0, 0, 0, kEventAttributeNone,
00031 &_wakeupEvent );
00032 if( status != noErr )
00033 {
00034 EQWARN << "CreateEvent failed: " << status << std::endl;
00035 EQUNREACHABLE;
00036 }
00037 }
00038
00039 AGLMessagePump::~AGLMessagePump()
00040 {
00041 ReleaseEvent( _wakeupEvent );
00042 }
00043
00044 void AGLMessagePump::postWakeup()
00045 {
00046 if( !_receiverQueue )
00047 {
00048 EQWARN << "Receiver thread not waiting?" << std::endl;
00049 return;
00050 }
00051
00052 PostEventToQueue( _receiverQueue, _wakeupEvent, kEventPriorityStandard );
00053 }
00054
00055 void AGLMessagePump::_initReceiverQueue()
00056 {
00057 if( !_receiverQueue )
00058 {
00059 _receiverQueue = GetCurrentEventQueue();
00060 _needGlobalLock = ( _receiverQueue == GetMainEventQueue( ));
00061 }
00062
00063 EQASSERTINFO( _receiverQueue == GetCurrentEventQueue(),
00064 "MessagePump::pop() called from two different threads" );
00065 }
00066
00067 void AGLMessagePump::dispatchOne()
00068 {
00069 _initReceiverQueue();
00070
00071 while( true )
00072 {
00073 EventRef event;
00074
00075 if( _needGlobalLock )
00076 Global::enterCarbon();
00077
00078 const OSStatus status = ReceiveNextEvent( 0, 0, .05 ,
00079 true, &event );
00080 if( status == noErr )
00081 {
00082 EQVERB << "Dispatch Carbon event " << event << std::endl;
00083
00084 if( !_needGlobalLock )
00085 Global::enterCarbon();
00086 const EventTargetRef target = GetEventDispatcherTarget();
00087 SendEventToEventTarget( event, target );
00088 Global::leaveCarbon();
00089
00090 ReleaseEvent( event );
00091 return;
00092 }
00093
00094 if( _needGlobalLock )
00095 Global::leaveCarbon();
00096
00097 if( status != eventLoopTimedOutErr )
00098 {
00099 EQWARN << "ReceiveNextEvent failed: " << status << std::endl;
00100 return;
00101 }
00102 }
00103 }
00104
00105 void AGLMessagePump::dispatchAll()
00106 {
00107 while( true )
00108 {
00109 EventRef event;
00110
00111 if( _needGlobalLock )
00112 Global::enterCarbon();
00113 const OSStatus status = ReceiveNextEvent( 0, 0, 0.0, true, &event );
00114
00115 if( status == eventLoopTimedOutErr )
00116 break;
00117
00118 if( status != noErr )
00119 {
00120 EQWARN << "ReceiveNextEvent failed: " << status << std::endl;
00121 break;
00122 }
00123
00124 EQVERB << "Dispatch Carbon event " << event << std::endl;
00125
00126 if( !_needGlobalLock )
00127 Global::enterCarbon();
00128 const EventTargetRef target = GetEventDispatcherTarget();
00129 SendEventToEventTarget( event, target );
00130 Global::leaveCarbon();
00131
00132 ReleaseEvent( event );
00133 }
00134
00135 if( _needGlobalLock )
00136 Global::leaveCarbon();
00137
00138
00139
00140 _initReceiverQueue();
00141 }
00142 }