Changeset 40888 in webkit for trunk/JavaScriptCore/wtf


Ignore:
Timestamp:
Feb 11, 2009, 11:58:36 PM (16 years ago)
Author:
[email protected]
Message:

2009-02-11 Dmitry Titov <[email protected]>

Reviewed by Alexey Proskuryakov.

https://bugs.webkit.org/show_bug.cgi?id=23705
Fix the UI freeze caused by Worker generating a flood of messages.
Measure time we spend in executing posted work items. If too much time is spent
without returning to the run loop, exit and reschedule.

  • wtf/MainThread.h: Added initializeMainThreadPlatform() to initialize low-level mechanism for posting work items from thread to thread. This removes #ifdefs for WIN and CHROMIUM from platform-independent code.
  • wtf/MainThread.cpp: (WTF::initializeMainThread): (WTF::dispatchFunctionsFromMainThread): Instead of dispatching all work items in the queue, dispatch them one by one and measure elapsed time. After a threshold, reschedule and quit.

(WTF::callOnMainThread):
(WTF::callOnMainThreadAndWait):
Only schedule dispatch if the queue was empty - to avoid many posted messages in the run loop queue.

  • wtf/mac/MainThreadMac.mm: (WTF::scheduleDispatchFunctionsOnMainThread): Use static instance of the mainThreadCaller instead of allocating and releasing it each time. (WTF::initializeMainThreadPlatform):
  • wtf/gtk/MainThreadChromium.cpp: (WTF::initializeMainThreadPlatform):
  • wtf/gtk/MainThreadGtk.cpp: (WTF::initializeMainThreadPlatform):
  • wtf/qt/MainThreadQt.cpp: (WTF::initializeMainThreadPlatform):
  • wtf/win/MainThreadWin.cpp: (WTF::initializeMainThreadPlatform):
  • wtf/wx/MainThreadWx.cpp: (WTF::initializeMainThreadPlatform):
