diff options
Diffstat (limited to 'pr/src/misc/prinit.c')
-rw-r--r-- | pr/src/misc/prinit.c | 56 |
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) |