Reviewed by Darin.
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Mar 2008 02:08:48 +0000 (02:08 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Mar 2008 02:08:48 +0000 (02:08 +0000)
        Move JNI specific code from runtime_root over to jni_jsobject, where it is used.

        * bridge/jni/jni_jsobject.cpp:
        (completedJavaScriptAccess):
        (initializeJavaScriptAccessLock):
        (lockJavaScriptAccess):
        (unlockJavaScriptAccess):
        (dispatchToJavaScriptThread):
        (performJavaScriptAccess):
        (JavaJSObject::initializeJNIThreading):
        (isJavaScriptThread):
        (JavaJSObject::invoke):
        * bridge/jni/jni_jsobject.h:
        * bridge/runtime_root.cpp:
        * bridge/runtime_root.h:
        * page/mac/WebCoreFrameBridge.mm:
        (-[WebCoreFrameBridge init]):

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

WebCore/ChangeLog
WebCore/bridge/jni/jni_jsobject.cpp
WebCore/bridge/jni/jni_jsobject.h
WebCore/bridge/runtime_root.cpp
WebCore/bridge/runtime_root.h
WebCore/page/mac/WebCoreFrameBridge.mm

index 64beb3e..f5735e6 100644 (file)
@@ -1,3 +1,25 @@
+2008-03-05  Anders Carlsson  <andersca@apple.com>
+
+        Reviewed by Darin.
+
+        Move JNI specific code from runtime_root over to jni_jsobject, where it is used.
+
+        * bridge/jni/jni_jsobject.cpp:
+        (completedJavaScriptAccess):
+        (initializeJavaScriptAccessLock):
+        (lockJavaScriptAccess):
+        (unlockJavaScriptAccess):
+        (dispatchToJavaScriptThread):
+        (performJavaScriptAccess):
+        (JavaJSObject::initializeJNIThreading):
+        (isJavaScriptThread):
+        (JavaJSObject::invoke):
+        * bridge/jni/jni_jsobject.h:
+        * bridge/runtime_root.cpp:
+        * bridge/runtime_root.h:
+        * page/mac/WebCoreFrameBridge.mm:
+        (-[WebCoreFrameBridge init]):
+
 2008-03-05  Darin Adler  <darin@apple.com>
 
         Reviewed by Sam.
index 28d8948..3f19aad 100644 (file)
@@ -48,19 +48,135 @@ using namespace KJS;
 #define JS_LOG(formatAndArgs...) ((void)0)
 #else
 #define JS_LOG(formatAndArgs...) { \
-    fprintf (stderr, "%s(%p,%p):  ", __PRETTY_FUNCTION__, RootObject::runLoop(), CFRunLoopGetCurrent()); \
+    fprintf (stderr, "%s(%p,%p):  ", __PRETTY_FUNCTION__, _performJavaScriptRunLoop, CFRunLoopGetCurrent()); \
     fprintf(stderr, formatAndArgs); \
 }
 #endif
 
 #define UndefinedHandle 1
 
+static CFRunLoopSourceRef _performJavaScriptSource;
+static CFRunLoopRef _performJavaScriptRunLoop;
+
+// May only be set by dispatchToJavaScriptThread().
+static CFRunLoopSourceRef completionSource;
+
+static void completedJavaScriptAccess (void *i)
+{
+    assert (CFRunLoopGetCurrent() != _performJavaScriptRunLoop);
+    
+    JSObjectCallContext *callContext = (JSObjectCallContext *)i;
+    CFRunLoopRef runLoop = (CFRunLoopRef)callContext->originatingLoop;
+    
+    assert (CFRunLoopGetCurrent() == runLoop);
+    
+    CFRunLoopStop(runLoop);
+}
+
+static pthread_once_t javaScriptAccessLockOnce = PTHREAD_ONCE_INIT;
+static pthread_mutex_t javaScriptAccessLock;
+static int javaScriptAccessLockCount = 0;
+
+static void initializeJavaScriptAccessLock()
+{
+    pthread_mutexattr_t attr;
+    
+    pthread_mutexattr_init(&attr);
+    pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+    
+    pthread_mutex_init(&javaScriptAccessLock, &attr);
+}
+
+static inline void lockJavaScriptAccess()
+{
+    // Perhaps add deadlock detection?
+    pthread_once(&javaScriptAccessLockOnce, initializeJavaScriptAccessLock);
+    pthread_mutex_lock(&javaScriptAccessLock);
+    javaScriptAccessLockCount++;
+}
+
+static inline void unlockJavaScriptAccess()
+{
+    javaScriptAccessLockCount--;
+    pthread_mutex_unlock(&javaScriptAccessLock);
+}
+
+static void dispatchToJavaScriptThread(JSObjectCallContext *context)
+{
+    // This lock guarantees that only one thread can invoke
+    // at a time, and also guarantees that completionSource;
+    // won't get clobbered.
+    lockJavaScriptAccess();
+    
+    CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent();
+    
+    assert (currentRunLoop != _performJavaScriptRunLoop);
+    
+    // Setup a source to signal once the invocation of the JavaScript
+    // call completes.
+    //
+    // FIXME:  This could be a potential performance issue.  Creating and
+    // adding run loop sources is expensive.  We could create one source 
+    // per thread, as needed, instead.
+    context->originatingLoop = currentRunLoop;
+    CFRunLoopSourceContext sourceContext = {0, context, NULL, NULL, NULL, NULL, NULL, NULL, NULL, completedJavaScriptAccess};
+    completionSource = CFRunLoopSourceCreate(NULL, 0, &sourceContext);
+    CFRunLoopAddSource(currentRunLoop, completionSource, kCFRunLoopDefaultMode);
+    
+    // Wakeup JavaScript access thread and make it do it's work.
+    CFRunLoopSourceSignal(_performJavaScriptSource);
+    if (CFRunLoopIsWaiting(_performJavaScriptRunLoop))
+        CFRunLoopWakeUp(_performJavaScriptRunLoop);
+    
+    // Wait until the JavaScript access thread is done.
+    CFRunLoopRun ();
+    
+    CFRunLoopRemoveSource(currentRunLoop, completionSource, kCFRunLoopDefaultMode);
+    CFRelease (completionSource);
+    
+    unlockJavaScriptAccess();
+}
+
+static void performJavaScriptAccess(void*)
+{
+    assert (CFRunLoopGetCurrent() == _performJavaScriptRunLoop);
+    
+    // Dispatch JavaScript calls here.
+    CFRunLoopSourceContext sourceContext;
+    CFRunLoopSourceGetContext (completionSource, &sourceContext);
+    JSObjectCallContext *callContext = (JSObjectCallContext *)sourceContext.info;    
+    CFRunLoopRef originatingLoop = callContext->originatingLoop;
+    
+    JavaJSObject::invoke (callContext);
+    
+    // Signal the originating thread that we're done.
+    CFRunLoopSourceSignal (completionSource);
+    if (CFRunLoopIsWaiting(originatingLoop))
+        CFRunLoopWakeUp(originatingLoop);
+}
+
+// Must be called from the thread that will be used to access JavaScript.
+void JavaJSObject::initializeJNIThreading() {
+    // Should only be called once.
+    ASSERT(!_performJavaScriptRunLoop);
+    
+    // Assume that we can retain this run loop forever.  It'll most 
+    // likely (always?) be the main loop.
+    _performJavaScriptRunLoop = (CFRunLoopRef)CFRetain(CFRunLoopGetCurrent());
+    
+    // Setup a source the other threads can use to signal the _runLoop
+    // thread that a JavaScript call needs to be invoked.
+    CFRunLoopSourceContext sourceContext = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, performJavaScriptAccess};
+    _performJavaScriptSource = CFRunLoopSourceCreate(NULL, 0, &sourceContext);
+    CFRunLoopAddSource(_performJavaScriptRunLoop, _performJavaScriptSource, kCFRunLoopDefaultMode);
+}
+
 static bool isJavaScriptThread()
 {
-    return (RootObject::runLoop() == CFRunLoopGetCurrent());
+    return (_performJavaScriptRunLoop == CFRunLoopGetCurrent());
 }
 