Location:
trunk/JavaScriptCore/wtf
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/wtf/MainThread.cpp

    r40684 r40888  
    3030#include "MainThread.h"
    3131
     32#include "CurrentTime.h"
     33#include "Deque.h"
    3234#include "StdLibExtras.h"
    3335#include "Threading.h"
    34 #include "Vector.h"
    3536
    3637namespace WTF {
     
    4950};
    5051
    51 typedef Vector<FunctionWithContext> FunctionQueue;
     52typedef Deque<FunctionWithContext> FunctionQueue;
    5253
    5354static bool callbacksPaused; // This global variable is only accessed from main thread.
     
    6566}
    6667
    67 #if !PLATFORM(WIN) && !PLATFORM(CHROMIUM)
    6868void initializeMainThread()
    6969{
    7070    mainThreadFunctionQueueMutex();
     71    initializeMainThreadPlatform();
    7172}
    72 #endif
     73
     74// 0.1 sec delays in UI is approximate threshold when they become noticeable. Have a limit that's half of that.
     75static const double maxRunLoopSuspensionTime = 0.05;
    7376
    7477void dispatchFunctionsFromMainThread()
     
    7982        return;
    8083
    81     FunctionQueue queueCopy;
    82     {
    83         MutexLocker locker(mainThreadFunctionQueueMutex());
    84         queueCopy.swap(functionQueue());
    85     }
     84    double startTime = currentTime();
    8685
    87     for (unsigned i = 0; i < queueCopy.size(); ++i) {
    88         FunctionWithContext& invocation = queueCopy[i];
     86    FunctionWithContext invocation;
     87    while (true) {
     88        {
     89            MutexLocker locker(mainThreadFunctionQueueMutex());
     90            if (!functionQueue().size())
     91                break;
     92            invocation = functionQueue().first();
     93            functionQueue().removeFirst();
     94        }
     95
    8996        invocation.function(invocation.context);
    9097        if (invocation.syncFlag)
    9198            invocation.syncFlag->signal();
     99       
     100        // If we are running accumulated functions for too long so UI may become unresponsive, we need to
     101        // yield so the user input can be processed. Otherwise user may not be able to even close the window.
     102        // This code has effect only in case the scheduleDispatchFunctionsOnMainThread() is implemented in a way that
     103        // allows input events to be processed before we are back here.
     104        if (currentTime() - startTime > maxRunLoopSuspensionTime) {
     105            scheduleDispatchFunctionsOnMainThread();
     106            break;
     107        }
    92108    }
    93109}
     
    96112{
    97113    ASSERT(function);
    98 
     114    bool needToSchedule = false;
    99115    {
    100116        MutexLocker locker(mainThreadFunctionQueueMutex());
     117        needToSchedule = functionQueue().size() == 0;
    101118        functionQueue().append(FunctionWithContext(function, context));
    102119    }
    103 
    104     scheduleDispatchFunctionsOnMainThread();
     120    if (needToSchedule)
     121        scheduleDispatchFunctionsOnMainThread();
    105122}
    106123
     
    116133    ThreadCondition syncFlag;
    117134    Mutex conditionMutex;
    118 
     135    bool needToSchedule = false;
    119136    {
    120137        MutexLocker locker(mainThreadFunctionQueueMutex());
     138        needToSchedule = functionQueue().size() == 0;
    121139        functionQueue().append(FunctionWithContext(function, context, &syncFlag));
    122140        conditionMutex.lock();
    123141    }
    124142
    125     scheduleDispatchFunctionsOnMainThread();
     143    if (needToSchedule)
     144        scheduleDispatchFunctionsOnMainThread();
    126145    syncFlag.wait(conditionMutex);
    127146}
  • trunk/JavaScriptCore/wtf/MainThread.h

    r36056 r40888  
    4646
    4747// These functions are internal to the callOnMainThread implementation.
    48 void dispatchFunctionsFromMainThread();
     48void initializeMainThreadPlatform();
    4949void scheduleDispatchFunctionsOnMainThread();
    5050Mutex& mainThreadFunctionQueueMutex();
     51void dispatchFunctionsFromMainThread();
    5152
    5253} // namespace WTF
  • trunk/JavaScriptCore/wtf/chromium/MainThreadChromium.cpp

    r40684 r40888  
    3636namespace WTF {
    3737
    38 void initializeMainThread()
     38void initializeMainThreadPlatform()
    3939{
    4040    ChromiumThreading::initializeMainThread();
  • trunk/JavaScriptCore/wtf/gtk/MainThreadGtk.cpp

    r31730 r40888  
    3535namespace WTF {
    3636
     37void initializeMainThreadPlatform()
     38{
     39}
     40
    3741static gboolean timeoutFired(gpointer)
    3842{
     
    4650}
    4751
    48 
    49 }
     52} // namespace WTF
  • trunk/JavaScriptCore/wtf/mac/MainThreadMac.mm

    r31730 r40888  
    3131
    3232#import <Foundation/NSThread.h>
     33#import <wtf/Assertions.h>
    3334
    3435@interface WTFMainThreadCaller : NSObject {
     
    4849namespace WTF {
    4950
     51static WTFMainThreadCaller* staticMainThreadCaller = nil;
     52
     53void initializeMainThreadPlatform()
     54{
     55    ASSERT(!staticMainThreadCaller);
     56    staticMainThreadCaller = [[WTFMainThreadCaller alloc] init];
     57}
     58
    5059void scheduleDispatchFunctionsOnMainThread()
    5160{
    52     WTFMainThreadCaller *caller = [[WTFMainThreadCaller alloc] init];
    53     [caller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO];
    54     [caller release];
     61    ASSERT(staticMainThreadCaller);
     62    [staticMainThreadCaller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO];
    5563}
    5664
  • trunk/JavaScriptCore/wtf/qt/MainThreadQt.cpp

    r37061 r40888  
    5959Q_GLOBAL_STATIC(MainThreadInvoker, webkit_main_thread_invoker)
    6060
     61void initializeMainThreadPlatform()
     62{
     63}
    6164
    6265void scheduleDispatchFunctionsOnMainThread()
     
    6568}
    6669
    67 }
     70} // namespace WTF
    6871
    6972#include "MainThreadQt.moc"
  • trunk/JavaScriptCore/wtf/win/MainThreadWin.cpp

    r38699 r40888  
    5151}
    5252
    53 void initializeMainThread()
     53void initializeMainThreadPlatform()
    5454{
    5555    if (threadingWindowHandle)
    5656        return;
    57 
    58     mainThreadFunctionQueueMutex();
    5957
    6058    WNDCLASSEX wcex;
     
    7674}
    7775
    78 } // namespace WebCore
     76} // namespace WTF
  • trunk/JavaScriptCore/wtf/wx/MainThreadWx.cpp

    r31730 r40888  
    3232namespace WTF {
    3333
     34void initializeMainThreadPlatform()
     35{
     36}
     37
    3438void scheduleDispatchFunctionsOnMainThread()
    3539{
    3640}
    3741
    38 }
     42} // namespace WTF
Note: See TracChangeset for help on using the changeset viewer.