Bug 686230 - Add JS_CallOnce to the JSAPI for module initialization (r=luke)
☠☠ backed out by 33876ffaad6a ☠ ☠
authorSteve Fink <sfink@mozilla.com>
Sun, 11 Sep 2011 11:37:43 -0700
changeset 78941 7b4c9429370708d2a69204f2582028d068e1eb1b
parent 78940 a21f23d350d819d20a42e73a247545dce83d4f7b
child 78942 e84d5957f3ae78d6f89b0aa75470e90160aa782c
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs686230
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 686230 - Add JS_CallOnce to the JSAPI for module initialization (r=luke)
js/src/jsapi.h
js/src/jslock.cpp
js/src/jslock.h
js/src/jspubtd.h
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1692,16 +1692,27 @@ extern JS_PUBLIC_DATA(jsid) JSID_EMPTY;
  * If you set this flag in a JSFunctionSpec struct's flags initializer, then
  * that struct must live at least as long as the native static method object
  * created due to this flag by JS_DefineFunctions or JS_InitClass.  Typically
  * JSFunctionSpec structs are allocated in static arrays.
  */
 #define JSFUN_GENERIC_NATIVE    JSFUN_LAMBDA
 
 /*
+ * The first call to JS_CallOnce by any thread in a process will call 'func'.
+ * Later calls to JS_CallOnce with the same JSCallOnceType object will be
+ * suppressed.
+ *
+ * Equivalently: each distinct JSCallOnceType object will allow one JS_CallOnce
+ * to invoke its JSInitCallback.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_CallOnce(JSCallOnceType *once, JSInitCallback func);
+
+/*
  * Microseconds since the epoch, midnight, January 1, 1970 UTC.  See the
  * comment in jstypes.h regarding safe int64 usage.
  */
 extern JS_PUBLIC_API(int64)
 JS_Now(void);
 
 /* Don't want to export data, so provide accessors for non-inline jsvals. */
 extern JS_PUBLIC_API(jsval)
--- a/js/src/jslock.cpp
+++ b/js/src/jslock.cpp
@@ -734,9 +734,33 @@ js_UnlockRuntime(JSRuntime *rt)
 
 #ifdef DEBUG
 JSBool
 js_IsRuntimeLocked(JSRuntime *rt)
 {
     return js_CurrentThreadId() == rt->rtLockOwner;
 }
 #endif /* DEBUG */
+
+static PRStatus
+CallOnce(void *func)
+{
+    JSInitCallback init = JS_DATA_TO_FUNC_PTR(JSInitCallback, func);
+    return init() ? PR_FAILURE : PR_SUCCESS;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_CallOnce(JSCallOnceType *once, JSInitCallback func)
+{
+    return PR_CallOnceWithArg(once, CallOnce, JS_FUNC_TO_DATA_PTR(void *, func)) == PR_SUCCESS;
+}
+#else /* JS_THREADSAFE */
+JS_PUBLIC_API(JSBool)
+JS_CallOnce(JSCallOnceType *once, JSInitCallback func)
+{
+    if (!*once) {
+        *once = true;
+        return func();
+    } else {
+        return JS_TRUE;
+    }
+}
 #endif /* JS_THREADSAFE */
--- a/js/src/jslock.h
+++ b/js/src/jslock.h
@@ -43,16 +43,17 @@
 #include "jsapi.h"
 #include "jsprvtd.h"
 
 #ifdef JS_THREADSAFE
 # include "pratom.h"
 # include "prlock.h"
 # include "prcvar.h"
 # include "prthread.h"
+# include "prinit.h"
 #endif
 
 #ifdef JS_THREADSAFE
 
 #if (defined(_WIN32) && defined(_M_IX86)) ||                                  \
     (defined(_WIN64) && (defined(_M_AMD64) || defined(_M_X64))) ||            \
     (defined(__i386) && (defined(__GNUC__) || defined(__SUNPRO_CC))) ||       \
     (defined(__x86_64) && (defined(__GNUC__) || defined(__SUNPRO_CC))) ||     \
--- a/js/src/jspubtd.h
+++ b/js/src/jspubtd.h
@@ -236,11 +236,18 @@ typedef struct JSXDRState               
 #ifdef __cplusplus
 class                                       JSFlatString;
 class                                       JSString;
 #else
 typedef struct JSFlatString                 JSFlatString;
 typedef struct JSString                     JSString;
 #endif
 
+#ifdef JS_THREADSAFE
+typedef struct PRCallOnceType    JSCallOnceType;
+#else
+typedef JSBool                   JSCallOnceType;
+#endif
+typedef JSBool                 (*JSInitCallback)(void);
+
 JS_END_EXTERN_C
 
 #endif /* jspubtd_h___ */