Reviewed by Darin.
authorap@webkit.org <ap@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 May 2008 10:29:47 +0000 (10:29 +0000)
committerap@webkit.org <ap@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 May 2008 10:29:47 +0000 (10:29 +0000)
        Make JavaScriptGlue and JavaScriptCore API functions implicitly call initializeThreading
        for the sake of non-WebKit clients.

JavaScriptCore:
        * API/JSBase.cpp:
        (JSGarbageCollect):
        * API/JSContextRef.cpp:
        (JSGlobalContextCreate):
        These are the JavaScriptCore API bottlenecks. There are a few other JSStringRef
        and JSClassRef functions that can be called earlier, but they do not do anything that
        requires initializeThreading.

        * kjs/InitializeThreading.cpp:
        (KJS::doInitializeThreading):
        (KJS::initializeThreading):
        On Darwin, make the initialization happen under pthread_once, since there is no guarantee
        that non-WebKit clients won't try to call this function re-entrantly.

        * kjs/InitializeThreading.h:
        * wtf/Threading.h:
        Spell out initializeThreading contract.

        * wtf/ThreadingPthreads.cpp: (WTF::isMainThread): Make sure that results are correct on
        Darwin, even if threading was initialized from a secondary thread.

JavaScriptGlue:
        * JavaScriptGlue.cpp:
        (JSRunCreate):
        (JSCollect):
        (JSCreateJSArrayFromCFArray):
        (JSLockInterpreter):
        These are all possible JavaScriptGlue entry points.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@32808 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/API/JSBase.cpp
JavaScriptCore/API/JSContextRef.cpp
JavaScriptCore/ChangeLog
JavaScriptCore/kjs/InitializeThreading.cpp
JavaScriptCore/kjs/InitializeThreading.h
JavaScriptCore/wtf/Threading.h
JavaScriptCore/wtf/ThreadingPthreads.cpp
JavaScriptGlue/ChangeLog
JavaScriptGlue/JavaScriptGlue.cpp

index ed36a58..143b8d1 100644 (file)
 
 #include "APICast.h"
 #include <kjs/ExecState.h>
+#include <kjs/InitializeThreading.h>
+#include <kjs/interpreter.h>
 #include <kjs/JSGlobalObject.h>
 #include <kjs/JSLock.h>
-#include <kjs/interpreter.h>
 #include <kjs/object.h>
 
 using namespace KJS;
@@ -76,8 +77,12 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc
     return true;
 }
 
