diff --git a/mozilla/xpcom/threads/plevent.c b/mozilla/xpcom/threads/plevent.c index a428af3d4ef..5b9b166af8f 100644 --- a/mozilla/xpcom/threads/plevent.c +++ b/mozilla/xpcom/threads/plevent.c @@ -71,7 +71,7 @@ #if defined(XP_MAC) || defined(XP_MACOSX) #if defined(MOZ_WIDGET_COCOA) #include -#define MAC_USE_CFRUNLOOPSOURCE +#define MAC_USE_CFMESSAGEPORT #elif defined(TARGET_CARBON) #include #define MAC_USE_CARBON_EVENT @@ -172,9 +172,10 @@ struct PLEventQueue { #elif defined(XP_BEOS) port_id eventport; #elif defined(XP_MAC) || defined(XP_MACOSX) -#if defined(MAC_USE_CFRUNLOOPSOURCE) +#if defined(MAC_USE_CFMESSAGEPORT) + CFMessagePortRef mLocalMessagePort; + CFMessagePortRef mRemoteMessagePort; CFRunLoopSourceRef mRunLoopSource; - CFRunLoopRef mMainRunLoop; #elif defined(MAC_USE_CARBON_EVENT) EventHandlerUPP eventHandlerUPP; EventHandlerRef eventHandlerRef; @@ -990,11 +991,14 @@ _pl_CleanupNativeNotifier(PLEventQueue* self) #elif defined(XP_OS2) WinDestroyWindow(self->eventReceiverWindow); -#elif defined(MAC_USE_CFRUNLOOPSOURCE) +#elif defined(MAC_USE_CFMESSAGEPORT) - CFRunLoopRemoveSource(self->mMainRunLoop, self->mRunLoopSource, kCFRunLoopCommonModes); + // XXX this assumes that the event queue is on the same run loop that it was created on + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), self->mRunLoopSource, kCFRunLoopCommonModes); CFRelease(self->mRunLoopSource); - CFRelease(self->mMainRunLoop); + + CFRelease(self->mRemoteMessagePort); + CFRelease(self->mLocalMessagePort); #elif defined(MAC_USE_CARBON_EVENT) EventComparatorUPP comparator = NewEventComparatorUPP(_md_CarbonEventComparator); @@ -1298,9 +1302,18 @@ _pl_NativeNotify(PLEventQueue* self) static PRStatus _pl_NativeNotify(PLEventQueue* self) { -#if defined(MAC_USE_CFRUNLOOPSOURCE) - CFRunLoopSourceSignal(self->mRunLoopSource); - CFRunLoopWakeUp(self->mMainRunLoop); +#if defined(MAC_USE_CFMESSAGEPORT) + // send a request with no data (just to wake the receiver) + SInt32 err = CFMessagePortSendRequest(self->mRemoteMessagePort, + 0, // msgid (arbitrary value; unused) + NULL, // data (none) + 1.0, // sendTimeout (1 second) + 0.0, // rcvTimeout + NULL, // replyMode (no reply expected) + NULL // returnData (none) + ); + PR_ASSERT(err == kCFMessagePortSuccess); + #elif defined(MAC_USE_CARBON_EVENT) OSErr err; EventRef newEvent; @@ -1615,11 +1628,12 @@ static void _md_CreateEventQueue( PLEventQueue *eventQueue ) } /* end _md_CreateEventQueue() */ #endif /* (defined(XP_UNIX) && !defined(XP_MACOSX)) || defined(XP_BEOS) */ -#if defined(MAC_USE_CFRUNLOOPSOURCE) -static void _md_EventReceiverProc(void *info) +#if defined(MAC_USE_CFMESSAGEPORT) +static CFDataRef _md_EventReceiverProc(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) { PLEventQueue *queue = (PLEventQueue*)info; PL_ProcessPendingEvents(queue); + return NULL; } #elif defined(MAC_USE_CARBON_EVENT) @@ -1667,21 +1681,35 @@ static pascal Boolean _md_CarbonEventComparator(EventRef inEvent, #if defined(XP_MAC) || defined(XP_MACOSX) static void _md_CreateEventQueue( PLEventQueue *eventQueue ) { -#if defined(MAC_USE_CFRUNLOOPSOURCE) - CFRunLoopSourceContext sourceContext = {0}; - sourceContext.version = 0; - sourceContext.info = (void*)eventQueue; - sourceContext.perform = _md_EventReceiverProc; +#if defined(MAC_USE_CFMESSAGEPORT) + CFMessagePortContext portContext = { + 0, + (void*)eventQueue, + NULL, NULL, NULL + }; + + // create the local port (the receiver). Note that message ports are machine-wide, + // so we include the pid and event queue pointer in the name. + CFStringRef portName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, + CFSTR("plevents_%d_%p"), getpid(), eventQueue); + eventQueue->mLocalMessagePort = CFMessagePortCreateLocal(kCFAllocatorDefault, portName, + _md_EventReceiverProc, &portContext, NULL); + + PR_ASSERT(eventQueue->mLocalMessagePort); + + // now create the remote port (the sender) + eventQueue->mRemoteMessagePort = CFMessagePortCreateRemote(kCFAllocatorDefault, portName); + PR_ASSERT(eventQueue->mRemoteMessagePort); + + CFRelease(portName); // make a run loop source - eventQueue->mRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0 /* order */, &sourceContext); + eventQueue->mRunLoopSource = CFMessagePortCreateRunLoopSource(kCFAllocatorDefault, + eventQueue->mLocalMessagePort, 0 /* order: ignored */); PR_ASSERT(eventQueue->mRunLoopSource); - eventQueue->mMainRunLoop = CFRunLoopGetCurrent(); - CFRetain(eventQueue->mMainRunLoop); - // and add it to the run loop. - CFRunLoopAddSource(eventQueue->mMainRunLoop, eventQueue->mRunLoopSource, kCFRunLoopCommonModes); + CFRunLoopAddSource(CFRunLoopGetCurrent(), eventQueue->mRunLoopSource, kCFRunLoopCommonModes); #elif defined(MAC_USE_CARBON_EVENT) eventQueue->eventHandlerUPP = NewEventHandlerUPP(_md_EventReceiverProc);