📄 prinit.c
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape Portable Runtime (NSPR). * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "primpl.h"#include <ctype.h>#include <string.h>PRLogModuleInfo *_pr_clock_lm;PRLogModuleInfo *_pr_cmon_lm;PRLogModuleInfo *_pr_io_lm;PRLogModuleInfo *_pr_cvar_lm;PRLogModuleInfo *_pr_mon_lm;PRLogModuleInfo *_pr_linker_lm;PRLogModuleInfo *_pr_sched_lm;PRLogModuleInfo *_pr_thread_lm;PRLogModuleInfo *_pr_gc_lm;PRLogModuleInfo *_pr_shm_lm;PRLogModuleInfo *_pr_shma_lm;PRFileDesc *_pr_stdin;PRFileDesc *_pr_stdout;PRFileDesc *_pr_stderr;#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)PRCList _pr_active_local_threadQ = PR_INIT_STATIC_CLIST(&_pr_active_local_threadQ);PRCList _pr_active_global_threadQ = PR_INIT_STATIC_CLIST(&_pr_active_global_threadQ);_MDLock _pr_cpuLock; /* lock for the CPU Q */PRCList _pr_cpuQ = PR_INIT_STATIC_CLIST(&_pr_cpuQ);PRUint32 _pr_utid;PRInt32 _pr_userActive;PRInt32 _pr_systemActive;PRUintn _pr_maxPTDs;#ifdef _PR_LOCAL_THREADS_ONLYstruct _PRCPU *_pr_currentCPU;PRThread *_pr_currentThread;PRThread *_pr_lastThread;PRInt32 _pr_intsOff;#endif /* _PR_LOCAL_THREADS_ONLY *//* Lock protecting all "termination" condition variables of all threads */PRLock *_pr_terminationCVLock;#endif /* !defined(_PR_PTHREADS) */PRLock *_pr_sleeplock; /* used in PR_Sleep(), classic and pthreads */static void _PR_InitCallOnce(void);PRBool _pr_initialized = PR_FALSE;PR_IMPLEMENT(PRBool) PR_VersionCheck(const char *importedVersion){ /* ** This is the secret handshake algorithm. ** ** This release has a simple version compatibility ** check algorithm. This release is not backward ** compatible with previous major releases. It is ** not compatible with future major, minor, or ** patch releases. */ int vmajor = 0, vminor = 0, vpatch = 0; const char *ptr = importedVersion; while (isdigit(*ptr)) { vmajor = 10 * vmajor + *ptr - '0'; ptr++; } if (*ptr == '.') { ptr++; while (isdigit(*ptr)) { vminor = 10 * vminor + *ptr - '0'; ptr++; } if (*ptr == '.') { ptr++; while (isdigit(*ptr)) { vpatch = 10 * vpatch + *ptr - '0'; ptr++; } } } if (vmajor != PR_VMAJOR) { return PR_FALSE; } if (vmajor == PR_VMAJOR && vminor > PR_VMINOR) { return PR_FALSE; } if (vmajor == PR_VMAJOR && vminor == PR_VMINOR && vpatch > PR_VPATCH) { return PR_FALSE; } return PR_TRUE;} /* PR_VersionCheck */PR_IMPLEMENT(PRBool) PR_Initialized(void){ return _pr_initialized;}PRInt32 _native_threads_only = 0;#ifdef WINNTstatic void _pr_SetNativeThreadsOnlyMode(void){ HMODULE mainExe; PRBool *globalp; char *envp; mainExe = GetModuleHandle(NULL); PR_ASSERT(NULL != mainExe); globalp = (PRBool *) GetProcAddress(mainExe, "nspr_native_threads_only"); if (globalp) { _native_threads_only = (*globalp != PR_FALSE); } else if (envp = getenv("NSPR_NATIVE_THREADS_ONLY")) { _native_threads_only = (atoi(envp) == 1); }}#endif#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)extern PRStatus _pr_init_ipv6(void);#endifstatic void _PR_InitStuff(void){ if (_pr_initialized) return; _pr_initialized = PR_TRUE;#ifdef _PR_ZONE_ALLOCATOR _PR_InitZones();#endif#ifdef WINNT _pr_SetNativeThreadsOnlyMode();#endif (void) PR_GetPageSize(); _pr_clock_lm = PR_NewLogModule("clock"); _pr_cmon_lm = PR_NewLogModule("cmon"); _pr_io_lm = PR_NewLogModule("io"); _pr_mon_lm = PR_NewLogModule("mon"); _pr_linker_lm = PR_NewLogModule("linker"); _pr_cvar_lm = PR_NewLogModule("cvar"); _pr_sched_lm = PR_NewLogModule("sched"); _pr_thread_lm = PR_NewLogModule("thread"); _pr_gc_lm = PR_NewLogModule("gc"); _pr_shm_lm = PR_NewLogModule("shm"); _pr_shma_lm = PR_NewLogModule("shma"); /* NOTE: These init's cannot depend on _PR_MD_CURRENT_THREAD() */ _PR_MD_EARLY_INIT(); _PR_InitLocks(); _PR_InitAtomic(); _PR_InitSegs(); _PR_InitStacks(); _PR_InitTPD(); _PR_InitEnv(); _PR_InitLayerCache(); _PR_InitClock(); _pr_sleeplock = PR_NewLock(); PR_ASSERT(NULL != _pr_sleeplock);#ifdef GC_LEAK_DETECTOR _PR_InitGarbageCollector();#endif _PR_InitThreads(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); #ifdef WIN16 { PRInt32 top; /* artificial top of stack, win16 */ _pr_top_of_task_stack = (char *) ⊤ }#endif #ifndef _PR_GLOBAL_THREADS_ONLY _PR_InitCPUs();#endif/* * XXX: call _PR_InitMem only on those platforms for which nspr implements * malloc, for now. */#ifdef _PR_OVERRIDE_MALLOC _PR_InitMem();#endif _PR_InitCMon(); _PR_InitIO(); _PR_InitNet(); _PR_InitLog(); _PR_InitLinker(); _PR_InitCallOnce(); _PR_InitDtoa(); _PR_InitMW(); _PR_InitRWLocks(); nspr_InitializePRErrorTable();#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE) _pr_init_ipv6();#endif _PR_MD_FINAL_INIT();}void _PR_ImplicitInitialization(void){ _PR_InitStuff(); /* Enable interrupts */#if !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) _PR_MD_START_INTERRUPTS();#endif}PR_IMPLEMENT(void) PR_DisableClockInterrupts(void){#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) if (!_pr_initialized) { _PR_InitStuff(); } else { _PR_MD_DISABLE_CLOCK_INTERRUPTS(); }#endif}PR_IMPLEMENT(void) PR_EnableClockInterrupts(void){#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) if (!_pr_initialized) { _PR_InitStuff(); } _PR_MD_ENABLE_CLOCK_INTERRUPTS();#endif}PR_IMPLEMENT(void) PR_BlockClockInterrupts(void){#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) _PR_MD_BLOCK_CLOCK_INTERRUPTS();#endif}PR_IMPLEMENT(void) PR_UnblockClockInterrupts(void){#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS();#endif}PR_IMPLEMENT(void) PR_Init( PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs){#if defined(XP_MAC)#pragma unused (type, priority, maxPTDs)#endif _PR_ImplicitInitialization();}PR_IMPLEMENT(PRIntn) PR_Initialize( PRPrimordialFn prmain, PRIntn argc, char **argv, PRUintn maxPTDs){#if defined(XP_MAC)#pragma unused (maxPTDs)#endif PRIntn rv; _PR_ImplicitInitialization(); rv = prmain(argc, argv); PR_Cleanup(); return rv;} /* PR_Initialize *//* *----------------------------------------------------------------------- * * _PR_CleanupBeforeExit -- * * Perform the cleanup work before exiting the process. * We first do the cleanup generic to all platforms. Then * we call _PR_MD_CLEANUP_BEFORE_EXIT(), where platform-dependent * cleanup is done. This function is used by PR_Cleanup(). * * See also: PR_Cleanup(). * *----------------------------------------------------------------------- */#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) /* see ptthread.c */#elsestatic void_PR_CleanupBeforeExit(void){/* Do not make any calls here other than to destroy resources. For example,do not make any calls that eventually may end up in PR_Lock. Because thethread is destroyed, can not access current thread any more.*/ _PR_CleanupTPD(); if (_pr_terminationCVLock) /* * In light of the comment above, this looks real suspicious. * I'd go so far as to say it's just a problem waiting to happen. */ PR_DestroyLock(_pr_terminationCVLock); _PR_MD_CLEANUP_BEFORE_EXIT();}#endif /* defined(_PR_PTHREADS) *//* *---------------------------------------------------------------------- * * PR_Cleanup -- * * Perform a graceful shutdown of the NSPR runtime. PR_Cleanup() may * only be called from the primordial thread, typically at the * end of the main() function. It returns when it has completed * its platform-dependent duty and the process must not make any other * NSPR library calls prior to exiting from main(). * * PR_Cleanup() first blocks the primordial thread until all the * other user (non-system) threads, if any, have terminated. * Then it performs cleanup in preparation for exiting the process. * PR_Cleanup() does not exit the primordial thread (which would * in turn exit the process). * * PR_Cleanup() only responds when it is called by the primordial * thread. Calls by any other thread are silently ignored. * * See also: PR_ExitProcess() * *---------------------------------------------------------------------- */#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) /* see ptthread.c */#elsePR_IMPLEMENT(PRStatus) PR_Cleanup(){ PRThread *me = PR_GetCurrentThread(); PR_ASSERT((NULL != me) && (me->flags & _PR_PRIMORDIAL)); if ((NULL != me) && (me->flags & _PR_PRIMORDIAL)) { PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR")); /* * No more recycling of threads */ _pr_recycleThreads = 0; /* * Wait for all other user (non-system/daemon) threads * to terminate. */ PR_Lock(_pr_activeLock); while (_pr_userActive > _pr_primordialExitCount) { PR_WaitCondVar(_pr_primordialExitCVar, PR_INTERVAL_NO_TIMEOUT); } PR_Unlock(_pr_activeLock);#ifdef IRIX _PR_MD_PRE_CLEANUP(me); /* * The primordial thread must now be running on the primordial cpu */ PR_ASSERT((_PR_IS_NATIVE_THREAD(me)) || (me->cpu->id == 0));#endif _PR_CleanupMW(); _PR_CleanupDtoa();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -