PR_IMPLEMENT(PRSemaphore*) PR_NewSem(PRUintn value) { PRSemaphore *semaphore; static PRBool unwarned = PR_TRUE; if (!_pr_initialized) _PR_ImplicitInitialization(); if (unwarned) unwarned = _PR_Obsolete( "PR_NewSem", "locks & condition variables"); semaphore = PR_NEWZAP(PRSemaphore); if (NULL != semaphore) { PRLock *lock = PR_NewLock(); if (NULL != lock) { semaphore->cvar = PR_NewCondVar(lock); if (NULL != semaphore->cvar) { semaphore->count = value; return semaphore; } PR_DestroyLock(lock); } PR_Free(semaphore); } return NULL; }
PR_IMPLEMENT(PRStatus) PR_NewThreadPrivateIndex( PRUintn *newIndex, PRThreadPrivateDTOR dtor) { PRStatus rv; PRInt32 index; if (!_pr_initialized) _PR_ImplicitInitialization(); PR_ASSERT(NULL != newIndex); PR_ASSERT(NULL != _pr_tpd_destructors); index = PR_ATOMIC_INCREMENT(&_pr_tpd_highwater) - 1; /* allocate index */ if (_PR_TPD_LIMIT <= index) { PR_SetError(PR_TPD_RANGE_ERROR, 0); rv = PR_FAILURE; /* that's just wrong */ } else { _pr_tpd_destructors[index] = dtor; /* record destructor @index */ *newIndex = (PRUintn)index; /* copy into client's location */ rv = PR_SUCCESS; /* that's okay */ } return rv; }
PR_IMPLEMENT(char*) PR_GetEnvSecure(const char *var) { #ifdef HAVE_SECURE_GETENV char *ev; if (!_pr_initialized) _PR_ImplicitInitialization(); _PR_LOCK_ENV(); ev = secure_getenv(var); _PR_UNLOCK_ENV(); return ev; #else #ifdef XP_UNIX /* ** Fall back to checking uids and gids. This won't detect any other ** privilege-granting mechanisms the platform may have. This also ** can't detect the case where the process already called ** setuid(geteuid()) and/or setgid(getegid()). */ if (getuid() != geteuid() || getgid() != getegid()) { return NULL; } #endif /* XP_UNIX */ return PR_GetEnv(var); #endif /* HAVE_SECURE_GETENV */ }
PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg( PRCallOnceType *once, PRCallOnceWithArgFN func, void *arg) { if (!_pr_initialized) _PR_ImplicitInitialization(); if (!once->initialized) { if (PR_ATOMIC_SET(&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); } } else { if (PR_SUCCESS != once->status) { PR_SetError(PR_CALL_ONCE_ERROR, 0); } } return once->status; }
PR_DeleteSharedMemory( const char *name ) { if (!_pr_initialized) _PR_ImplicitInitialization(); return(_PR_MD_DELETE_SHARED_MEMORY( name )); } /* end PR_DestroySharedMemory() */
PR_IMPLEMENT(PRIntn) PR_Initialize( PRPrimordialFn prmain, PRIntn argc, char **argv, PRUintn maxPTDs) { PRIntn rv; _PR_ImplicitInitialization(); rv = prmain(argc, argv); PR_Cleanup(); return rv; } /* PR_Initialize */
PR_IMPLEMENT(PRStatus) PR_SetFDCacheSize(PRIntn low, PRIntn high) { /* ** This can be called at any time, may adjust the cache sizes, ** turn the caches off, or turn them on. It is not dependent ** on the compilation setting of DEBUG. */ if (!_pr_initialized) _PR_ImplicitInitialization(); if (low > high) low = high; /* sanity check the params */ PR_Lock(_pr_fd_cache.ml); if (0 == high) /* shutting down or staying down */ { if (0 != _pr_fd_cache.limit_high) /* shutting down */ { _pr_fd_cache.limit_high = 0; /* stop use */ /* ** Hold the lock throughout - nobody's going to want it ** other than another caller to this routine. Just don't ** let that happen. ** ** Put all the cached fds onto the new cache. */ while (NULL != _pr_fd_cache.head) { PRFileDesc *fd = _pr_fd_cache.head; _pr_fd_cache.head = fd->higher; PR_StackPush(_pr_fd_cache.stack, (PRStackElem*)(&fd->higher)); } _pr_fd_cache.limit_low = 0; _pr_fd_cache.tail = NULL; _pr_fd_cache.count = 0; } } else /* starting up or just adjusting parameters */ { PRBool was_using_stack = (0 == _pr_fd_cache.limit_high); _pr_fd_cache.limit_low = low; _pr_fd_cache.limit_high = high; if (was_using_stack) /* was using stack - feed into cache */ { PRStackElem *pop; while (NULL != (pop = PR_StackPop(_pr_fd_cache.stack))) { PRFileDesc *fd = (PRFileDesc*) ((PRPtrdiff)pop - (PRPtrdiff)stack2fd); if (NULL == _pr_fd_cache.tail) _pr_fd_cache.tail = fd; fd->higher = _pr_fd_cache.head; _pr_fd_cache.head = fd; _pr_fd_cache.count += 1; } } } PR_Unlock(_pr_fd_cache.ml); return PR_SUCCESS; } /* PR_SetFDCacheSize */
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(const char*) PR_GetNameForIdentity(PRDescIdentity ident) { if (!_pr_initialized) _PR_ImplicitInitialization(); if (PR_TOP_IO_LAYER == ident) return NULL; PR_ASSERT(ident <= identity_cache.ident); return (ident > identity_cache.ident) ? NULL : identity_cache.name[ident]; } /* PR_GetNameForIdentity */
PR_IMPLEMENT(void) PR_LogPrint(const char *fmt, ...) { va_list ap; char line[LINE_BUF_SIZE]; PRUint32 nb; PRThread *me; if (!_pr_initialized) _PR_ImplicitInitialization(); if (!logFile) { return; } va_start(ap, fmt); me = PR_GetCurrentThread(); nb = PR_snprintf(line, sizeof(line)-1, "%ld[%p]: ", #if defined(_PR_DCETHREADS) /* The problem is that for _PR_DCETHREADS, pthread_t is not a * pointer, but a structure; so you can't easily print it... */ me ? &(me->id): 0L, me); #elif defined(_PR_BTHREADS) me, me); #else me ? me->id : 0L, me); #endif nb += PR_vsnprintf(line+nb, sizeof(line)-nb-1, fmt, ap); if (nb && (line[nb-1] != '\n')) { #ifndef XP_MAC line[nb++] = '\n'; #else line[nb++] = '\015'; #endif line[nb] = '\0'; } else { #ifdef XP_MAC line[nb-1] = '\015'; #endif } va_end(ap); _PR_LOCK_LOG(); if (logBuf == 0) { _PUT_LOG(logFile, line, nb); } else { if (logp + nb > logEndp) { _PUT_LOG(logFile, logBuf, logp - logBuf); logp = logBuf; } memcpy(logp, line, nb); logp += nb; } _PR_UNLOCK_LOG(); PR_LogFlush(); }
PR_OpenSharedMemory( const char *name, PRSize size, PRIntn flags, PRIntn mode ) { if (!_pr_initialized) _PR_ImplicitInitialization(); return( _PR_MD_OPEN_SHARED_MEMORY( name, size, flags, mode )); } /* end PR_OpenSharedMemory() */
PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name) { char osname[PR_IPC_NAME_SIZE]; if (!_pr_initialized) _PR_ImplicitInitialization(); if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) == PR_FAILURE) { return PR_FAILURE; } return _PR_MD_DELETE_SEMAPHORE(osname); }
PR_IMPLEMENT(char*) PR_GetEnv(const char *var) { char *ev; if (!_pr_initialized) _PR_ImplicitInitialization(); _PR_LOCK_ENV(); ev = _PR_MD_GET_ENV(var); _PR_UNLOCK_ENV(); return ev; }
PR_IMPLEMENT(PRSem *) PR_OpenSemaphore( const char *name, PRIntn flags, PRIntn mode, PRUintn value) { char osname[PR_IPC_NAME_SIZE]; if (!_pr_initialized) _PR_ImplicitInitialization(); if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) == PR_FAILURE) { return NULL; } return _PR_MD_OPEN_SEMAPHORE(osname, flags, mode, value); }
PR_IMPLEMENT(PRStatus) PR_SetEnv(const char *string) { PRIntn result; if (!_pr_initialized) _PR_ImplicitInitialization(); if ( !strchr(string, '=')) return(PR_FAILURE); _PR_LOCK_ENV(); result = _PR_MD_PUT_ENV(string); _PR_UNLOCK_ENV(); return (result)? PR_FAILURE : PR_SUCCESS; }
PR_IMPLEMENT(PRFileDesc *) PR_ImportUDPSocket(PROsfd osfd) { PRFileDesc *fd; if (!_pr_initialized) _PR_ImplicitInitialization(); fd = PR_AllocFileDesc(osfd, PR_GetUDPMethods()); if (fd != NULL) { _PR_MD_MAKE_NONBLOCK(fd); _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE); } else _PR_MD_CLOSE_SOCKET(osfd); return(fd); }
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_IMPLEMENT(PRStatus) PR_NewThreadPrivateIndex( PRUintn *newIndex, PRThreadPrivateDTOR dtor) { PRStatus rv; if (!_pr_initialized) _PR_ImplicitInitialization(); if (_pr_tpd_highwater >= _PR_TPD_LIMIT) { PR_SetError(PR_TPD_RANGE_ERROR, 0); rv = PR_FAILURE; /* that's just wrong */ } else { PRThreadPrivateDTOR *old = NULL; PRIntn _is; _PR_LOCK_TPINDEX(); if (_pr_tpd_highwater >= _pr_tpd_length) { old = _pr_tpd_destructors; _pr_tpd_destructors = PR_CALLOC( (_pr_tpd_length + _PR_TPD_MODULO) * sizeof(PRThreadPrivateDTOR*)); if (NULL == _pr_tpd_destructors) { _pr_tpd_destructors = old; old = NULL; PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); rv = PR_FAILURE; /* that's just wrong */ goto failed; /* then extract one's self */ } else { memcpy( _pr_tpd_destructors, old, _pr_tpd_length * sizeof(PRThreadPrivateDTOR*)); _pr_tpd_length += _PR_TPD_MODULO; } } *newIndex = _pr_tpd_highwater++; /* this is really all we wanted */ _pr_tpd_destructors[*newIndex] = dtor; /* record destructor @index */ failed: _PR_UNLOCK_TPINDEX(); if (NULL != old) PR_DELETE(old); rv = PR_SUCCESS; } return rv; }
PR_IMPLEMENT(PRLock*) PR_NewLock(void) { PRLock *lock; if (!_pr_initialized) _PR_ImplicitInitialization(); lock = PR_NEWZAP(PRLock); if (lock) { if (_PR_InitLock(lock) != PR_SUCCESS) { PR_DELETE(lock); return NULL; } } return lock; }
PR_NewSem (PRUintn value) { PRSemaphore *semaphore; if (!_pr_initialized) _PR_ImplicitInitialization(); semaphore = PR_NEWZAP(PRSemaphore); if (NULL != semaphore) { if ((semaphore->sem = create_sem(value, "nspr_sem")) < B_NO_ERROR) return NULL; else return semaphore; } return NULL; }
PR_IMPLEMENT(PRLogModuleInfo*) PR_NewLogModule(const char *name) { PRLogModuleInfo *lm; if (!_pr_initialized) _PR_ImplicitInitialization(); lm = PR_NEWZAP(PRLogModuleInfo); if (lm) { lm->name = strdup(name); lm->level = PR_LOG_NONE; lm->next = logModules; logModules = lm; _PR_SetLogModuleLevel(lm); } return lm; }
PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void) { PRCondVar *cv; if (!_pr_initialized) _PR_ImplicitInitialization(); cv = PR_NEW(PRCondVar); if (cv != NULL) { int rv; rv = _PT_PTHREAD_COND_INIT(cv->cv, _pt_cvar_attr); PR_ASSERT(0 == rv); cv->lock = _PR_NAKED_CV_LOCK; } return cv; } /* PRP_NewNakedCondVar */
PR_IMPLEMENT(PRMonitor*) PR_NewMonitor(void) { PRMonitor *mon; int rv; if (!_pr_initialized) _PR_ImplicitInitialization(); mon = PR_NEWZAP(PRMonitor); if (mon == NULL) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return NULL; } rv = _PT_PTHREAD_MUTEX_INIT(mon->lock, _pt_mattr); PR_ASSERT(0 == rv); if (0 != rv) goto error1; _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner); rv = _PT_PTHREAD_COND_INIT(mon->entryCV, _pt_cvar_attr); PR_ASSERT(0 == rv); if (0 != rv) goto error2; rv = _PT_PTHREAD_COND_INIT(mon->waitCV, _pt_cvar_attr); PR_ASSERT(0 == rv); if (0 != rv) goto error3; mon->notifyTimes = 0; mon->entryCount = 0; mon->refCount = 1; mon->name = NULL; return mon; error3: pthread_cond_destroy(&mon->entryCV); error2: pthread_mutex_destroy(&mon->lock); error1: PR_Free(mon); PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0); return NULL; } /* PR_NewMonitor */
PR_IMPLEMENT(PRStatus) PR_SetFDCacheSize(PRIntn low, PRIntn high) { /* ** This can be called at any time, may adjust the cache sizes, ** turn the caches off, or turn them on. It is not dependent ** on the compilation setting of DEBUG. */ if (!_pr_initialized) _PR_ImplicitInitialization(); if (low > high) low = high; /* sanity check the params */ PR_Lock(_pr_fd_cache.ml); _pr_fd_cache.limit_high = high; _pr_fd_cache.limit_low = low; PR_Unlock(_pr_fd_cache.ml); return PR_SUCCESS; } /* PR_SetFDCacheSize */
PR_IMPLEMENT(PRLock*) PR_NewLock(void) { PRLock *lock; if (!_pr_initialized) _PR_ImplicitInitialization(); lock = PR_NEWZAP(PRLock); if (lock) { if (_PR_MD_NEW_LOCK(&lock->ilock) == PR_FAILURE) { PR_DELETE(lock); return(NULL); } PR_INIT_CLIST(&lock->links); PR_INIT_CLIST(&lock->waitQ); } return lock; }
PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd) { PRFileDesc *result = NULL; PR_ASSERT((int) osfd >= PR_StandardInput && osfd <= PR_StandardError); if (!_pr_initialized) _PR_ImplicitInitialization(); switch (osfd) { case PR_StandardInput: result = _pr_stdin; break; case PR_StandardOutput: result = _pr_stdout; break; case PR_StandardError: result = _pr_stderr; break; default: (void)PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); } return result; }
PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode) { PRInt32 osfd; PRFileDesc *fd = 0; if (!_pr_initialized) _PR_ImplicitInitialization(); /* Map pr open flags and mode to os specific flags */ osfd = _PR_MD_OPEN(name, flags, mode); if (osfd != -1) { fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); if (!fd) { (void) _PR_MD_CLOSE_FILE(osfd); } } return fd; }
PR_IMPLEMENT(PRLock*) PR_NewLock(void) { PRIntn rv; PRLock *lock; if (!_pr_initialized) _PR_ImplicitInitialization(); lock = PR_NEWZAP(PRLock); if (lock != NULL) { rv = _PT_PTHREAD_MUTEX_INIT(lock->mutex, _pt_mattr); PR_ASSERT(0 == rv); } #if defined(DEBUG) pt_debug.locks_created += 1; #endif return lock; } /* PR_NewLock */
PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 buflen) { PRUintn len = 0; if (!_pr_initialized) _PR_ImplicitInitialization(); switch(cmd) { case PR_SI_HOSTNAME: if (PR_FAILURE == _PR_MD_GETHOSTNAME(buf, (PRUintn)buflen)) return PR_FAILURE; /* Return the unqualified hostname */ while (buf[len] && (len < buflen)) { if (buf[len] == '.') { buf[len] = '\0'; break; } len += 1; } break; case PR_SI_SYSNAME: /* Return the operating system name */ (void)PR_snprintf(buf, buflen, _PR_SI_SYSNAME); break; case PR_SI_RELEASE: /* Return the version of the operating system */ #if defined(XP_UNIX) { struct utsname info; uname(&info); (void)PR_snprintf(buf, buflen, info.release); } #endif break; case PR_SI_ARCHITECTURE: /* Return the architecture of the machine (ie. x86, mips, alpha, ...)*/ (void)PR_snprintf(buf, buflen, _PR_SI_ARCHITECTURE); break; } return PR_SUCCESS; }
PR_IMPLEMENT(PRFileDesc*) PR_CreateSocketPollFd(PROsfd osfd) { PRFileDesc *fd; if (!_pr_initialized) _PR_ImplicitInitialization(); fd = _PR_Getfd(); if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); else { fd->secret->md.osfd = osfd; fd->secret->inheritable = _PR_TRI_FALSE; fd->secret->state = _PR_FILEDESC_OPEN; fd->methods = PR_GetSocketPollFdMethods(); } return fd; } /* PR_CreateSocketPollFD */