mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Checking in CFRunLoop patch in bug 271050 to test pageload performance in Camino. r=pinkerton
This commit is contained in:
parent
d0064a3136
commit
726a1a4b01
@ -51,163 +51,11 @@
|
||||
#undef DARWIN
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
//
|
||||
// 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<nsIEventQueueService> 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;
|
||||
}
|
||||
|
||||
|
@ -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 <CoreFoundation/CoreFoundation.h>
|
||||
#define MAC_USE_CFRUNLOOPSOURCE
|
||||
#elif defined(TARGET_CARBON)
|
||||
#include <CarbonEvents.h>
|
||||
#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)
|
||||
|
Loading…
Reference in New Issue
Block a user