Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(715)

Side by Side Diff: nspr/pr/src/misc/prinit.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nspr/pr/src/misc/prerrortable.c ('k') | nspr/pr/src/misc/prinrval.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "primpl.h"
7 #include <ctype.h>
8 #include <string.h>
9
10 PRLogModuleInfo *_pr_clock_lm;
11 PRLogModuleInfo *_pr_cmon_lm;
12 PRLogModuleInfo *_pr_io_lm;
13 PRLogModuleInfo *_pr_cvar_lm;
14 PRLogModuleInfo *_pr_mon_lm;
15 PRLogModuleInfo *_pr_linker_lm;
16 PRLogModuleInfo *_pr_sched_lm;
17 PRLogModuleInfo *_pr_thread_lm;
18 PRLogModuleInfo *_pr_gc_lm;
19 PRLogModuleInfo *_pr_shm_lm;
20 PRLogModuleInfo *_pr_shma_lm;
21
22 PRFileDesc *_pr_stdin;
23 PRFileDesc *_pr_stdout;
24 PRFileDesc *_pr_stderr;
25
26 #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
27
28 PRCList _pr_active_local_threadQ =
29 PR_INIT_STATIC_CLIST(&_pr_active_local_threadQ);
30 PRCList _pr_active_global_threadQ =
31 PR_INIT_STATIC_CLIST(&_pr_active_global_threadQ);
32
33 _MDLock _pr_cpuLock; /* lock for the CPU Q */
34 PRCList _pr_cpuQ = PR_INIT_STATIC_CLIST(&_pr_cpuQ);
35
36 PRUint32 _pr_utid;
37
38 PRInt32 _pr_userActive;
39 PRInt32 _pr_systemActive;
40 PRUintn _pr_maxPTDs;
41
42 #ifdef _PR_LOCAL_THREADS_ONLY
43
44 struct _PRCPU *_pr_currentCPU;
45 PRThread *_pr_currentThread;
46 PRThread *_pr_lastThread;
47 PRInt32 _pr_intsOff;
48
49 #endif /* _PR_LOCAL_THREADS_ONLY */
50
51 /* Lock protecting all "termination" condition variables of all threads */
52 PRLock *_pr_terminationCVLock;
53
54 #endif /* !defined(_PR_PTHREADS) */
55
56 PRLock *_pr_sleeplock; /* used in PR_Sleep(), classic and pthreads */
57
58 static void _PR_InitCallOnce(void);
59
60 PRBool _pr_initialized = PR_FALSE;
61
62
63 PR_IMPLEMENT(PRBool) PR_VersionCheck(const char *importedVersion)
64 {
65 /*
66 ** This is the secret handshake algorithm.
67 **
68 ** This release has a simple version compatibility
69 ** check algorithm. This release is not backward
70 ** compatible with previous major releases. It is
71 ** not compatible with future major, minor, or
72 ** patch releases.
73 */
74 int vmajor = 0, vminor = 0, vpatch = 0;
75 const char *ptr = importedVersion;
76
77 while (isdigit(*ptr)) {
78 vmajor = 10 * vmajor + *ptr - '0';
79 ptr++;
80 }
81 if (*ptr == '.') {
82 ptr++;
83 while (isdigit(*ptr)) {
84 vminor = 10 * vminor + *ptr - '0';
85 ptr++;
86 }
87 if (*ptr == '.') {
88 ptr++;
89 while (isdigit(*ptr)) {
90 vpatch = 10 * vpatch + *ptr - '0';
91 ptr++;
92 }
93 }
94 }
95
96 if (vmajor != PR_VMAJOR) {
97 return PR_FALSE;
98 }
99 if (vmajor == PR_VMAJOR && vminor > PR_VMINOR) {
100 return PR_FALSE;
101 }
102 if (vmajor == PR_VMAJOR && vminor == PR_VMINOR && vpatch > PR_VPATCH) {
103 return PR_FALSE;
104 }
105 return PR_TRUE;
106 } /* PR_VersionCheck */
107
108 PR_IMPLEMENT(const char*) PR_GetVersion(void)
109 {
110 return PR_VERSION;
111 }
112
113 PR_IMPLEMENT(PRBool) PR_Initialized(void)
114 {
115 return _pr_initialized;
116 }
117
118 PRInt32 _native_threads_only = 0;
119
120 #ifdef WINNT
121 static void _pr_SetNativeThreadsOnlyMode(void)
122 {
123 HMODULE mainExe;
124 PRBool *globalp;
125 char *envp;
126
127 mainExe = GetModuleHandle(NULL);
128 PR_ASSERT(NULL != mainExe);
129 globalp = (PRBool *) GetProcAddress(mainExe, "nspr_native_threads_only");
130 if (globalp) {
131 _native_threads_only = (*globalp != PR_FALSE);
132 } else if (envp = getenv("NSPR_NATIVE_THREADS_ONLY")) {
133 _native_threads_only = (atoi(envp) == 1);
134 }
135 }
136 #endif
137
138 static void _PR_InitStuff(void)
139 {
140
141 if (_pr_initialized) return;
142 _pr_initialized = PR_TRUE;
143 #ifdef _PR_ZONE_ALLOCATOR
144 _PR_InitZones();
145 #endif
146 #ifdef WINNT
147 _pr_SetNativeThreadsOnlyMode();
148 #endif
149
150
151 (void) PR_GetPageSize();
152
153 _pr_clock_lm = PR_NewLogModule("clock");
154 _pr_cmon_lm = PR_NewLogModule("cmon");
155 _pr_io_lm = PR_NewLogModule("io");
156 _pr_mon_lm = PR_NewLogModule("mon");
157 _pr_linker_lm = PR_NewLogModule("linker");
158 _pr_cvar_lm = PR_NewLogModule("cvar");
159 _pr_sched_lm = PR_NewLogModule("sched");
160 _pr_thread_lm = PR_NewLogModule("thread");
161 _pr_gc_lm = PR_NewLogModule("gc");
162 _pr_shm_lm = PR_NewLogModule("shm");
163 _pr_shma_lm = PR_NewLogModule("shma");
164
165 /* NOTE: These init's cannot depend on _PR_MD_CURRENT_THREAD() */
166 _PR_MD_EARLY_INIT();
167
168 _PR_InitLocks();
169 _PR_InitAtomic();
170 _PR_InitSegs();
171 _PR_InitStacks();
172 _PR_InitTPD();
173 _PR_InitEnv();
174 _PR_InitLayerCache();
175 _PR_InitClock();
176
177 _pr_sleeplock = PR_NewLock();
178 PR_ASSERT(NULL != _pr_sleeplock);
179
180 _PR_InitThreads(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
181
182 #ifdef WIN16
183 {
184 PRInt32 top; /* artificial top of stack, win16 */
185 _pr_top_of_task_stack = (char *) &top;
186 }
187 #endif
188
189 #ifndef _PR_GLOBAL_THREADS_ONLY
190 _PR_InitCPUs();
191 #endif
192
193 /*
194 * XXX: call _PR_InitMem only on those platforms for which nspr implements
195 * malloc, for now.
196 */
197 #ifdef _PR_OVERRIDE_MALLOC
198 _PR_InitMem();
199 #endif
200
201 _PR_InitCMon();
202 _PR_InitIO();
203 _PR_InitNet();
204 _PR_InitTime();
205 _PR_InitLog();
206 _PR_InitLinker();
207 _PR_InitCallOnce();
208 _PR_InitDtoa();
209 _PR_InitMW();
210 _PR_InitRWLocks();
211
212 nspr_InitializePRErrorTable();
213
214 _PR_MD_FINAL_INIT();
215 }
216
217 void _PR_ImplicitInitialization(void)
218 {
219 _PR_InitStuff();
220
221 /* Enable interrupts */
222 #if !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY)
223 _PR_MD_START_INTERRUPTS();
224 #endif
225
226 }
227
228 PR_IMPLEMENT(void) PR_DisableClockInterrupts(void)
229 {
230 #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
231 if (!_pr_initialized) {
232 _PR_InitStuff();
233 } else {
234 _PR_MD_DISABLE_CLOCK_INTERRUPTS();
235 }
236 #endif
237 }
238
239 PR_IMPLEMENT(void) PR_EnableClockInterrupts(void)
240 {
241 #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
242 if (!_pr_initialized) {
243 _PR_InitStuff();
244 }
245 _PR_MD_ENABLE_CLOCK_INTERRUPTS();
246 #endif
247 }
248
249 PR_IMPLEMENT(void) PR_BlockClockInterrupts(void)
250 {
251 #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
252 _PR_MD_BLOCK_CLOCK_INTERRUPTS();
253 #endif
254 }
255
256 PR_IMPLEMENT(void) PR_UnblockClockInterrupts(void)
257 {
258 #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
259 _PR_MD_UNBLOCK_CLOCK_INTERRUPTS();
260 #endif
261 }
262
263 PR_IMPLEMENT(void) PR_Init(
264 PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs)
265 {
266 _PR_ImplicitInitialization();
267 }
268
269 PR_IMPLEMENT(PRIntn) PR_Initialize(
270 PRPrimordialFn prmain, PRIntn argc, char **argv, PRUintn maxPTDs)
271 {
272 PRIntn rv;
273 _PR_ImplicitInitialization();
274 rv = prmain(argc, argv);
275 PR_Cleanup();
276 return rv;
277 } /* PR_Initialize */
278
279 /*
280 *-----------------------------------------------------------------------
281 *
282 * _PR_CleanupBeforeExit --
283 *
284 * Perform the cleanup work before exiting the process.
285 * We first do the cleanup generic to all platforms. Then
286 * we call _PR_MD_CLEANUP_BEFORE_EXIT(), where platform-dependent
287 * cleanup is done. This function is used by PR_Cleanup().
288 *
289 * See also: PR_Cleanup().
290 *
291 *-----------------------------------------------------------------------
292 */
293 #if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
294 /* see ptthread.c */
295 #else
296 static void
297 _PR_CleanupBeforeExit(void)
298 {
299 /*
300 Do not make any calls here other than to destroy resources. For example,
301 do not make any calls that eventually may end up in PR_Lock. Because the
302 thread is destroyed, can not access current thread any more.
303 */
304 _PR_CleanupTPD();
305 if (_pr_terminationCVLock)
306 /*
307 * In light of the comment above, this looks real suspicious.
308 * I'd go so far as to say it's just a problem waiting to happen.
309 */
310 PR_DestroyLock(_pr_terminationCVLock);
311
312 _PR_MD_CLEANUP_BEFORE_EXIT();
313 }
314 #endif /* defined(_PR_PTHREADS) */
315
316 /*
317 *----------------------------------------------------------------------
318 *
319 * PR_Cleanup --
320 *
321 * Perform a graceful shutdown of the NSPR runtime. PR_Cleanup() may
322 * only be called from the primordial thread, typically at the
323 * end of the main() function. It returns when it has completed
324 * its platform-dependent duty and the process must not make any other
325 * NSPR library calls prior to exiting from main().
326 *
327 * PR_Cleanup() first blocks the primordial thread until all the
328 * other user (non-system) threads, if any, have terminated.
329 * Then it performs cleanup in preparation for exiting the process.
330 * PR_Cleanup() does not exit the primordial thread (which would
331 * in turn exit the process).
332 *
333 * PR_Cleanup() only responds when it is called by the primordial
334 * thread. Calls by any other thread are silently ignored.
335 *
336 * See also: PR_ExitProcess()
337 *
338 *----------------------------------------------------------------------
339 */
340 #if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
341 /* see ptthread.c */
342 #else
343
344 PR_IMPLEMENT(PRStatus) PR_Cleanup()
345 {
346 PRThread *me = PR_GetCurrentThread();
347 PR_ASSERT((NULL != me) && (me->flags & _PR_PRIMORDIAL));
348 if ((NULL != me) && (me->flags & _PR_PRIMORDIAL))
349 {
350 PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR"));
351
352 /*
353 * No more recycling of threads
354 */
355 _pr_recycleThreads = 0;
356
357 /*
358 * Wait for all other user (non-system/daemon) threads
359 * to terminate.
360 */
361 PR_Lock(_pr_activeLock);
362 while (_pr_userActive > _pr_primordialExitCount) {
363 PR_WaitCondVar(_pr_primordialExitCVar, PR_INTERVAL_NO_TIMEOUT);
364 }
365 if (me->flags & _PR_SYSTEM) {
366 _pr_systemActive--;
367 } else {
368 _pr_userActive--;
369 }
370 PR_Unlock(_pr_activeLock);
371
372 #ifdef IRIX
373 _PR_MD_PRE_CLEANUP(me);
374 /*
375 * The primordial thread must now be running on the primordial c pu
376 */
377 PR_ASSERT((_PR_IS_NATIVE_THREAD(me)) || (me->cpu->id == 0));
378 #endif
379
380 _PR_MD_EARLY_CLEANUP();
381
382 _PR_CleanupMW();
383 _PR_CleanupTime();
384 _PR_CleanupDtoa();
385 _PR_CleanupCallOnce();
386 _PR_ShutdownLinker();
387 _PR_CleanupNet();
388 _PR_CleanupIO();
389 /* Release the primordial thread's private data, etc. */
390 _PR_CleanupThread(me);
391
392 _PR_MD_STOP_INTERRUPTS();
393
394 PR_LOG(_pr_thread_lm, PR_LOG_MIN,
395 ("PR_Cleanup: clean up before destroying thread"));
396 _PR_LogCleanup();
397
398 /*
399 * This part should look like the end of _PR_NativeRunThread
400 * and _PR_UserRunThread.
401 */
402 if (_PR_IS_NATIVE_THREAD(me)) {
403 _PR_MD_EXIT_THREAD(me);
404 _PR_NativeDestroyThread(me);
405 } else {
406 _PR_UserDestroyThread(me);
407 PR_DELETE(me->stack);
408 PR_DELETE(me);
409 }
410
411 /*
412 * XXX: We are freeing the heap memory here so that Purify won't
413 * complain, but we should also free other kinds of resources
414 * that are allocated by the _PR_InitXXX() functions.
415 * Ideally, for each _PR_InitXXX(), there should be a corresponding
416 * _PR_XXXCleanup() that we can call here.
417 */
418 #ifdef WINNT
419 _PR_CleanupCPUs();
420 #endif
421 _PR_CleanupThreads();
422 _PR_CleanupCMon();
423 PR_DestroyLock(_pr_sleeplock);
424 _pr_sleeplock = NULL;
425 _PR_CleanupLayerCache();
426 _PR_CleanupEnv();
427 _PR_CleanupStacks();
428 _PR_CleanupBeforeExit();
429 _pr_initialized = PR_FALSE;
430 return PR_SUCCESS;
431 }
432 return PR_FAILURE;
433 }
434 #endif /* defined(_PR_PTHREADS) */
435
436 /*
437 *------------------------------------------------------------------------
438 * PR_ProcessExit --
439 *
440 * Cause an immediate, nongraceful, forced termination of the process.
441 * It takes a PRIntn argument, which is the exit status code of the
442 * process.
443 *
444 * See also: PR_Cleanup()
445 *
446 *------------------------------------------------------------------------
447 */
448
449 #if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
450 /* see ptthread.c */
451 #else
452 PR_IMPLEMENT(void) PR_ProcessExit(PRIntn status)
453 {
454 _PR_MD_EXIT(status);
455 }
456
457 #endif /* defined(_PR_PTHREADS) */
458
459 PR_IMPLEMENT(PRProcessAttr *)
460 PR_NewProcessAttr(void)
461 {
462 PRProcessAttr *attr;
463
464 attr = PR_NEWZAP(PRProcessAttr);
465 if (!attr) {
466 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
467 }
468 return attr;
469 }
470
471 PR_IMPLEMENT(void)
472 PR_ResetProcessAttr(PRProcessAttr *attr)
473 {
474 PR_FREEIF(attr->currentDirectory);
475 PR_FREEIF(attr->fdInheritBuffer);
476 memset(attr, 0, sizeof(*attr));
477 }
478
479 PR_IMPLEMENT(void)
480 PR_DestroyProcessAttr(PRProcessAttr *attr)
481 {
482 PR_FREEIF(attr->currentDirectory);
483 PR_FREEIF(attr->fdInheritBuffer);
484 PR_DELETE(attr);
485 }
486
487 PR_IMPLEMENT(void)
488 PR_ProcessAttrSetStdioRedirect(
489 PRProcessAttr *attr,
490 PRSpecialFD stdioFd,
491 PRFileDesc *redirectFd)
492 {
493 switch (stdioFd) {
494 case PR_StandardInput:
495 attr->stdinFd = redirectFd;
496 break;
497 case PR_StandardOutput:
498 attr->stdoutFd = redirectFd;
499 break;
500 case PR_StandardError:
501 attr->stderrFd = redirectFd;
502 break;
503 default:
504 PR_ASSERT(0);
505 }
506 }
507
508 /*
509 * OBSOLETE
510 */
511 PR_IMPLEMENT(void)
512 PR_SetStdioRedirect(
513 PRProcessAttr *attr,
514 PRSpecialFD stdioFd,
515 PRFileDesc *redirectFd)
516 {
517 #if defined(DEBUG)
518 static PRBool warn = PR_TRUE;
519 if (warn) {
520 warn = _PR_Obsolete("PR_SetStdioRedirect()",
521 "PR_ProcessAttrSetStdioRedirect()");
522 }
523 #endif
524 PR_ProcessAttrSetStdioRedirect(attr, stdioFd, redirectFd);
525 }
526
527 PR_IMPLEMENT(PRStatus)
528 PR_ProcessAttrSetCurrentDirectory(
529 PRProcessAttr *attr,
530 const char *dir)
531 {
532 PR_FREEIF(attr->currentDirectory);
533 attr->currentDirectory = (char *) PR_MALLOC(strlen(dir) + 1);
534 if (!attr->currentDirectory) {
535 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
536 return PR_FAILURE;
537 }
538 strcpy(attr->currentDirectory, dir);
539 return PR_SUCCESS;
540 }
541
542 PR_IMPLEMENT(PRStatus)
543 PR_ProcessAttrSetInheritableFD(
544 PRProcessAttr *attr,
545 PRFileDesc *fd,
546 const char *name)
547 {
548 /* We malloc the fd inherit buffer in multiples of this number. */
549 #define FD_INHERIT_BUFFER_INCR 128
550 /* The length of "NSPR_INHERIT_FDS=" */
551 #define NSPR_INHERIT_FDS_STRLEN 17
552 /* The length of osfd (PROsfd) printed in hexadecimal with 0x prefix */
553 #ifdef _WIN64
554 #define OSFD_STRLEN 18
555 #else
556 #define OSFD_STRLEN 10
557 #endif
558 /* The length of fd type (PRDescType) printed in decimal */
559 #define FD_TYPE_STRLEN 1
560 PRSize newSize;
561 int remainder;
562 char *newBuffer;
563 int nwritten;
564 char *cur;
565 int freeSize;
566
567 if (fd->identity != PR_NSPR_IO_LAYER) {
568 PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
569 return PR_FAILURE;
570 }
571 if (fd->secret->inheritable == _PR_TRI_UNKNOWN) {
572 _PR_MD_QUERY_FD_INHERITABLE(fd);
573 }
574 if (fd->secret->inheritable != _PR_TRI_TRUE) {
575 PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0);
576 return PR_FAILURE;
577 }
578
579 /*
580 * We also need to account for the : separators and the
581 * terminating null byte.
582 */
583 if (NULL == attr->fdInheritBuffer) {
584 /* The first time, we print "NSPR_INHERIT_FDS=<name>:<type>:<val>" */
585 newSize = NSPR_INHERIT_FDS_STRLEN + strlen(name)
586 + FD_TYPE_STRLEN + OSFD_STRLEN + 2 + 1;
587 } else {
588 /* At other times, we print ":<name>:<type>:<val>" */
589 newSize = attr->fdInheritBufferUsed + strlen(name)
590 + FD_TYPE_STRLEN + OSFD_STRLEN + 3 + 1;
591 }
592 if (newSize > attr->fdInheritBufferSize) {
593 /* Make newSize a multiple of FD_INHERIT_BUFFER_INCR */
594 remainder = newSize % FD_INHERIT_BUFFER_INCR;
595 if (remainder != 0) {
596 newSize += (FD_INHERIT_BUFFER_INCR - remainder);
597 }
598 if (NULL == attr->fdInheritBuffer) {
599 newBuffer = (char *) PR_MALLOC(newSize);
600 } else {
601 newBuffer = (char *) PR_REALLOC(attr->fdInheritBuffer, newSize);
602 }
603 if (NULL == newBuffer) {
604 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
605 return PR_FAILURE;
606 }
607 attr->fdInheritBuffer = newBuffer;
608 attr->fdInheritBufferSize = newSize;
609 }
610 cur = attr->fdInheritBuffer + attr->fdInheritBufferUsed;
611 freeSize = attr->fdInheritBufferSize - attr->fdInheritBufferUsed;
612 if (0 == attr->fdInheritBufferUsed) {
613 nwritten = PR_snprintf(cur, freeSize,
614 "NSPR_INHERIT_FDS=%s:%d:0x%" PR_PRIxOSFD,
615 name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd);
616 } else {
617 nwritten = PR_snprintf(cur, freeSize, ":%s:%d:0x%" PR_PRIxOSFD,
618 name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd);
619 }
620 attr->fdInheritBufferUsed += nwritten;
621 return PR_SUCCESS;
622 }
623
624 PR_IMPLEMENT(PRFileDesc *) PR_GetInheritedFD(
625 const char *name)
626 {
627 PRFileDesc *fd;
628 const char *envVar;
629 const char *ptr;
630 int len = strlen(name);
631 PROsfd osfd;
632 int nColons;
633 PRIntn fileType;
634
635 envVar = PR_GetEnv("NSPR_INHERIT_FDS");
636 if (NULL == envVar || '\0' == envVar[0]) {
637 PR_SetError(PR_UNKNOWN_ERROR, 0);
638 return NULL;
639 }
640
641 ptr = envVar;
642 while (1) {
643 if ((ptr[len] == ':') && (strncmp(ptr, name, len) == 0)) {
644 ptr += len + 1;
645 if (PR_sscanf(ptr, "%d:0x%" PR_SCNxOSFD, &fileType, &osfd) != 2) {
646 PR_SetError(PR_UNKNOWN_ERROR, 0);
647 return NULL;
648 }
649 switch ((PRDescType)fileType) {
650 case PR_DESC_FILE:
651 fd = PR_ImportFile(osfd);
652 break;
653 case PR_DESC_PIPE:
654 fd = PR_ImportPipe(osfd);
655 break;
656 case PR_DESC_SOCKET_TCP:
657 fd = PR_ImportTCPSocket(osfd);
658 break;
659 case PR_DESC_SOCKET_UDP:
660 fd = PR_ImportUDPSocket(osfd);
661 break;
662 default:
663 PR_ASSERT(0);
664 PR_SetError(PR_UNKNOWN_ERROR, 0);
665 fd = NULL;
666 break;
667 }
668 if (fd) {
669 /*
670 * An inherited FD is inheritable by default.
671 * The child process needs to call PR_SetFDInheritable
672 * to make it non-inheritable if so desired.
673 */
674 fd->secret->inheritable = _PR_TRI_TRUE;
675 }
676 return fd;
677 }
678 /* Skip three colons */
679 nColons = 0;
680 while (*ptr) {
681 if (*ptr == ':') {
682 if (++nColons == 3) {
683 break;
684 }
685 }
686 ptr++;
687 }
688 if (*ptr == '\0') {
689 PR_SetError(PR_UNKNOWN_ERROR, 0);
690 return NULL;
691 }
692 ptr++;
693 }
694 }
695
696 PR_IMPLEMENT(PRProcess*) PR_CreateProcess(
697 const char *path,
698 char *const *argv,
699 char *const *envp,
700 const PRProcessAttr *attr)
701 {
702 return _PR_MD_CREATE_PROCESS(path, argv, envp, attr);
703 } /* PR_CreateProcess */
704
705 PR_IMPLEMENT(PRStatus) PR_CreateProcessDetached(
706 const char *path,
707 char *const *argv,
708 char *const *envp,
709 const PRProcessAttr *attr)
710 {
711 PRProcess *process;
712 PRStatus rv;
713
714 process = PR_CreateProcess(path, argv, envp, attr);
715 if (NULL == process) {
716 return PR_FAILURE;
717 }
718 rv = PR_DetachProcess(process);
719 PR_ASSERT(PR_SUCCESS == rv);
720 if (rv == PR_FAILURE) {
721 PR_DELETE(process);
722 return PR_FAILURE;
723 }
724 return PR_SUCCESS;
725 }
726
727 PR_IMPLEMENT(PRStatus) PR_DetachProcess(PRProcess *process)
728 {
729 return _PR_MD_DETACH_PROCESS(process);
730 }
731
732 PR_IMPLEMENT(PRStatus) PR_WaitProcess(PRProcess *process, PRInt32 *exitCode)
733 {
734 return _PR_MD_WAIT_PROCESS(process, exitCode);
735 } /* PR_WaitProcess */
736
737 PR_IMPLEMENT(PRStatus) PR_KillProcess(PRProcess *process)
738 {
739 return _PR_MD_KILL_PROCESS(process);
740 }
741
742 /*
743 ********************************************************************
744 *
745 * Module initialization
746 *
747 ********************************************************************
748 */
749
750 static struct {
751 PRLock *ml;
752 PRCondVar *cv;
753 } mod_init;
754
755 static void _PR_InitCallOnce(void) {
756 mod_init.ml = PR_NewLock();
757 PR_ASSERT(NULL != mod_init.ml);
758 mod_init.cv = PR_NewCondVar(mod_init.ml);
759 PR_ASSERT(NULL != mod_init.cv);
760 }
761
762 void _PR_CleanupCallOnce()
763 {
764 PR_DestroyLock(mod_init.ml);
765 mod_init.ml = NULL;
766 PR_DestroyCondVar(mod_init.cv);
767 mod_init.cv = NULL;
768 }
769
770 PR_IMPLEMENT(PRStatus) PR_CallOnce(
771 PRCallOnceType *once,
772 PRCallOnceFN func)
773 {
774 if (!_pr_initialized) _PR_ImplicitInitialization();
775
776 if (!once->initialized) {
777 if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) {
778 once->status = (*func)();
779 PR_Lock(mod_init.ml);
780 once->initialized = 1;
781 PR_NotifyAllCondVar(mod_init.cv);
782 PR_Unlock(mod_init.ml);
783 } else {
784 PR_Lock(mod_init.ml);
785 while (!once->initialized) {
786 PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT);
787 }
788 PR_Unlock(mod_init.ml);
789 }
790 } else {
791 if (PR_SUCCESS != once->status) {
792 PR_SetError(PR_CALL_ONCE_ERROR, 0);
793 }
794 }
795 return once->status;
796 }
797
798 PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg(
799 PRCallOnceType *once,
800 PRCallOnceWithArgFN func,
801 void *arg)
802 {
803 if (!_pr_initialized) _PR_ImplicitInitialization();
804
805 if (!once->initialized) {
806 if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) {
807 once->status = (*func)(arg);
808 PR_Lock(mod_init.ml);
809 once->initialized = 1;
810 PR_NotifyAllCondVar(mod_init.cv);
811 PR_Unlock(mod_init.ml);
812 } else {
813 PR_Lock(mod_init.ml);
814 while (!once->initialized) {
815 PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT);
816 }
817 PR_Unlock(mod_init.ml);
818 }
819 } else {
820 if (PR_SUCCESS != once->status) {
821 PR_SetError(PR_CALL_ONCE_ERROR, 0);
822 }
823 }
824 return once->status;
825 }
826
827 PRBool _PR_Obsolete(const char *obsolete, const char *preferred)
828 {
829 #if defined(DEBUG)
830 PR_fprintf(
831 PR_STDERR, "'%s' is obsolete. Use '%s' instead.\n",
832 obsolete, (NULL == preferred) ? "something else" : preferred);
833 #endif
834 return PR_FALSE;
835 } /* _PR_Obsolete */
836
837 /* prinit.c */
838
839
OLDNEW
« no previous file with comments | « nspr/pr/src/misc/prerrortable.c ('k') | nspr/pr/src/misc/prinrval.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698