-void JSGarbageCollect(JSContextRef)
+void JSGarbageCollect(JSContextRef ctx)
 {
+    // Unlikely, but it is legal to call JSGarbageCollect(0) before actually doing anything that would implicitly call initializeThreading().
+    if (!ctx)
+        initializeThreading();
+
     JSLock lock;
 
     // It might seem that we have a context passed to this function, and can use toJS(ctx)->heap(), but the parameter is likely to be NULL.
index c0c6d1a..c651b59 100644 (file)
@@ -28,6 +28,7 @@
 #include "JSContextRef.h"
 
 #include "APICast.h"
+#include "InitializeThreading.h"
 #include "JSCallbackObject.h"
 #include "JSClassRef.h"
 #include "JSGlobalObject.h"
@@ -38,6 +39,8 @@ using namespace KJS;
 
 JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
 {
+    initializeThreading();
+
     JSLock lock;
 
     if (!globalObjectClass) {
index 83f4ddc..0c50a26 100644 (file)
@@ -1,5 +1,33 @@
 2008-05-02  Alexey Proskuryakov  <ap@webkit.org>
 
+        Reviewed by Darin.
+
+        Make JavaScriptGlue and JavaScriptCore API functions implicitly call initializeThreading
+        for the sake of non-WebKit clients.
+
+        * API/JSBase.cpp:
+        (JSGarbageCollect):
+        * API/JSContextRef.cpp:
+        (JSGlobalContextCreate):
+        These are the JavaScriptCore API bottlenecks. There are a few other JSStringRef
+        and JSClassRef functions that can be called earlier, but they do not do anything that
+        requires initializeThreading.
+
+        * kjs/InitializeThreading.cpp:
+        (KJS::doInitializeThreading):
+        (KJS::initializeThreading):
+        On Darwin, make the initialization happen under pthread_once, since there is no guarantee
+        that non-WebKit clients won't try to call this function re-entrantly.
+
+        * kjs/InitializeThreading.h:
+        * wtf/Threading.h:
+        Spell out initializeThreading contract.
+
+        * wtf/ThreadingPthreads.cpp: (WTF::isMainThread): Make sure that results are correct on
+        Darwin, even if threading was initialized from a secondary thread.
+
+2008-05-02  Alexey Proskuryakov  <ap@webkit.org>
+
         Reviewed by Geoffrey Garen.
 
         https://bugs.webkit.org/show_bug.cgi?id=18826
index 158eddb..ec535da 100644 (file)
 
 namespace KJS {
 
-void initializeThreading()
+#if PLATFORM(DARWIN)
+static pthread_once_t initializeThreadingKeyOnce = PTHREAD_ONCE_INIT;
+#endif
+
+static void initializeThreadingOnce()
 {
     WTF::initializeThreading();
 #if USE(MULTIPLE_THREADS)
-    if (!s_dtoaP5Mutex) {
-        s_dtoaP5Mutex = new Mutex;
-        Heap::threadHeap();
-        UString::null();
-        Identifier::initializeIdentifierThreading();
-        CommonIdentifiers::shared();
-        lexer();
-        initDateMath();
-        JSGlobalObject::threadClassInfoHashTables();
-        JSGlobalObject::head();
+    s_dtoaP5Mutex = new Mutex;
+    Heap::threadHeap();
+    UString::null();
+    Identifier::initializeIdentifierThreading();
+    CommonIdentifiers::shared();
+    lexer();
+    initDateMath();
+    JSGlobalObject::threadClassInfoHashTables();
+    JSGlobalObject::head();
+#endif
+}
+
+void initializeThreading()
+{
+#if PLATFORM(DARWIN)
+    pthread_once(&initializeThreadingKeyOnce, initializeThreadingOnce);
+#else
+    static bool initializedThreading = false;
+    if (!initializedThreading) {
+        initializeThreadingOnce();
+        initializedThreading = true;
     }
 #endif
 }
index 9250f96..35c7f70 100644 (file)
@@ -31,6 +31,8 @@
 
 namespace KJS {
 
+    // This function must be called from the main thread. It is safe to call it repeatedly.
+    // Darwin is an exception to this rule: it is OK to call this function from any thread, even reentrantly.
     void initializeThreading();
 
 }
index 6463acf..964b5cc 100644 (file)
@@ -239,6 +239,8 @@ private:
 #endif
 };
 
+// This function must be called from the main thread. It is safe to call it repeatedly.
+// Darwin is an exception to this rule: it is OK to call it from any thread, the only requirement is that the calls are not reentrant.
 void initializeThreading();
 
 extern Mutex* atomicallyInitializedStaticMutex;
index 28cc867..8ead1f5 100644 (file)
@@ -39,7 +39,7 @@ namespace WTF {
 
 Mutex* atomicallyInitializedStaticMutex;
 
-static ThreadIdentifier mainThreadIdentifier;
+static ThreadIdentifier mainThreadIdentifier; // More precisely, the thread that was the first to call initializeThreading().
 
 static Mutex& threadMapMutex()
 {
@@ -150,7 +150,11 @@ ThreadIdentifier currentThread()
 
 bool isMainThread()
 {
+#if PLATFORM(DARWIN)
+    return pthread_main_np();
+#else
     return currentThread() == mainThreadIdentifier;
+#endif
 }
 
 Mutex::Mutex()
index 099e625..496cdea 100644 (file)
@@ -1,5 +1,19 @@
 2008-05-02  Alexey Proskuryakov  <ap@webkit.org>
 
+        Reviewed by Darin.
+
+        Make JavaScriptGlue and JavaScriptCore API functions implicitly call initializeThreading
+        for the sake of non-WebKit clients.
+
+        * JavaScriptGlue.cpp:
+        (JSRunCreate):
+        (JSCollect):
+        (JSCreateJSArrayFromCFArray):
+        (JSLockInterpreter):
+        These are all possible JavaScriptGlue entry points.
+
+2008-05-02  Alexey Proskuryakov  <ap@webkit.org>
+
         Reviewed by Geoffrey Garen.
 
         https://bugs.webkit.org/show_bug.cgi?id=18826
index c8f2c8e..87c0ca2 100644 (file)
@@ -32,6 +32,7 @@
 #include "JSBase.h"
 #include "JSObject.h"
 #include "JSRun.h"
+#include <JavaScriptCore/InitializeThreading.h>
 
 static CFTypeRef sJSCFNullRef = 0;
 
@@ -239,6 +240,8 @@ JSObjectRef JSObjectCallFunction(JSObjectRef ref, JSObjectRef thisObj, CFArrayRe
 */
 JSRunRef JSRunCreate(CFStringRef jsSource, JSFlags inFlags)
 {
+    initializeThreading();
+
     JSRunRef result = 0;
     if (jsSource)
     {
@@ -330,8 +333,10 @@ bool JSRunCheckSyntax(JSRunRef ref)
 /*
     JSCollect - trigger garbage collection
 */
-void JSCollect(void)
+void JSCollect()
 {
+    initializeThreading();
+
     JSLock lock;
     getThreadGlobalExecState()->heap()->collect();
 }
@@ -614,6 +619,8 @@ CFMutableArrayRef JSCreateCFArrayFromJSArray(CFArrayRef array)
 
 CFMutableArrayRef JSCreateJSArrayFromCFArray(CFArrayRef array)
 {
+    initializeThreading();
+
     CFIndex count = array ? CFArrayGetCount(array) : 0;
     CFArrayCallBacks arrayCallbacks;
     CFMutableArrayRef jsArray;
@@ -640,6 +647,7 @@ CFMutableArrayRef JSCreateJSArrayFromCFArray(CFArrayRef array)
 
 void JSLockInterpreter()
 {
+    initializeThreading();
     JSLock::lock();
 }