-jvalue JavaJSObject::invoke (JSObjectCallContext *context)
+jvalue JavaJSObject::invoke(JSObjectCallContext *context)
 {
     jvalue result;
 
@@ -69,7 +185,7 @@ jvalue JavaJSObject::invoke (JSObjectCallContext *context)
     if (!isJavaScriptThread()) {        
         // Send the call context to the thread that is allowed to
         // call JavaScript.
-        RootObject::dispatchToJavaScriptThread(context);
+        dispatchToJavaScriptThread(context);
         result = context->result;
     }
     else {
index 75f37a2..3a0df07 100644 (file)
@@ -94,6 +94,8 @@ public:
     
     RootObject* rootObject() const;
     
+    // Must be called from the thread that will be used to access JavaScript.
+    static void initializeJNIThreading();
 private:
     RefPtr<RootObject> _rootObject;
     JSObject* _imp;
index 78b0242..c8ab7fd 100644 (file)
@@ -69,131 +69,6 @@ RootObject* findRootObject(JSGlobalObject* globalObject)
     return 0;
 }
 
-#if PLATFORM(MAC)
-    
-static CFRunLoopSourceRef _performJavaScriptSource;
-static CFRunLoopRef _runLoop;
-
-// May only be set by dispatchToJavaScriptThread().
-static CFRunLoopSourceRef completionSource;
-
-static void completedJavaScriptAccess (void *i)
-{
-    assert (CFRunLoopGetCurrent() != _runLoop);
-
-    JSObjectCallContext *callContext = (JSObjectCallContext *)i;
-    CFRunLoopRef runLoop = (CFRunLoopRef)callContext->originatingLoop;
-
-    assert (CFRunLoopGetCurrent() == runLoop);
-
-    CFRunLoopStop(runLoop);
-}
-
-static pthread_once_t javaScriptAccessLockOnce = PTHREAD_ONCE_INIT;
-static pthread_mutex_t javaScriptAccessLock;
-static int javaScriptAccessLockCount = 0;
-
-static void initializeJavaScriptAccessLock()
-{
-    pthread_mutexattr_t attr;
-    
-    pthread_mutexattr_init(&attr);
-    pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
-    
-    pthread_mutex_init(&javaScriptAccessLock, &attr);
-}
-
-static inline void lockJavaScriptAccess()
-{
-    // Perhaps add deadlock detection?
-    pthread_once(&javaScriptAccessLockOnce, initializeJavaScriptAccessLock);
-    pthread_mutex_lock(&javaScriptAccessLock);
-    javaScriptAccessLockCount++;
-}
-
-static inline void unlockJavaScriptAccess()
-{
-    javaScriptAccessLockCount--;
-    pthread_mutex_unlock(&javaScriptAccessLock);
-}
-
-void RootObject::dispatchToJavaScriptThread(JSObjectCallContext *context)
-{
-    // This lock guarantees that only one thread can invoke
-    // at a time, and also guarantees that completionSource;
-    // won't get clobbered.
-    lockJavaScriptAccess();
-
-    CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent();
-
-    assert (currentRunLoop != _runLoop);
-
-    // Setup a source to signal once the invocation of the JavaScript
-    // call completes.
-    //
-    // FIXME:  This could be a potential performance issue.  Creating and
-    // adding run loop sources is expensive.  We could create one source 
-    // per thread, as needed, instead.
-    context->originatingLoop = currentRunLoop;
-    CFRunLoopSourceContext sourceContext = {0, context, NULL, NULL, NULL, NULL, NULL, NULL, NULL, completedJavaScriptAccess};
-    completionSource = CFRunLoopSourceCreate(NULL, 0, &sourceContext);
-    CFRunLoopAddSource(currentRunLoop, completionSource, kCFRunLoopDefaultMode);
-
-    // Wakeup JavaScript access thread and make it do it's work.
-    CFRunLoopSourceSignal(_performJavaScriptSource);
-    if (CFRunLoopIsWaiting(_runLoop))
-        CFRunLoopWakeUp(_runLoop);
-    
-    // Wait until the JavaScript access thread is done.
-    CFRunLoopRun ();
-
-    CFRunLoopRemoveSource(currentRunLoop, completionSource, kCFRunLoopDefaultMode);
-    CFRelease (completionSource);
-
-    unlockJavaScriptAccess();
-}
-
-static void performJavaScriptAccess(void*)
-{
-    assert (CFRunLoopGetCurrent() == _runLoop);
-    
-    // Dispatch JavaScript calls here.
-    CFRunLoopSourceContext sourceContext;
-    CFRunLoopSourceGetContext (completionSource, &sourceContext);
-    JSObjectCallContext *callContext = (JSObjectCallContext *)sourceContext.info;    
-    CFRunLoopRef originatingLoop = callContext->originatingLoop;
-
-    JavaJSObject::invoke (callContext);
-    
-    // Signal the originating thread that we're done.
-    CFRunLoopSourceSignal (completionSource);
-    if (CFRunLoopIsWaiting(originatingLoop))
-        CFRunLoopWakeUp(originatingLoop);
-}
-
-CFRunLoopRef RootObject::runLoop()
-{
-    return _runLoop;
-}        
-
-// Must be called from the thread that will be used to access JavaScript.
-void RootObject::initializeJNIThreading() {
-    // Should only be called once.
-    ASSERT(!_runLoop);
-
-    // Assume that we can retain this run loop forever.  It'll most 
-    // likely (always?) be the main loop.
-    _runLoop = (CFRunLoopRef)CFRetain (CFRunLoopGetCurrent());
-
-    // Setup a source the other threads can use to signal the _runLoop
-    // thread that a JavaScript call needs to be invoked.
-    CFRunLoopSourceContext sourceContext = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, performJavaScriptAccess};
-    _performJavaScriptSource = CFRunLoopSourceCreate(NULL, 0, &sourceContext);
-    CFRunLoopAddSource(_runLoop, _performJavaScriptSource, kCFRunLoopDefaultMode);
-}
-
-#endif
-
 PassRefPtr<RootObject> RootObject::create(const void* nativeHandle, JSGlobalObject* globalObject)
 {
     return adoptRef(new RootObject(nativeHandle, globalObject));
index 57ab7c8..ad2e3a4 100644 (file)
@@ -68,14 +68,6 @@ public:
     const void* nativeHandle() const;
     JSGlobalObject* globalObject() const;
 
-#if PLATFORM(MAC)
-    // Must be called from the thread that will be used to access JavaScript.
-    static void initializeJNIThreading();
-    
-    static CFRunLoopRef runLoop();
-    static void dispatchToJavaScriptThread(JSObjectCallContext *context);
-#endif
-
     void addRuntimeObject(RuntimeObjectImp*);
     void removeRuntimeObject(RuntimeObjectImp*);
 private:
index bd793cd..453b2eb 100644 (file)
@@ -90,6 +90,7 @@
 #import "visible_units.h"
 #import <JavaScriptCore/array_instance.h>
 #import <JavaScriptCore/date_object.h>
+#import "jni_jsobject.h"
 #import "runtime_root.h"
 #import "runtime.h"
 #import <OpenScripting/ASRegistry.h>
@@ -119,7 +120,7 @@ using KJS::StringType;
 using KJS::UndefinedType;
 using KJS::UnspecifiedType;
 
-using KJS::Bindings::RootObject;
+using KJS::Bindings::JavaJSObject;
 
 static pthread_t mainThread = 0;
 
@@ -241,7 +242,7 @@ static inline WebCoreFrameBridge *bridge(Frame *frame)
         initializedKJS = true;
 
         mainThread = pthread_self();
-        RootObject::initializeJNIThreading();
+        JavaJSObject::initializeJNIThreading();
         KJS::Bindings::Instance::setDidExecuteFunction(updateRenderingForBindings);
     }