Bug 686230 - Add JS_CallOnce to the JSAPI for module initialization (r=luke)
authorSteve Fink <sfink@mozilla.com>
Sun, 11 Sep 2011 11:37:43 -0700
changeset 78554 74c8bc479d72f4b74248926fbabe87a585021297
parent 78553 6d2816c9cd412074f909193fba9b39fc78b0b6a7
child 78555 8fae5a109fe23c94621dca623741aa94525f711c
push id2580
push usersfink@mozilla.com
push dateTue, 11 Oct 2011 19:01:55 +0000
treeherdermozilla-inbound@c515dbded0c2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs686230
milestone10.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
@@ -1693,16 +1693,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
@@ -32,33 +32,34 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "jstypes.h"
+#include "jspubtd.h"
+
 #ifdef JS_THREADSAFE
 
 /*
  * JS locking stubs.
  */
 #include <stdlib.h>
 #include <string.h>
 
 #ifdef XP_WIN
 # include "jswin.h"
 #else
 # include <unistd.h>
 #endif
 
-#include "jspubtd.h"
 #include "jsutil.h"
-#include "jstypes.h"
 #include "jsstdint.h"
 #include "jscntxt.h"
 #include "jsgc.h"
 #include "jslock.h"
 #include "jsscope.h"
 #include "jsstr.h"
 
 using namespace js;
@@ -757,9 +758,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___ */