diff --git a/mozilla/widget/src/cocoa/nsToolkit.mm b/mozilla/widget/src/cocoa/nsToolkit.mm index 3c58df788d5..2a6081600c7 100644 --- a/mozilla/widget/src/cocoa/nsToolkit.mm +++ b/mozilla/widget/src/cocoa/nsToolkit.mm @@ -51,163 +51,11 @@ #undef DARWIN #import -// -// interface EventQueueHanlder -// -// An object that handles processing events for the PLEvent queue -// on each thread. -// -@interface EventQueueHandler : NSObject -{ - nsIEventQueue* mMainThreadEventQueue; // addreffed - NSTimer* mEventTimer; // our timer [STRONG] -} - -- (void)eventTimer:(NSTimer *)theTimer; - -@end - - -static EventQueueHandler* gEventQueueHandler = nsnull; - - -@implementation EventQueueHandler - -// -// -init -// -// Do init stuff. Cache the EventQueue Service and kick off our repeater -// to process PLEvents. The toolkit owns the timer so that neither Mozilla -// nor embedding apps need to worry about polling to process these events. -// -- (id)init -{ - if ( (self = [super init]) ) - { - nsCOMPtr service = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID); - if (!service) { - [self release]; - return nil; - } - - service->GetThreadEventQueue(NS_CURRENT_THREAD, &mMainThreadEventQueue); // addref - - mEventTimer = [NSTimer scheduledTimerWithTimeInterval:0.005 - target:self - selector:@selector(eventTimer:) - userInfo:nil - repeats:YES]; - if (!mMainThreadEventQueue || !mEventTimer) { - [self release]; - return nil; - } - } - - return self; -} - - -// -// -dealloc -// -// When we're finally ready to go away, kill our timer and get rid of the -// EventQueue Service. Also set the global var to null so in case we're called -// into action again we'll start over and not try to re-use the deleted object. -// -- (void) dealloc -{ - [mEventTimer release]; - NS_IF_RELEASE(mMainThreadEventQueue); - - gEventQueueHandler = nsnull; - - [super dealloc]; -} - - -// -// -eventTimer -// -// Called periodically to process PLEvents from the queue on the current thread -// - -#define MAX_PROCESS_EVENT_CALLS 20 - -//#define DEBUG_EVENT_TIMING - -//#define TIMED_EVENT_PROCESSING -#define MAX_PLEVENT_TIME_MILLISECONDS 500 - - -- (void)eventTimer:(NSTimer *)theTimer -{ -#ifdef DEBUG_EVENT_TIMING - AbsoluteTime startTime = ::UpTime(); -#endif - - if (mMainThreadEventQueue) - { -#ifdef TIMED_EVENT_PROCESSING - // the new way; process events until some time has elapsed, or there are - // no events left. UpTime() is a very low-overhead way to measure time. - AbsoluteTime bailTime = ::AddDurationToAbsolute(MAX_PLEVENT_TIME_MILLISECONDS * durationMillisecond, ::UpTime()); - while (1) - { - PRBool pendingEvents = PR_FALSE; - mMainThreadEventQueue->PendingEvents(&pendingEvents); - if (!pendingEvents) - break; - mMainThreadEventQueue->ProcessPendingEvents(); - - AbsoluteTime now = ::UpTime(); - if (UnsignedWideToUInt64(now) > UnsignedWideToUInt64(bailTime)) - break; - } -#else - // the old way; process events 20 times. Can suck CPU, and make the app - // unresponsive - for (PRInt32 i = 0; i < MAX_PROCESS_EVENT_CALLS; i ++) - { - PRBool pendingEvents = PR_FALSE; - mMainThreadEventQueue->PendingEvents(&pendingEvents); - if (!pendingEvents) - break; - mMainThreadEventQueue->ProcessPendingEvents(); - } -#endif - } - -#ifdef DEBUG_EVENT_TIMING - Nanoseconds duration = ::AbsoluteDeltaToNanoseconds(::UpTime(), startTime); - UInt32 milliseconds = UnsignedWideToUInt64(duration) / 1000000; - - static UInt32 sMaxDuration = 0; - - if (milliseconds > sMaxDuration) - sMaxDuration = milliseconds; - - printf("Event handling took %u ms (max %u)\n", milliseconds, sMaxDuration); -#endif - -} - - -@end - - -#pragma mark - - //------------------------------------------------------------------------- // //------------------------------------------------------------------------- nsToolkit::nsToolkit() { - if (!gEventQueueHandler) - { - // autorelease this so that if Init is never called, it is not - // leaked. Init retains it. - gEventQueueHandler = [[[EventQueueHandler alloc] init] autorelease]; - } } //------------------------------------------------------------------------- @@ -215,13 +63,6 @@ nsToolkit::nsToolkit() //------------------------------------------------------------------------- nsToolkit::~nsToolkit() { - /* Decrement our refcount on gEventQueueHandler; a prelude toward - stopping event handling. This is not something you want to do unless you've - bloody well started event handling and incremented the refcount. That's - done in the Init method, not the constructor, and that's what mInited is about. - */ - if (mInited && gEventQueueHandler) - [gEventQueueHandler release]; } @@ -231,11 +72,7 @@ nsToolkit::~nsToolkit() nsresult nsToolkit::InitEventQueue(PRThread * aThread) { - if (!gEventQueueHandler) - return NS_ERROR_FAILURE; - - [gEventQueueHandler retain]; - + // nothing to do return NS_OK; } diff --git a/mozilla/xpcom/threads/plevent.c b/mozilla/xpcom/threads/plevent.c index 7962879a977..a428af3d4ef 100644 --- a/mozilla/xpcom/threads/plevent.c +++ b/mozilla/xpcom/threads/plevent.c @@ -69,7 +69,10 @@ #endif #if defined(XP_MAC) || defined(XP_MACOSX) -#if !defined(MOZ_WIDGET_COCOA) && TARGET_CARBON +#if defined(MOZ_WIDGET_COCOA) +#include +#define MAC_USE_CFRUNLOOPSOURCE +#elif defined(TARGET_CARBON) #include #define MAC_USE_CARBON_EVENT #else @@ -169,7 +172,10 @@ struct PLEventQueue { #elif defined(XP_BEOS) port_id eventport; #elif defined(XP_MAC) || defined(XP_MACOSX) -#if defined(MAC_USE_CARBON_EVENT) +#if defined(MAC_USE_CFRUNLOOPSOURCE) + CFRunLoopSourceRef mRunLoopSource; + CFRunLoopRef mMainRunLoop; +#elif defined(MAC_USE_CARBON_EVENT) EventHandlerUPP eventHandlerUPP; EventHandlerRef eventHandlerRef; #elif defined(MAC_USE_WAKEUPPROCESS) @@ -984,6 +990,12 @@ _pl_CleanupNativeNotifier(PLEventQueue* self) #elif defined(XP_OS2) WinDestroyWindow(self->eventReceiverWindow); +#elif defined(MAC_USE_CFRUNLOOPSOURCE) + + CFRunLoopRemoveSource(self->mMainRunLoop, self->mRunLoopSource, kCFRunLoopCommonModes); + CFRelease(self->mRunLoopSource); + CFRelease(self->mMainRunLoop); + #elif defined(MAC_USE_CARBON_EVENT) EventComparatorUPP comparator = NewEventComparatorUPP(_md_CarbonEventComparator); PR_ASSERT(comparator != NULL); @@ -1286,7 +1298,10 @@ _pl_NativeNotify(PLEventQueue* self) static PRStatus _pl_NativeNotify(PLEventQueue* self) { -#if defined(MAC_USE_CARBON_EVENT) +#if defined(MAC_USE_CFRUNLOOPSOURCE) + CFRunLoopSourceSignal(self->mRunLoopSource); + CFRunLoopWakeUp(self->mMainRunLoop); +#elif defined(MAC_USE_CARBON_EVENT) OSErr err; EventRef newEvent; if (CreateEvent(NULL, kEventClassPL, kEventProcessPLEvents, @@ -1600,7 +1615,14 @@ static void _md_CreateEventQueue( PLEventQueue *eventQueue ) } /* end _md_CreateEventQueue() */ #endif /* (defined(XP_UNIX) && !defined(XP_MACOSX)) || defined(XP_BEOS) */ -#if defined(MAC_USE_CARBON_EVENT) +#if defined(MAC_USE_CFRUNLOOPSOURCE) +static void _md_EventReceiverProc(void *info) +{ + PLEventQueue *queue = (PLEventQueue*)info; + PL_ProcessPendingEvents(queue); +} + +#elif defined(MAC_USE_CARBON_EVENT) /* ** _md_CreateEventQueue() -- ModelDependent initializer */ @@ -1645,7 +1667,23 @@ static pascal Boolean _md_CarbonEventComparator(EventRef inEvent, #if defined(XP_MAC) || defined(XP_MACOSX) static void _md_CreateEventQueue( PLEventQueue *eventQueue ) { -#if defined(MAC_USE_CARBON_EVENT) +#if defined(MAC_USE_CFRUNLOOPSOURCE) + CFRunLoopSourceContext sourceContext = {0}; + sourceContext.version = 0; + sourceContext.info = (void*)eventQueue; + sourceContext.perform = _md_EventReceiverProc; + + // make a run loop source + eventQueue->mRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0 /* order */, &sourceContext); + PR_ASSERT(eventQueue->mRunLoopSource); + + eventQueue->mMainRunLoop = CFRunLoopGetCurrent(); + CFRetain(eventQueue->mMainRunLoop); + + // and add it to the run loop. + CFRunLoopAddSource(eventQueue->mMainRunLoop, eventQueue->mRunLoopSource, kCFRunLoopCommonModes); + +#elif defined(MAC_USE_CARBON_EVENT) eventQueue->eventHandlerUPP = NewEventHandlerUPP(_md_EventReceiverProc); PR_ASSERT(eventQueue->eventHandlerUPP); if (eventQueue->eventHandlerUPP)