summaryrefslogtreecommitdiff
path: root/pr/src/misc/prinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'pr/src/misc/prinit.c')
-rw-r--r--pr/src/misc/prinit.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/pr/src/misc/prinit.c b/pr/src/misc/prinit.c
index 6da27fa0..04c92226 100644
--- a/pr/src/misc/prinit.c
+++ b/pr/src/misc/prinit.c
@@ -161,7 +161,7 @@ static void _pr_SetNativeThreadsOnlyMode(void)
#endif
#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
-extern PRStatus _pr_init_ipv6();
+extern PRStatus _pr_init_ipv6(void);
#endif
static void _PR_InitStuff(void)
@@ -169,6 +169,9 @@ static void _PR_InitStuff(void)
if (_pr_initialized) return;
_pr_initialized = PR_TRUE;
+#ifdef _PR_ZONE_ALLOCATOR
+ _PR_InitZones();
+#endif
#ifdef WINNT
_pr_SetNativeThreadsOnlyMode();
#endif
@@ -220,10 +223,6 @@ static void _PR_InitStuff(void)
_PR_InitCPUs();
#endif
-#ifdef _PR_ZONE_ALLOCATOR
- _PR_InitZones();
-#endif
-
/*
* XXX: call _PR_InitMem only on those platforms for which nspr implements
* malloc, for now.
@@ -251,7 +250,7 @@ static void _PR_InitStuff(void)
_PR_MD_FINAL_INIT();
}
-void _PR_ImplicitInitialization()
+void _PR_ImplicitInitialization(void)
{
_PR_InitStuff();
@@ -417,9 +416,10 @@ PR_IMPLEMENT(PRStatus) PR_Cleanup()
PR_ASSERT((_PR_IS_NATIVE_THREAD(me)) || (me->cpu->id == 0));
#endif
-#if defined(WIN16)
+ _PR_CleanupMW();
+ _PR_CleanupDtoa();
+ _PR_CleanupCallOnce();
_PR_ShutdownLinker();
-#endif
/* Release the primordial thread's private data, etc. */
_PR_CleanupThread(me);
@@ -449,7 +449,11 @@ PR_IMPLEMENT(PRStatus) PR_Cleanup()
* Ideally, for each _PR_InitXXX(), there should be a corresponding
* _PR_XXXCleanup() that we can call here.
*/
+ _PR_CleanupNet();
_PR_CleanupIO();
+#ifdef WINNT
+ _PR_CleanupCPUs();
+#endif
_PR_CleanupThreads();
PR_DestroyLock(_pr_sleeplock);
_pr_sleeplock = NULL;
@@ -561,7 +565,7 @@ PR_ProcessAttrSetCurrentDirectory(
const char *dir)
{
PR_FREEIF(attr->currentDirectory);
- attr->currentDirectory = PR_MALLOC(strlen(dir) + 1);
+ attr->currentDirectory = (char *) PR_MALLOC(strlen(dir) + 1);
if (!attr->currentDirectory) {
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
return PR_FAILURE;
@@ -776,13 +780,20 @@ static struct {
PRCondVar *cv;
} mod_init;
-static void _PR_InitCallOnce() {
+static void _PR_InitCallOnce(void) {
mod_init.ml = PR_NewLock();
PR_ASSERT(NULL != mod_init.ml);
mod_init.cv = PR_NewCondVar(mod_init.ml);
PR_ASSERT(NULL != mod_init.cv);
}
+void _PR_CleanupCallOnce()
+{
+ PR_DestroyLock(mod_init.ml);
+ mod_init.ml = NULL;
+ PR_DestroyCondVar(mod_init.cv);
+ mod_init.cv = NULL;
+}
PR_IMPLEMENT(PRStatus) PR_CallOnce(
PRCallOnceType *once,
@@ -808,6 +819,31 @@ PR_IMPLEMENT(PRStatus) PR_CallOnce(
return once->status;
}
+PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg(
+ PRCallOnceType *once,
+ PRCallOnceWithArgFN func,
+ void *arg)
+{
+ if (!_pr_initialized) _PR_ImplicitInitialization();
+
+ if (!once->initialized) {
+ if (PR_AtomicSet(&once->inProgress, 1) == 0) {
+ once->status = (*func)(arg);
+ PR_Lock(mod_init.ml);
+ once->initialized = 1;
+ PR_NotifyAllCondVar(mod_init.cv);
+ PR_Unlock(mod_init.ml);
+ } else {
+ PR_Lock(mod_init.ml);
+ while (!once->initialized) {
+ PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT);
+ }
+ PR_Unlock(mod_init.ml);
+ }
+ }
+ return once->status;
+}
+
PRBool _PR_Obsolete(const char *obsolete, const char *preferred)
{
#if defined(DEBUG)