]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - wtf/MainThread.cpp
JavaScriptCore-721.26.tar.gz
[apple/javascriptcore.git] / wtf / MainThread.cpp
index 40a4ae530818ea30d973afce7127f6e2000f7d91..1a0682bb6b60c267b40319c3aa6e40cbdb86579d 100644 (file)
 #include "config.h"
 #include "MainThread.h"
 
-#include "StdLibExtras.h"
 #include "CurrentTime.h"
 #include "Deque.h"
+#include "StdLibExtras.h"
 #include "Threading.h"
 
+#if PLATFORM(CHROMIUM)
+#error Chromium uses a different main thread implementation
+#endif
+
 namespace WTF {
 
 struct FunctionWithContext {
@@ -47,13 +51,30 @@ struct FunctionWithContext {
         , syncFlag(syncFlag)
     { 
     }
+    bool operator == (const FunctionWithContext& o)
+    {
+        return function == o.function
+            && context == o.context
+            && syncFlag == o.syncFlag;
+    }
 };
 
+class FunctionWithContextFinder {
+public:
+    FunctionWithContextFinder(const FunctionWithContext& m) : m(m) {}
+    bool operator() (FunctionWithContext& o) { return o == m; }
+    FunctionWithContext m;
+};
+
+
 typedef Deque<FunctionWithContext> FunctionQueue;
 
 static bool callbacksPaused; // This global variable is only accessed from main thread.
+#if !PLATFORM(MAC) && !PLATFORM(QT)
+static ThreadIdentifier mainThreadIdentifier;
+#endif
 
-Mutex& mainThreadFunctionQueueMutex()
+static Mutex& mainThreadFunctionQueueMutex()
 {
     DEFINE_STATIC_LOCAL(Mutex, staticMutex, ());
     return staticMutex;
@@ -65,12 +86,51 @@ static FunctionQueue& functionQueue()
     return staticFunctionQueue;
 }
 
+
+#if !PLATFORM(MAC)
+
 void initializeMainThread()
+{
+    static bool initializedMainThread;
+    if (initializedMainThread)
+        return;
+    initializedMainThread = true;
+
+#if !PLATFORM(QT)
+    mainThreadIdentifier = currentThread();
+#endif
+
+    mainThreadFunctionQueueMutex();
+    initializeMainThreadPlatform();
+}
+
+#else
+
+static pthread_once_t initializeMainThreadKeyOnce = PTHREAD_ONCE_INIT;
+
+static void initializeMainThreadOnce()
 {
     mainThreadFunctionQueueMutex();
     initializeMainThreadPlatform();
 }
 
+void initializeMainThread()
+{
+    pthread_once(&initializeMainThreadKeyOnce, initializeMainThreadOnce);
+}
+
+static void initializeMainThreadToProcessMainThreadOnce()
+{
+    mainThreadFunctionQueueMutex();
+    initializeMainThreadToProcessMainThreadPlatform();
+}
+
+void initializeMainThreadToProcessMainThread()
+{
+    pthread_once(&initializeMainThreadKeyOnce, initializeMainThreadToProcessMainThreadOnce);
+}
+#endif
+
 // 0.1 sec delays in UI is approximate threshold when they become noticeable. Have a limit that's half of that.
 static const double maxRunLoopSuspensionTime = 0.05;
 
@@ -139,6 +199,24 @@ void callOnMainThreadAndWait(MainThreadFunction* function, void* context)
     syncFlag.wait(functionQueueMutex);
 }
 
+void cancelCallOnMainThread(MainThreadFunction* function, void* context)
+{
+    ASSERT(function);
+
+    MutexLocker locker(mainThreadFunctionQueueMutex());
+
+    FunctionWithContextFinder pred(FunctionWithContext(function, context));
+
+    while (true) {
+        // We must redefine 'i' each pass, because the itererator's operator= 
+        // requires 'this' to be valid, and remove() invalidates all iterators
+        FunctionQueue::iterator i(functionQueue().findIf(pred));
+        if (i == functionQueue().end())
+            break;
+        functionQueue().remove(i);
+    }
+}
+
 void setMainThreadCallbacksPaused(bool paused)
 {
     ASSERT(isMainThread());
@@ -152,4 +230,11 @@ void setMainThreadCallbacksPaused(bool paused)
         scheduleDispatchFunctionsOnMainThread();
 }
 
+#if !PLATFORM(MAC) && !PLATFORM(QT)
+bool isMainThread()
+{
+    return currentThread() == mainThreadIdentifier;
+}
+#endif
+
 } // namespace WTF