summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/wtf/MainThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/wtf/MainThread.cpp')
-rw-r--r--JavaScriptCore/wtf/MainThread.cpp92
1 files changed, 88 insertions, 4 deletions
diff --git a/JavaScriptCore/wtf/MainThread.cpp b/JavaScriptCore/wtf/MainThread.cpp
index 40a4ae5..a5f2346 100644
--- a/JavaScriptCore/wtf/MainThread.cpp
+++ b/JavaScriptCore/wtf/MainThread.cpp
@@ -29,11 +29,15 @@
#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;
@@ -89,8 +149,7 @@ void dispatchFunctionsFromMainThread()
MutexLocker locker(mainThreadFunctionQueueMutex());
if (!functionQueue().size())
break;
- invocation = functionQueue().first();
- functionQueue().removeFirst();
+ invocation = functionQueue().takeFirst();
}
invocation.function(invocation.context);
@@ -139,6 +198,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 +229,11 @@ void setMainThreadCallbacksPaused(bool paused)
scheduleDispatchFunctionsOnMainThread();
}
+#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(BREWMP)
+bool isMainThread()
+{
+ return currentThread() == mainThreadIdentifier;
+}
+#endif
+
} // namespace WTF