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