1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/include/private/primpl.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,2151 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef primpl_h___ 1.10 +#define primpl_h___ 1.11 + 1.12 +/* 1.13 + * HP-UX 10.10's pthread.h (DCE threads) includes dce/cma.h, which 1.14 + * has: 1.15 + * #define sigaction _sigaction_sys 1.16 + * This macro causes chaos if signal.h gets included before pthread.h. 1.17 + * To be safe, we include pthread.h first. 1.18 + */ 1.19 + 1.20 +#if defined(_PR_PTHREADS) 1.21 +#include <pthread.h> 1.22 +#endif 1.23 + 1.24 +#if defined(_PR_BTHREADS) 1.25 +#include <kernel/OS.h> 1.26 +#endif 1.27 + 1.28 +#ifdef WIN32 1.29 +/* 1.30 + * Allow use of functions and symbols first defined in Win2k. 1.31 + */ 1.32 +#if !defined(WINVER) || (WINVER < 0x0500) 1.33 +#undef WINVER 1.34 +#define WINVER 0x0500 1.35 +#endif 1.36 +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) 1.37 +#undef _WIN32_WINNT 1.38 +#define _WIN32_WINNT 0x0500 1.39 +#endif 1.40 +#endif /* WIN32 */ 1.41 + 1.42 +#include "nspr.h" 1.43 +#include "prpriv.h" 1.44 + 1.45 +typedef struct PRSegment PRSegment; 1.46 + 1.47 +#include "md/prosdep.h" 1.48 +#include "obsolete/probslet.h" 1.49 + 1.50 +#ifdef _PR_HAVE_POSIX_SEMAPHORES 1.51 +#include <semaphore.h> 1.52 +#elif defined(_PR_HAVE_SYSV_SEMAPHORES) 1.53 +#include <sys/sem.h> 1.54 +#endif 1.55 + 1.56 +#ifdef HAVE_SYSCALL 1.57 +#include <sys/syscall.h> 1.58 +#endif 1.59 + 1.60 +/************************************************************************* 1.61 +***** A Word about Model Dependent Function Naming Convention *********** 1.62 +*************************************************************************/ 1.63 + 1.64 +/* 1.65 +NSPR 2.0 must implement its function across a range of platforms 1.66 +including: MAC, Windows/16, Windows/95, Windows/NT, and several 1.67 +variants of Unix. Each implementation shares common code as well 1.68 +as having platform dependent portions. This standard describes how 1.69 +the model dependent portions are to be implemented. 1.70 + 1.71 +In header file pr/include/primpl.h, each publicly declared 1.72 +platform dependent function is declared as: 1.73 + 1.74 +NSPR_API void _PR_MD_FUNCTION( long arg1, long arg2 ); 1.75 +#define _PR_MD_FUNCTION _MD_FUNCTION 1.76 + 1.77 +In header file pr/include/md/<platform>/_<platform>.h, 1.78 +each #define'd macro is redefined as one of: 1.79 + 1.80 +#define _MD_FUNCTION <blanks> 1.81 +#define _MD_FUNCTION <expanded macro> 1.82 +#define _MD_FUNCTION <osFunction> 1.83 +#define _MD_FUNCTION <_MD_Function> 1.84 + 1.85 +Where: 1.86 + 1.87 +<blanks> is no definition at all. In this case, the function is not implemented 1.88 +and is never called for this platform. 1.89 +For example: 1.90 +#define _MD_INIT_CPUS() 1.91 + 1.92 +<expanded macro> is a C language macro expansion. 1.93 +For example: 1.94 +#define _MD_CLEAN_THREAD(_thread) \ 1.95 + PR_BEGIN_MACRO \ 1.96 + PR_DestroyCondVar(_thread->md.asyncIOCVar); \ 1.97 + PR_DestroyLock(_thread->md.asyncIOLock); \ 1.98 + PR_END_MACRO 1.99 + 1.100 +<osFunction> is some function implemented by the host operating system. 1.101 +For example: 1.102 +#define _MD_EXIT exit 1.103 + 1.104 +<_MD_function> is the name of a function implemented for this platform in 1.105 +pr/src/md/<platform>/<soruce>.c file. 1.106 +For example: 1.107 +#define _MD_GETFILEINFO _MD_GetFileInfo 1.108 + 1.109 +In <source>.c, the implementation is: 1.110 +PR_IMPLEMENT(PRInt32) _MD_GetFileInfo(const char *fn, PRFileInfo *info); 1.111 +*/ 1.112 + 1.113 +PR_BEGIN_EXTERN_C 1.114 + 1.115 +typedef struct _MDLock _MDLock; 1.116 +typedef struct _MDCVar _MDCVar; 1.117 +typedef struct _MDSegment _MDSegment; 1.118 +typedef struct _MDThread _MDThread; 1.119 +typedef struct _MDThreadStack _MDThreadStack; 1.120 +typedef struct _MDSemaphore _MDSemaphore; 1.121 +typedef struct _MDDir _MDDir; 1.122 +#ifdef MOZ_UNICODE 1.123 +typedef struct _MDDirUTF16 _MDDirUTF16; 1.124 +#endif /* MOZ_UNICODE */ 1.125 +typedef struct _MDFileDesc _MDFileDesc; 1.126 +typedef struct _MDProcess _MDProcess; 1.127 +typedef struct _MDFileMap _MDFileMap; 1.128 + 1.129 +#if defined(_PR_PTHREADS) 1.130 + 1.131 +/* 1.132 +** The following definitions are unique to implementing NSPR using pthreads. 1.133 +** Since pthreads defines most of the thread and thread synchronization 1.134 +** stuff, this is a pretty small set. 1.135 +*/ 1.136 + 1.137 +#define PT_CV_NOTIFIED_LENGTH 6 1.138 +typedef struct _PT_Notified _PT_Notified; 1.139 +struct _PT_Notified 1.140 +{ 1.141 + PRIntn length; /* # of used entries in this structure */ 1.142 + struct 1.143 + { 1.144 + PRCondVar *cv; /* the condition variable notified */ 1.145 + PRIntn times; /* and the number of times notified */ 1.146 + } cv[PT_CV_NOTIFIED_LENGTH]; 1.147 + _PT_Notified *link; /* link to another of these | NULL */ 1.148 +}; 1.149 + 1.150 +/* 1.151 + * bits defined for pthreads 'state' field 1.152 + */ 1.153 +#define PT_THREAD_DETACHED 0x01 /* thread can't be joined */ 1.154 +#define PT_THREAD_GLOBAL 0x02 /* a global thread (unlikely) */ 1.155 +#define PT_THREAD_SYSTEM 0x04 /* system (not user) thread */ 1.156 +#define PT_THREAD_PRIMORD 0x08 /* this is the primordial thread */ 1.157 +#define PT_THREAD_ABORTED 0x10 /* thread has been interrupted */ 1.158 +#define PT_THREAD_GCABLE 0x20 /* thread is garbage collectible */ 1.159 +#define PT_THREAD_SUSPENDED 0x40 /* thread has been suspended */ 1.160 +#define PT_THREAD_FOREIGN 0x80 /* thread is not one of ours */ 1.161 +#define PT_THREAD_BOUND 0x100 /* a bound-global thread */ 1.162 + 1.163 +#define _PT_THREAD_INTERRUPTED(thr) \ 1.164 + (!(thr->interrupt_blocked) && (thr->state & PT_THREAD_ABORTED)) 1.165 +#define _PT_THREAD_BLOCK_INTERRUPT(thr) \ 1.166 + (thr->interrupt_blocked = 1) 1.167 +#define _PT_THREAD_UNBLOCK_INTERRUPT(thr) \ 1.168 + (thr->interrupt_blocked = 0) 1.169 + 1.170 +#define _PT_IS_GCABLE_THREAD(thr) ((thr)->state & PT_THREAD_GCABLE) 1.171 + 1.172 +/* 1.173 +** Possible values for thread's suspend field 1.174 +** Note that the first two can be the same as they are really mutually exclusive, 1.175 +** i.e. both cannot be happening at the same time. We have two symbolic names 1.176 +** just as a mnemonic. 1.177 +**/ 1.178 +#define PT_THREAD_RESUMED 0x80 /* thread has been resumed */ 1.179 +#define PT_THREAD_SETGCABLE 0x100 /* set the GCAble flag */ 1.180 + 1.181 +#if defined(DEBUG) 1.182 + 1.183 +typedef struct PTDebug 1.184 +{ 1.185 + PRTime timeStarted; 1.186 + PRUintn locks_created, locks_destroyed; 1.187 + PRUintn locks_acquired, locks_released; 1.188 + PRUintn cvars_created, cvars_destroyed; 1.189 + PRUintn cvars_notified, delayed_cv_deletes; 1.190 +} PTDebug; 1.191 + 1.192 +#endif /* defined(DEBUG) */ 1.193 + 1.194 +NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg); 1.195 + 1.196 +/* 1.197 + * On Linux and its derivatives POSIX priority scheduling works only for 1.198 + * real-time threads. On those platforms we set thread's nice values 1.199 + * instead which requires us to track kernel thread IDs for each POSIX 1.200 + * thread we create. 1.201 + */ 1.202 +#if defined(LINUX) && defined(HAVE_SETPRIORITY) && \ 1.203 + ((defined(HAVE_SYSCALL) && defined(SYS_gettid)) || defined(HAVE_GETTID)) 1.204 +#define _PR_NICE_PRIORITY_SCHEDULING 1.205 +#endif 1.206 + 1.207 +#else /* defined(_PR_PTHREADS) */ 1.208 + 1.209 +NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg); 1.210 + 1.211 +/* 1.212 +** This section is contains those parts needed to implement NSPR on 1.213 +** platforms in general. One would assume that the pthreads implementation 1.214 +** included lots of the same types, at least conceptually. 1.215 +*/ 1.216 + 1.217 +/* 1.218 + * Local threads only. No multiple CPU support and hence all the 1.219 + * following routines are no-op. 1.220 + */ 1.221 +#ifdef _PR_LOCAL_THREADS_ONLY 1.222 + 1.223 +#define _PR_MD_SUSPEND_THREAD(thread) 1.224 +#define _PR_MD_RESUME_THREAD(thread) 1.225 +#define _PR_MD_SUSPEND_CPU(cpu) 1.226 +#define _PR_MD_RESUME_CPU(cpu) 1.227 +#define _PR_MD_BEGIN_SUSPEND_ALL() 1.228 +#define _PR_MD_END_SUSPEND_ALL() 1.229 +#define _PR_MD_BEGIN_RESUME_ALL() 1.230 +#define _PR_MD_END_RESUME_ALL() 1.231 +#define _PR_MD_INIT_ATTACHED_THREAD(thread) PR_FAILURE 1.232 + 1.233 +#endif 1.234 + 1.235 +typedef struct _PRCPUQueue _PRCPUQueue; 1.236 +typedef struct _PRCPU _PRCPU; 1.237 +typedef struct _MDCPU _MDCPU; 1.238 + 1.239 +struct _PRCPUQueue { 1.240 + _MDLock runQLock; /* lock for the run + wait queues */ 1.241 + _MDLock sleepQLock; /* lock for the run + wait queues */ 1.242 + _MDLock miscQLock; /* lock for the run + wait queues */ 1.243 + 1.244 + PRCList runQ[PR_PRIORITY_LAST + 1]; /* run queue for this CPU */ 1.245 + PRUint32 runQReadyMask; 1.246 + PRCList sleepQ; 1.247 + PRIntervalTime sleepQmax; 1.248 + PRCList pauseQ; 1.249 + PRCList suspendQ; 1.250 + PRCList waitingToJoinQ; 1.251 + 1.252 + PRUintn numCPUs; /* number of CPUs using this Q */ 1.253 +}; 1.254 + 1.255 +struct _PRCPU { 1.256 + PRCList links; /* link list of CPUs */ 1.257 + PRUint32 id; /* id for this CPU */ 1.258 + 1.259 + union { 1.260 + PRInt32 bits; 1.261 + PRUint8 missed[4]; 1.262 + } u; 1.263 + PRIntn where; /* index into u.missed */ 1.264 + PRPackedBool paused; /* cpu is paused */ 1.265 + PRPackedBool exit; /* cpu should exit */ 1.266 + 1.267 + PRThread *thread; /* native thread for this CPUThread */ 1.268 + PRThread *idle_thread; /* user-level idle thread for this CPUThread */ 1.269 + 1.270 + PRIntervalTime last_clock; /* the last time we went into 1.271 + * _PR_ClockInterrupt() on this CPU 1.272 + */ 1.273 + 1.274 + _PRCPUQueue *queue; 1.275 + 1.276 + _MDCPU md; 1.277 +}; 1.278 + 1.279 +typedef struct _PRInterruptTable { 1.280 + const char *name; 1.281 + PRUintn missed_bit; 1.282 + void (*handler)(void); 1.283 +} _PRInterruptTable; 1.284 + 1.285 +#define _PR_CPU_PTR(_qp) \ 1.286 + ((_PRCPU*) ((char*) (_qp) - offsetof(_PRCPU,links))) 1.287 + 1.288 +#if !defined(IRIX) && !defined(WIN32) && !defined(XP_OS2) \ 1.289 + && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)) 1.290 +#define _MD_GET_ATTACHED_THREAD() (_PR_MD_CURRENT_THREAD()) 1.291 +#endif 1.292 + 1.293 +#ifdef _PR_LOCAL_THREADS_ONLY 1.294 + 1.295 +NSPR_API(struct _PRCPU *) _pr_currentCPU; 1.296 +NSPR_API(PRThread *) _pr_currentThread; 1.297 +NSPR_API(PRThread *) _pr_lastThread; 1.298 +NSPR_API(PRInt32) _pr_intsOff; 1.299 + 1.300 +#define _MD_CURRENT_CPU() (_pr_currentCPU) 1.301 +#define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = (_cpu)) 1.302 +#define _MD_CURRENT_THREAD() (_pr_currentThread) 1.303 +#define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread)) 1.304 +#define _MD_LAST_THREAD() (_pr_lastThread) 1.305 +#define _MD_SET_LAST_THREAD(t) (_pr_lastThread = t) 1.306 + 1.307 +#define _MD_GET_INTSOFF() (_pr_intsOff) 1.308 +#define _MD_SET_INTSOFF(_val) (_pr_intsOff = _val) 1.309 + 1.310 + 1.311 +/* The unbalanced curly braces in these two macros are intentional */ 1.312 +#define _PR_LOCK_HEAP() { PRIntn _is; if (_pr_currentCPU) _PR_INTSOFF(_is); 1.313 +#define _PR_UNLOCK_HEAP() if (_pr_currentCPU) _PR_INTSON(_is); } 1.314 + 1.315 +#endif /* _PR_LOCAL_THREADS_ONLY */ 1.316 + 1.317 +extern PRInt32 _native_threads_only; 1.318 + 1.319 +#if defined(_PR_GLOBAL_THREADS_ONLY) 1.320 + 1.321 +#define _MD_GET_INTSOFF() 0 1.322 +#define _MD_SET_INTSOFF(_val) 1.323 +#define _PR_INTSOFF(_is) 1.324 +#define _PR_FAST_INTSON(_is) 1.325 +#define _PR_INTSON(_is) 1.326 +#define _PR_THREAD_LOCK(_thread) 1.327 +#define _PR_THREAD_UNLOCK(_thread) 1.328 +#define _PR_RUNQ_LOCK(cpu) 1.329 +#define _PR_RUNQ_UNLOCK(cpu) 1.330 +#define _PR_SLEEPQ_LOCK(thread) 1.331 +#define _PR_SLEEPQ_UNLOCK(thread) 1.332 +#define _PR_MISCQ_LOCK(thread) 1.333 +#define _PR_MISCQ_UNLOCK(thread) 1.334 +#define _PR_CPU_LIST_LOCK() 1.335 +#define _PR_CPU_LIST_UNLOCK() 1.336 + 1.337 +#define _PR_ADD_RUNQ(_thread, _cpu, _pri) 1.338 +#define _PR_DEL_RUNQ(_thread) 1.339 +#define _PR_ADD_SLEEPQ(_thread, _timeout) 1.340 +#define _PR_DEL_SLEEPQ(_thread, _propogate) 1.341 +#define _PR_ADD_JOINQ(_thread, _cpu) 1.342 +#define _PR_DEL_JOINQ(_thread) 1.343 +#define _PR_ADD_SUSPENDQ(_thread, _cpu) 1.344 +#define _PR_DEL_SUSPENDQ(_thread) 1.345 + 1.346 +#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) 1.347 + 1.348 +#define _PR_IS_NATIVE_THREAD(thread) 1 1.349 +#define _PR_IS_NATIVE_THREAD_SUPPORTED() 1 1.350 + 1.351 +#else 1.352 + 1.353 +#define _PR_INTSOFF(_is) \ 1.354 + PR_BEGIN_MACRO \ 1.355 + (_is) = _PR_MD_GET_INTSOFF(); \ 1.356 + _PR_MD_SET_INTSOFF(1); \ 1.357 + PR_END_MACRO 1.358 + 1.359 +#define _PR_FAST_INTSON(_is) \ 1.360 + PR_BEGIN_MACRO \ 1.361 + _PR_MD_SET_INTSOFF(_is); \ 1.362 + PR_END_MACRO 1.363 + 1.364 +#define _PR_INTSON(_is) \ 1.365 + PR_BEGIN_MACRO \ 1.366 + if ((_is == 0) && (_PR_MD_CURRENT_CPU())->u.bits) \ 1.367 + _PR_IntsOn((_PR_MD_CURRENT_CPU())); \ 1.368 + _PR_MD_SET_INTSOFF(_is); \ 1.369 + PR_END_MACRO 1.370 + 1.371 +#ifdef _PR_LOCAL_THREADS_ONLY 1.372 + 1.373 +#define _PR_IS_NATIVE_THREAD(thread) 0 1.374 +#define _PR_THREAD_LOCK(_thread) 1.375 +#define _PR_THREAD_UNLOCK(_thread) 1.376 +#define _PR_RUNQ_LOCK(cpu) 1.377 +#define _PR_RUNQ_UNLOCK(cpu) 1.378 +#define _PR_SLEEPQ_LOCK(thread) 1.379 +#define _PR_SLEEPQ_UNLOCK(thread) 1.380 +#define _PR_MISCQ_LOCK(thread) 1.381 +#define _PR_MISCQ_UNLOCK(thread) 1.382 +#define _PR_CPU_LIST_LOCK() 1.383 +#define _PR_CPU_LIST_UNLOCK() 1.384 + 1.385 +#define _PR_ADD_RUNQ(_thread, _cpu, _pri) \ 1.386 + PR_BEGIN_MACRO \ 1.387 + PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \ 1.388 + _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \ 1.389 + PR_END_MACRO 1.390 + 1.391 +#define _PR_DEL_RUNQ(_thread) \ 1.392 + PR_BEGIN_MACRO \ 1.393 + _PRCPU *_cpu = _thread->cpu; \ 1.394 + PRInt32 _pri = _thread->priority; \ 1.395 + PR_REMOVE_LINK(&(_thread)->links); \ 1.396 + if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \ 1.397 + _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \ 1.398 + PR_END_MACRO 1.399 + 1.400 +#define _PR_ADD_SLEEPQ(_thread, _timeout) \ 1.401 + _PR_AddSleepQ(_thread, _timeout); 1.402 + 1.403 +#define _PR_DEL_SLEEPQ(_thread, _propogate) \ 1.404 + _PR_DelSleepQ(_thread, _propogate); 1.405 + 1.406 +#define _PR_ADD_JOINQ(_thread, _cpu) \ 1.407 + PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu)); 1.408 + 1.409 +#define _PR_DEL_JOINQ(_thread) \ 1.410 + PR_REMOVE_LINK(&(_thread)->links); 1.411 + 1.412 +#define _PR_ADD_SUSPENDQ(_thread, _cpu) \ 1.413 + PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu)); 1.414 + 1.415 +#define _PR_DEL_SUSPENDQ(_thread) \ 1.416 + PR_REMOVE_LINK(&(_thread)->links); 1.417 + 1.418 +#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) 1.419 + 1.420 +#define _PR_IS_NATIVE_THREAD_SUPPORTED() 0 1.421 + 1.422 +#else /* _PR_LOCAL_THREADS_ONLY */ 1.423 + 1.424 +/* These are for the "combined" thread model */ 1.425 + 1.426 +#define _PR_THREAD_LOCK(_thread) \ 1.427 + _PR_MD_LOCK(&(_thread)->threadLock); 1.428 + 1.429 +#define _PR_THREAD_UNLOCK(_thread) \ 1.430 + _PR_MD_UNLOCK(&(_thread)->threadLock); 1.431 + 1.432 +#define _PR_RUNQ_LOCK(_cpu) \ 1.433 + PR_BEGIN_MACRO \ 1.434 + _PR_MD_LOCK(&(_cpu)->queue->runQLock );\ 1.435 + PR_END_MACRO 1.436 + 1.437 +#define _PR_RUNQ_UNLOCK(_cpu) \ 1.438 + PR_BEGIN_MACRO \ 1.439 + _PR_MD_UNLOCK(&(_cpu)->queue->runQLock );\ 1.440 + PR_END_MACRO 1.441 + 1.442 +#define _PR_SLEEPQ_LOCK(_cpu) \ 1.443 + _PR_MD_LOCK(&(_cpu)->queue->sleepQLock ); 1.444 + 1.445 +#define _PR_SLEEPQ_UNLOCK(_cpu) \ 1.446 + _PR_MD_UNLOCK(&(_cpu)->queue->sleepQLock ); 1.447 + 1.448 +#define _PR_MISCQ_LOCK(_cpu) \ 1.449 + _PR_MD_LOCK(&(_cpu)->queue->miscQLock ); 1.450 + 1.451 +#define _PR_MISCQ_UNLOCK(_cpu) \ 1.452 + _PR_MD_UNLOCK(&(_cpu)->queue->miscQLock ); 1.453 + 1.454 +#define _PR_CPU_LIST_LOCK() _PR_MD_LOCK(&_pr_cpuLock) 1.455 +#define _PR_CPU_LIST_UNLOCK() _PR_MD_UNLOCK(&_pr_cpuLock) 1.456 + 1.457 +#define QUEUE_RUN 0x1 1.458 +#define QUEUE_SLEEP 0x2 1.459 +#define QUEUE_JOIN 0x4 1.460 +#define QUEUE_SUSPEND 0x8 1.461 +#define QUEUE_LOCK 0x10 1.462 + 1.463 +#define _PR_ADD_RUNQ(_thread, _cpu, _pri) \ 1.464 + PR_BEGIN_MACRO \ 1.465 + PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \ 1.466 + _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \ 1.467 + PR_ASSERT((_thread)->queueCount == 0); \ 1.468 + (_thread)->queueCount = QUEUE_RUN; \ 1.469 + PR_END_MACRO 1.470 + 1.471 +#define _PR_DEL_RUNQ(_thread) \ 1.472 + PR_BEGIN_MACRO \ 1.473 + _PRCPU *_cpu = _thread->cpu; \ 1.474 + PRInt32 _pri = _thread->priority; \ 1.475 + PR_REMOVE_LINK(&(_thread)->links); \ 1.476 + if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \ 1.477 + _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \ 1.478 + PR_ASSERT((_thread)->queueCount == QUEUE_RUN);\ 1.479 + (_thread)->queueCount = 0; \ 1.480 + PR_END_MACRO 1.481 + 1.482 +#define _PR_ADD_SLEEPQ(_thread, _timeout) \ 1.483 + PR_ASSERT((_thread)->queueCount == 0); \ 1.484 + (_thread)->queueCount = QUEUE_SLEEP; \ 1.485 + _PR_AddSleepQ(_thread, _timeout); 1.486 + 1.487 +#define _PR_DEL_SLEEPQ(_thread, _propogate) \ 1.488 + PR_ASSERT((_thread)->queueCount == QUEUE_SLEEP);\ 1.489 + (_thread)->queueCount = 0; \ 1.490 + _PR_DelSleepQ(_thread, _propogate); 1.491 + 1.492 +#define _PR_ADD_JOINQ(_thread, _cpu) \ 1.493 + PR_ASSERT((_thread)->queueCount == 0); \ 1.494 + (_thread)->queueCount = QUEUE_JOIN; \ 1.495 + PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu)); 1.496 + 1.497 +#define _PR_DEL_JOINQ(_thread) \ 1.498 + PR_ASSERT((_thread)->queueCount == QUEUE_JOIN);\ 1.499 + (_thread)->queueCount = 0; \ 1.500 + PR_REMOVE_LINK(&(_thread)->links); 1.501 + 1.502 +#define _PR_ADD_SUSPENDQ(_thread, _cpu) \ 1.503 + PR_ASSERT((_thread)->queueCount == 0); \ 1.504 + (_thread)->queueCount = QUEUE_SUSPEND; \ 1.505 + PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu)); 1.506 + 1.507 +#define _PR_DEL_SUSPENDQ(_thread) \ 1.508 + PR_ASSERT((_thread)->queueCount == QUEUE_SUSPEND);\ 1.509 + (_thread)->queueCount = 0; \ 1.510 + PR_REMOVE_LINK(&(_thread)->links); 1.511 + 1.512 +#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) \ 1.513 + (_thread)->cpu = (_newCPU); 1.514 + 1.515 +#define _PR_IS_NATIVE_THREAD(thread) (thread->flags & _PR_GLOBAL_SCOPE) 1.516 +#define _PR_IS_NATIVE_THREAD_SUPPORTED() 1 1.517 + 1.518 +#endif /* _PR_LOCAL_THREADS_ONLY */ 1.519 + 1.520 +#endif /* _PR_GLOBAL_THREADS_ONLY */ 1.521 + 1.522 +#define _PR_SET_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 1 1.523 +#define _PR_CLEAR_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 0 1.524 + 1.525 +extern _PRInterruptTable _pr_interruptTable[]; 1.526 + 1.527 +/* Bits for _pr_interruptState.u.missed[0,1] */ 1.528 +#define _PR_MISSED_CLOCK 0x1 1.529 +#define _PR_MISSED_IO 0x2 1.530 +#define _PR_MISSED_CHILD 0x4 1.531 + 1.532 +extern void _PR_IntsOn(_PRCPU *cpu); 1.533 + 1.534 +NSPR_API(void) _PR_WakeupCPU(void); 1.535 +NSPR_API(void) _PR_PauseCPU(void); 1.536 + 1.537 +/************************************************************************/ 1.538 + 1.539 +#define _PR_LOCK_LOCK(_lock) \ 1.540 + _PR_MD_LOCK(&(_lock)->ilock); 1.541 +#define _PR_LOCK_UNLOCK(_lock) \ 1.542 + _PR_MD_UNLOCK(&(_lock)->ilock); 1.543 + 1.544 +extern void _PR_UnblockLockWaiter(PRLock *lock); 1.545 +extern PRStatus _PR_InitLock(PRLock *lock); 1.546 +extern void _PR_FreeLock(PRLock *lock); 1.547 + 1.548 +#define _PR_LOCK_PTR(_qp) \ 1.549 + ((PRLock*) ((char*) (_qp) - offsetof(PRLock,links))) 1.550 + 1.551 +/************************************************************************/ 1.552 + 1.553 +#define _PR_CVAR_LOCK(_cvar) \ 1.554 + _PR_MD_LOCK(&(_cvar)->ilock); 1.555 +#define _PR_CVAR_UNLOCK(_cvar) \ 1.556 + _PR_MD_UNLOCK(&(_cvar)->ilock); 1.557 + 1.558 +extern PRStatus _PR_InitCondVar(PRCondVar *cvar, PRLock *lock); 1.559 +extern void _PR_FreeCondVar(PRCondVar *cvar); 1.560 +extern PRStatus _PR_WaitCondVar( 1.561 + PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout); 1.562 +extern void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me); 1.563 +extern PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen); 1.564 + 1.565 +NSPR_API(void) _PR_Notify(PRMonitor *mon, PRBool all, PRBool sticky); 1.566 + 1.567 +/* PRThread.flags */ 1.568 +#define _PR_SYSTEM 0x01 1.569 +#define _PR_INTERRUPT 0x02 1.570 +#define _PR_ATTACHED 0x04 /* created via PR_AttachThread */ 1.571 +#define _PR_PRIMORDIAL 0x08 /* the thread that called PR_Init */ 1.572 +#define _PR_ON_SLEEPQ 0x10 /* thread is on the sleepQ */ 1.573 +#define _PR_ON_PAUSEQ 0x20 /* thread is on the pauseQ */ 1.574 +#define _PR_SUSPENDING 0x40 /* thread wants to suspend */ 1.575 +#define _PR_GLOBAL_SCOPE 0x80 /* thread is global scope */ 1.576 +#define _PR_IDLE_THREAD 0x200 /* this is an idle thread */ 1.577 +#define _PR_GCABLE_THREAD 0x400 /* this is a collectable thread */ 1.578 +#define _PR_BOUND_THREAD 0x800 /* a bound thread */ 1.579 +#define _PR_INTERRUPT_BLOCKED 0x1000 /* interrupts blocked */ 1.580 + 1.581 +/* PRThread.state */ 1.582 +#define _PR_UNBORN 0 1.583 +#define _PR_RUNNABLE 1 1.584 +#define _PR_RUNNING 2 1.585 +#define _PR_LOCK_WAIT 3 1.586 +#define _PR_COND_WAIT 4 1.587 +#define _PR_JOIN_WAIT 5 1.588 +#define _PR_IO_WAIT 6 1.589 +#define _PR_SUSPENDED 7 1.590 +#define _PR_DEAD_STATE 8 /* for debugging */ 1.591 + 1.592 +/* PRThreadStack.flags */ 1.593 +#define _PR_STACK_VM 0x1 /* using vm instead of malloc */ 1.594 +#define _PR_STACK_MAPPED 0x2 /* vm is mapped */ 1.595 +#define _PR_STACK_PRIMORDIAL 0x4 /* stack for primordial thread */ 1.596 + 1.597 +/* 1.598 +** If the default stcksize from the client is zero, we need to pick a machine 1.599 +** dependent value. This is only for standard user threads. For custom threads, 1.600 +** 0 has a special meaning. 1.601 +** Adjust stackSize. Round up to a page boundary. 1.602 +*/ 1.603 + 1.604 +#ifndef _MD_MINIMUM_STACK_SIZE 1.605 +#define _MD_MINIMUM_STACK_SIZE 0 1.606 +#endif 1.607 + 1.608 +#if (!defined(HAVE_CUSTOM_USER_THREADS)) 1.609 +#define _PR_ADJUST_STACKSIZE(stackSize) \ 1.610 + PR_BEGIN_MACRO \ 1.611 + if (stackSize == 0) \ 1.612 + stackSize = _MD_DEFAULT_STACK_SIZE; \ 1.613 + if (stackSize < _MD_MINIMUM_STACK_SIZE) \ 1.614 + stackSize = _MD_MINIMUM_STACK_SIZE; \ 1.615 + stackSize = (stackSize + (1 << _pr_pageShift) - 1) >> _pr_pageShift; \ 1.616 + stackSize <<= _pr_pageShift; \ 1.617 + PR_END_MACRO 1.618 +#else 1.619 +#define _PR_ADJUST_STACKSIZE(stackSize) 1.620 +#endif 1.621 + 1.622 +#define _PR_IS_GCABLE_THREAD(thr) ((thr)->flags & _PR_GCABLE_THREAD) 1.623 + 1.624 +#define _PR_PENDING_INTERRUPT(thr) \ 1.625 + (!((thr)->flags & _PR_INTERRUPT_BLOCKED) && ((thr)->flags & _PR_INTERRUPT)) 1.626 +#define _PR_THREAD_BLOCK_INTERRUPT(thr) \ 1.627 + (thr->flags |= _PR_INTERRUPT_BLOCKED) 1.628 +#define _PR_THREAD_UNBLOCK_INTERRUPT(thr) \ 1.629 + (thr->flags &= ~_PR_INTERRUPT_BLOCKED) 1.630 + 1.631 +#define _PR_THREAD_PTR(_qp) \ 1.632 + ((PRThread*) ((char*) (_qp) - offsetof(PRThread,links))) 1.633 + 1.634 +#define _PR_ACTIVE_THREAD_PTR(_qp) \ 1.635 + ((PRThread*) ((char*) (_qp) - offsetof(PRThread,active))) 1.636 + 1.637 +#define _PR_THREAD_CONDQ_PTR(_qp) \ 1.638 + ((PRThread*) ((char*) (_qp) - offsetof(PRThread,waitQLinks))) 1.639 + 1.640 +#define _PR_THREAD_MD_TO_PTR(_md) \ 1.641 + ((PRThread*) ((char*) (_md) - offsetof(PRThread,md))) 1.642 + 1.643 +#define _PR_THREAD_STACK_TO_PTR(_stack) \ 1.644 + ((PRThread*) (_stack->thr)) 1.645 + 1.646 +extern PRCList _pr_active_local_threadQ; 1.647 +extern PRCList _pr_active_global_threadQ; 1.648 +extern PRCList _pr_cpuQ; 1.649 +extern _MDLock _pr_cpuLock; 1.650 +extern PRInt32 _pr_md_idle_cpus; 1.651 + 1.652 +#define _PR_ACTIVE_LOCAL_THREADQ() _pr_active_local_threadQ 1.653 +#define _PR_ACTIVE_GLOBAL_THREADQ() _pr_active_global_threadQ 1.654 +#define _PR_CPUQ() _pr_cpuQ 1.655 +#define _PR_RUNQ(_cpu) ((_cpu)->queue->runQ) 1.656 +#define _PR_RUNQREADYMASK(_cpu) ((_cpu)->queue->runQReadyMask) 1.657 +#define _PR_SLEEPQ(_cpu) ((_cpu)->queue->sleepQ) 1.658 +#define _PR_SLEEPQMAX(_cpu) ((_cpu)->queue->sleepQmax) 1.659 +#define _PR_PAUSEQ(_cpu) ((_cpu)->queue->pauseQ) 1.660 +#define _PR_SUSPENDQ(_cpu) ((_cpu)->queue->suspendQ) 1.661 +#define _PR_WAITINGTOJOINQ(_cpu) ((_cpu)->queue->waitingToJoinQ) 1.662 + 1.663 +extern PRUint32 _pr_recycleThreads; /* Flag for behavior on thread cleanup */ 1.664 +extern PRLock *_pr_deadQLock; 1.665 +extern PRUint32 _pr_numNativeDead; 1.666 +extern PRUint32 _pr_numUserDead; 1.667 +extern PRCList _pr_deadNativeQ; 1.668 +extern PRCList _pr_deadUserQ; 1.669 +#define _PR_DEADNATIVEQ _pr_deadNativeQ 1.670 +#define _PR_DEADUSERQ _pr_deadUserQ 1.671 +#define _PR_DEADQ_LOCK PR_Lock(_pr_deadQLock); 1.672 +#define _PR_DEADQ_UNLOCK PR_Unlock(_pr_deadQLock); 1.673 +#define _PR_INC_DEADNATIVE (_pr_numNativeDead++) 1.674 +#define _PR_DEC_DEADNATIVE (_pr_numNativeDead--) 1.675 +#define _PR_NUM_DEADNATIVE (_pr_numNativeDead) 1.676 +#define _PR_INC_DEADUSER (_pr_numUserDead++) 1.677 +#define _PR_DEC_DEADUSER (_pr_numUserDead--) 1.678 +#define _PR_NUM_DEADUSER (_pr_numUserDead) 1.679 + 1.680 +extern PRUint32 _pr_utid; 1.681 + 1.682 +extern struct _PRCPU *_pr_primordialCPU; 1.683 + 1.684 +extern PRLock *_pr_activeLock; /* lock for userActive and systemActive */ 1.685 +extern PRInt32 _pr_userActive; /* number of active user threads */ 1.686 +extern PRInt32 _pr_systemActive; /* number of active system threads */ 1.687 +extern PRInt32 _pr_primordialExitCount; /* number of user threads left 1.688 + * before the primordial thread 1.689 + * can exit. */ 1.690 +extern PRCondVar *_pr_primordialExitCVar; /* the condition variable for 1.691 + * notifying the primordial thread 1.692 + * when all other user threads 1.693 + * have terminated. */ 1.694 + 1.695 +extern PRUintn _pr_maxPTDs; 1.696 + 1.697 +extern PRLock *_pr_terminationCVLock; 1.698 + 1.699 +/************************************************************************* 1.700 +* Internal routines either called by PR itself or from machine-dependent * 1.701 +* code. * 1.702 +*************************************************************************/ 1.703 + 1.704 +extern void _PR_ClockInterrupt(void); 1.705 + 1.706 +extern void _PR_Schedule(void); 1.707 +extern void _PR_SetThreadPriority( 1.708 + PRThread* thread, PRThreadPriority priority); 1.709 + 1.710 +/*********************************************************************** 1.711 +** FUNCTION: _PR_NewSegment() 1.712 +** DESCRIPTION: 1.713 +** Allocate a memory segment. The "size" value is rounded up to the 1.714 +** native system page size and a page aligned portion of memory is 1.715 +** returned. This memory is not part of the malloc heap. If "vaddr" is 1.716 +** not NULL then PR tries to allocate the segment at the desired virtual 1.717 +** address. 1.718 +** INPUTS: size: size of the desired memory segment 1.719 +** vaddr: address at which the newly aquired segment is to be 1.720 +** mapped into memory. 1.721 +** OUTPUTS: a memory segment is allocated, a PRSegment is allocated 1.722 +** RETURN: pointer to PRSegment 1.723 +***********************************************************************/ 1.724 +extern PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr); 1.725 + 1.726 +/*********************************************************************** 1.727 +** FUNCTION: _PR_DestroySegment() 1.728 +** DESCRIPTION: 1.729 +** The memory segment and the PRSegment are freed 1.730 +** INPUTS: seg: pointer to PRSegment to be freed 1.731 +** OUTPUTS: the the PRSegment and its associated memory segment are freed 1.732 +** RETURN: void 1.733 +***********************************************************************/ 1.734 +extern void _PR_DestroySegment(PRSegment *seg); 1.735 + 1.736 +extern PRThreadStack * _PR_NewStack(PRUint32 stackSize); 1.737 +extern void _PR_FreeStack(PRThreadStack *stack); 1.738 +extern PRBool _PR_NotifyThread (PRThread *thread, PRThread *me); 1.739 +extern void _PR_NotifyLockedThread (PRThread *thread); 1.740 + 1.741 +NSPR_API(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout); 1.742 +NSPR_API(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time); 1.743 + 1.744 +extern void _PR_AddThreadToRunQ(PRThread *me, PRThread *thread); 1.745 + 1.746 +NSPR_API(PRThread*) _PR_CreateThread(PRThreadType type, 1.747 + void (*start)(void *arg), 1.748 + void *arg, 1.749 + PRThreadPriority priority, 1.750 + PRThreadScope scope, 1.751 + PRThreadState state, 1.752 + PRUint32 stackSize, 1.753 + PRUint32 flags); 1.754 + 1.755 +extern void _PR_NativeDestroyThread(PRThread *thread); 1.756 +extern void _PR_UserDestroyThread(PRThread *thread); 1.757 + 1.758 +extern PRThread* _PRI_AttachThread( 1.759 + PRThreadType type, PRThreadPriority priority, 1.760 + PRThreadStack *stack, PRUint32 flags); 1.761 + 1.762 +extern void _PRI_DetachThread(void); 1.763 + 1.764 + 1.765 +#define _PR_IO_PENDING(_thread) ((_thread)->io_pending) 1.766 + 1.767 +NSPR_API(void) _PR_MD_INIT_CPUS(); 1.768 +#define _PR_MD_INIT_CPUS _MD_INIT_CPUS 1.769 + 1.770 +NSPR_API(void) _PR_MD_WAKEUP_CPUS(); 1.771 +#define _PR_MD_WAKEUP_CPUS _MD_WAKEUP_CPUS 1.772 + 1.773 +/* Interrupts related */ 1.774 + 1.775 +NSPR_API(void) _PR_MD_START_INTERRUPTS(void); 1.776 +#define _PR_MD_START_INTERRUPTS _MD_START_INTERRUPTS 1.777 + 1.778 +NSPR_API(void) _PR_MD_STOP_INTERRUPTS(void); 1.779 +#define _PR_MD_STOP_INTERRUPTS _MD_STOP_INTERRUPTS 1.780 + 1.781 +NSPR_API(void) _PR_MD_ENABLE_CLOCK_INTERRUPTS(void); 1.782 +#define _PR_MD_ENABLE_CLOCK_INTERRUPTS _MD_ENABLE_CLOCK_INTERRUPTS 1.783 + 1.784 +NSPR_API(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void); 1.785 +#define _PR_MD_DISABLE_CLOCK_INTERRUPTS _MD_DISABLE_CLOCK_INTERRUPTS 1.786 + 1.787 +NSPR_API(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void); 1.788 +#define _PR_MD_BLOCK_CLOCK_INTERRUPTS _MD_BLOCK_CLOCK_INTERRUPTS 1.789 + 1.790 +NSPR_API(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void); 1.791 +#define _PR_MD_UNBLOCK_CLOCK_INTERRUPTS _MD_UNBLOCK_CLOCK_INTERRUPTS 1.792 + 1.793 +/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and 1.794 + * awaken a thread which is waiting on a lock or cvar. 1.795 + */ 1.796 +extern PRStatus _PR_MD_WAIT(PRThread *, PRIntervalTime timeout); 1.797 +#define _PR_MD_WAIT _MD_WAIT 1.798 + 1.799 +extern PRStatus _PR_MD_WAKEUP_WAITER(PRThread *); 1.800 +#define _PR_MD_WAKEUP_WAITER _MD_WAKEUP_WAITER 1.801 + 1.802 +#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ 1.803 +NSPR_API(void) _PR_MD_CLOCK_INTERRUPT(void); 1.804 +#define _PR_MD_CLOCK_INTERRUPT _MD_CLOCK_INTERRUPT 1.805 +#endif 1.806 + 1.807 +/* Stack debugging */ 1.808 +NSPR_API(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone); 1.809 +#define _PR_MD_INIT_STACK _MD_INIT_STACK 1.810 + 1.811 +NSPR_API(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts); 1.812 +#define _PR_MD_CLEAR_STACK _MD_CLEAR_STACK 1.813 + 1.814 +/* CPU related */ 1.815 +NSPR_API(PRInt32) _PR_MD_GET_INTSOFF(void); 1.816 +#define _PR_MD_GET_INTSOFF _MD_GET_INTSOFF 1.817 + 1.818 +NSPR_API(void) _PR_MD_SET_INTSOFF(PRInt32 _val); 1.819 +#define _PR_MD_SET_INTSOFF _MD_SET_INTSOFF 1.820 + 1.821 +NSPR_API(_PRCPU*) _PR_MD_CURRENT_CPU(void); 1.822 +#define _PR_MD_CURRENT_CPU _MD_CURRENT_CPU 1.823 + 1.824 +NSPR_API(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu); 1.825 +#define _PR_MD_SET_CURRENT_CPU _MD_SET_CURRENT_CPU 1.826 + 1.827 +NSPR_API(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu); 1.828 +#define _PR_MD_INIT_RUNNING_CPU _MD_INIT_RUNNING_CPU 1.829 + 1.830 +/* 1.831 + * Returns the number of threads awoken or 0 if a timeout occurred; 1.832 + */ 1.833 +extern PRInt32 _PR_MD_PAUSE_CPU(PRIntervalTime timeout); 1.834 +#define _PR_MD_PAUSE_CPU _MD_PAUSE_CPU 1.835 + 1.836 +extern void _PR_MD_CLEANUP_BEFORE_EXIT(void); 1.837 +#define _PR_MD_CLEANUP_BEFORE_EXIT _MD_CLEANUP_BEFORE_EXIT 1.838 + 1.839 +extern void _PR_MD_EXIT(PRIntn status); 1.840 +#define _PR_MD_EXIT _MD_EXIT 1.841 + 1.842 +/* Locks related */ 1.843 + 1.844 +NSPR_API(void) _PR_MD_INIT_LOCKS(void); 1.845 +#define _PR_MD_INIT_LOCKS _MD_INIT_LOCKS 1.846 + 1.847 +NSPR_API(PRStatus) _PR_MD_NEW_LOCK(_MDLock *md); 1.848 +#define _PR_MD_NEW_LOCK _MD_NEW_LOCK 1.849 + 1.850 +NSPR_API(void) _PR_MD_FREE_LOCK(_MDLock *md); 1.851 +#define _PR_MD_FREE_LOCK _MD_FREE_LOCK 1.852 + 1.853 +NSPR_API(void) _PR_MD_LOCK(_MDLock *md); 1.854 +#define _PR_MD_LOCK _MD_LOCK 1.855 + 1.856 +/* Return 0 on success, a nonzero value on failure. */ 1.857 +NSPR_API(PRIntn) _PR_MD_TEST_AND_LOCK(_MDLock *md); 1.858 +#define _PR_MD_TEST_AND_LOCK _MD_TEST_AND_LOCK 1.859 + 1.860 +NSPR_API(void) _PR_MD_UNLOCK(_MDLock *md); 1.861 +#define _PR_MD_UNLOCK _MD_UNLOCK 1.862 + 1.863 +NSPR_API(void) _PR_MD_IOQ_LOCK(void); 1.864 +#define _PR_MD_IOQ_LOCK _MD_IOQ_LOCK 1.865 + 1.866 +NSPR_API(void) _PR_MD_IOQ_UNLOCK(void); 1.867 +#define _PR_MD_IOQ_UNLOCK _MD_IOQ_UNLOCK 1.868 + 1.869 +#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ 1.870 +/* Semaphore related -- only for native threads */ 1.871 +#ifdef HAVE_CVAR_BUILT_ON_SEM 1.872 +NSPR_API(void) _PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value); 1.873 +#define _PR_MD_NEW_SEM _MD_NEW_SEM 1.874 + 1.875 +NSPR_API(void) _PR_MD_DESTROY_SEM(_MDSemaphore *md); 1.876 +#define _PR_MD_DESTROY_SEM _MD_DESTROY_SEM 1.877 + 1.878 +NSPR_API(PRStatus) _PR_MD_TIMED_WAIT_SEM( 1.879 + _MDSemaphore *md, PRIntervalTime timeout); 1.880 +#define _PR_MD_TIMED_WAIT_SEM _MD_TIMED_WAIT_SEM 1.881 + 1.882 +NSPR_API(PRStatus) _PR_MD_WAIT_SEM(_MDSemaphore *md); 1.883 +#define _PR_MD_WAIT_SEM _MD_WAIT_SEM 1.884 + 1.885 +NSPR_API(void) _PR_MD_POST_SEM(_MDSemaphore *md); 1.886 +#define _PR_MD_POST_SEM _MD_POST_SEM 1.887 +#endif /* HAVE_CVAR_BUILT_ON_SEM */ 1.888 + 1.889 +#endif 1.890 + 1.891 +/* Condition Variables related -- only for native threads */ 1.892 + 1.893 +#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ 1.894 +NSPR_API(PRInt32) _PR_MD_NEW_CV(_MDCVar *md); 1.895 +#define _PR_MD_NEW_CV _MD_NEW_CV 1.896 + 1.897 +NSPR_API(void) _PR_MD_FREE_CV(_MDCVar *md); 1.898 +#define _PR_MD_FREE_CV _MD_FREE_CV 1.899 + 1.900 +NSPR_API(void) _PR_MD_WAIT_CV( 1.901 + _MDCVar *mdCVar,_MDLock *mdLock,PRIntervalTime timeout); 1.902 +#define _PR_MD_WAIT_CV _MD_WAIT_CV 1.903 + 1.904 +NSPR_API(void) _PR_MD_NOTIFY_CV(_MDCVar *md, _MDLock *lock); 1.905 +#define _PR_MD_NOTIFY_CV _MD_NOTIFY_CV 1.906 + 1.907 +NSPR_API(void) _PR_MD_NOTIFYALL_CV(_MDCVar *md, _MDLock *lock); 1.908 +#define _PR_MD_NOTIFYALL_CV _MD_NOTIFYALL_CV 1.909 +#endif /* _PR_LOCAL_THREADS_ONLY */ 1.910 + 1.911 +/* Threads related */ 1.912 +NSPR_API(PRThread*) _PR_MD_CURRENT_THREAD(void); 1.913 +#define _PR_MD_CURRENT_THREAD _MD_CURRENT_THREAD 1.914 + 1.915 +NSPR_API(PRThread*) _PR_MD_GET_ATTACHED_THREAD(void); 1.916 +#define _PR_MD_GET_ATTACHED_THREAD _MD_GET_ATTACHED_THREAD 1.917 + 1.918 +NSPR_API(PRThread*) _PR_MD_LAST_THREAD(void); 1.919 +#define _PR_MD_LAST_THREAD _MD_LAST_THREAD 1.920 + 1.921 +NSPR_API(void) _PR_MD_SET_CURRENT_THREAD(PRThread *thread); 1.922 +#define _PR_MD_SET_CURRENT_THREAD _MD_SET_CURRENT_THREAD 1.923 + 1.924 +NSPR_API(void) _PR_MD_SET_LAST_THREAD(PRThread *thread); 1.925 +#define _PR_MD_SET_LAST_THREAD _MD_SET_LAST_THREAD 1.926 + 1.927 +extern PRStatus _PR_MD_INIT_THREAD(PRThread *thread); 1.928 +#define _PR_MD_INIT_THREAD _MD_INIT_THREAD 1.929 + 1.930 +extern void _PR_MD_EXIT_THREAD(PRThread *thread); 1.931 +#define _PR_MD_EXIT_THREAD _MD_EXIT_THREAD 1.932 + 1.933 +#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ 1.934 + 1.935 +NSPR_API(PRStatus) _PR_MD_INIT_ATTACHED_THREAD(PRThread *thread); 1.936 +#define _PR_MD_INIT_ATTACHED_THREAD _MD_INIT_ATTACHED_THREAD 1.937 + 1.938 +extern void _PR_MD_SUSPEND_THREAD(PRThread *thread); 1.939 +#define _PR_MD_SUSPEND_THREAD _MD_SUSPEND_THREAD 1.940 + 1.941 +extern void _PR_MD_RESUME_THREAD(PRThread *thread); 1.942 +#define _PR_MD_RESUME_THREAD _MD_RESUME_THREAD 1.943 + 1.944 +extern void _PR_MD_SUSPEND_CPU(_PRCPU *cpu); 1.945 +#define _PR_MD_SUSPEND_CPU _MD_SUSPEND_CPU 1.946 + 1.947 +extern void _PR_MD_RESUME_CPU(_PRCPU *cpu); 1.948 +#define _PR_MD_RESUME_CPU _MD_RESUME_CPU 1.949 + 1.950 +extern void _PR_MD_BEGIN_SUSPEND_ALL(void); 1.951 +#define _PR_MD_BEGIN_SUSPEND_ALL _MD_BEGIN_SUSPEND_ALL 1.952 + 1.953 +extern void _PR_MD_END_SUSPEND_ALL(void); 1.954 +#define _PR_MD_END_SUSPEND_ALL _MD_END_SUSPEND_ALL 1.955 + 1.956 +extern void _PR_MD_BEGIN_RESUME_ALL(void); 1.957 +#define _PR_MD_BEGIN_RESUME_ALL _MD_BEGIN_RESUME_ALL 1.958 + 1.959 +extern void _PR_MD_END_RESUME_ALL(void); 1.960 +#define _PR_MD_END_RESUME_ALL _MD_END_RESUME_ALL 1.961 + 1.962 +#if defined(IRIX) 1.963 +NSPR_API(void) _PR_IRIX_CHILD_PROCESS(void); 1.964 +#endif /* IRIX */ 1.965 + 1.966 +#endif /* !_PR_LOCAL_THREADS_ONLY */ 1.967 + 1.968 +extern void _PR_MD_CLEAN_THREAD(PRThread *thread); 1.969 +#define _PR_MD_CLEAN_THREAD _MD_CLEAN_THREAD 1.970 + 1.971 +#ifdef HAVE_CUSTOM_USER_THREADS 1.972 +extern void _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *); 1.973 +#define _PR_MD_CREATE_PRIMORDIAL_USER_THREAD _MD_CREATE_PRIMORDIAL_USER_THREAD 1.974 + 1.975 +extern PRThread* _PR_MD_CREATE_USER_THREAD( 1.976 + PRUint32 stacksize, 1.977 + void (*start)(void *), 1.978 + void *arg); 1.979 +#define _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD 1.980 +#endif 1.981 + 1.982 +extern PRStatus _PR_MD_CREATE_THREAD( 1.983 + PRThread *thread, 1.984 + void (*start) (void *), 1.985 + PRThreadPriority priority, 1.986 + PRThreadScope scope, 1.987 + PRThreadState state, 1.988 + PRUint32 stackSize); 1.989 +#define _PR_MD_CREATE_THREAD _MD_CREATE_THREAD 1.990 + 1.991 +extern void _PR_MD_JOIN_THREAD(_MDThread *md); 1.992 +#define _PR_MD_JOIN_THREAD _MD_JOIN_THREAD 1.993 + 1.994 +extern void _PR_MD_END_THREAD(void); 1.995 +#define _PR_MD_END_THREAD _MD_END_THREAD 1.996 + 1.997 +extern void _PR_MD_YIELD(void); 1.998 +#define _PR_MD_YIELD _MD_YIELD 1.999 + 1.1000 +extern void _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri); 1.1001 +#define _PR_MD_SET_PRIORITY _MD_SET_PRIORITY 1.1002 + 1.1003 +extern void _PR_MD_SET_CURRENT_THREAD_NAME(const char *name); 1.1004 +#define _PR_MD_SET_CURRENT_THREAD_NAME _MD_SET_CURRENT_THREAD_NAME 1.1005 + 1.1006 +NSPR_API(void) _PR_MD_SUSPENDALL(void); 1.1007 +#define _PR_MD_SUSPENDALL _MD_SUSPENDALL 1.1008 + 1.1009 +NSPR_API(void) _PR_MD_RESUMEALL(void); 1.1010 +#define _PR_MD_RESUMEALL _MD_RESUMEALL 1.1011 + 1.1012 +extern void _PR_MD_INIT_CONTEXT( 1.1013 + PRThread *thread, char *top, void (*start) (void), PRBool *status); 1.1014 +#define _PR_MD_INIT_CONTEXT _MD_INIT_CONTEXT 1.1015 + 1.1016 +extern void _PR_MD_SWITCH_CONTEXT(PRThread *thread); 1.1017 +#define _PR_MD_SWITCH_CONTEXT _MD_SWITCH_CONTEXT 1.1018 + 1.1019 +extern void _PR_MD_RESTORE_CONTEXT(PRThread *thread); 1.1020 +#define _PR_MD_RESTORE_CONTEXT _MD_RESTORE_CONTEXT 1.1021 + 1.1022 +/* Segment related */ 1.1023 +extern void _PR_MD_INIT_SEGS(void); 1.1024 +#define _PR_MD_INIT_SEGS _MD_INIT_SEGS 1.1025 + 1.1026 +extern PRStatus _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr); 1.1027 +#define _PR_MD_ALLOC_SEGMENT _MD_ALLOC_SEGMENT 1.1028 + 1.1029 +extern void _PR_MD_FREE_SEGMENT(PRSegment *seg); 1.1030 +#define _PR_MD_FREE_SEGMENT _MD_FREE_SEGMENT 1.1031 + 1.1032 +/* Directory enumeration related */ 1.1033 +extern PRStatus _PR_MD_OPEN_DIR(_MDDir *md,const char *name); 1.1034 +#define _PR_MD_OPEN_DIR _MD_OPEN_DIR 1.1035 + 1.1036 +extern char * _PR_MD_READ_DIR(_MDDir *md, PRIntn flags); 1.1037 +#define _PR_MD_READ_DIR _MD_READ_DIR 1.1038 + 1.1039 +extern PRInt32 _PR_MD_CLOSE_DIR(_MDDir *md); 1.1040 +#define _PR_MD_CLOSE_DIR _MD_CLOSE_DIR 1.1041 + 1.1042 +/* Named semaphores related */ 1.1043 +extern PRSem * _PR_MD_OPEN_SEMAPHORE( 1.1044 + const char *osname, PRIntn flags, PRIntn mode, PRUintn value); 1.1045 +#define _PR_MD_OPEN_SEMAPHORE _MD_OPEN_SEMAPHORE 1.1046 + 1.1047 +extern PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem); 1.1048 +#define _PR_MD_WAIT_SEMAPHORE _MD_WAIT_SEMAPHORE 1.1049 + 1.1050 +extern PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem); 1.1051 +#define _PR_MD_POST_SEMAPHORE _MD_POST_SEMAPHORE 1.1052 + 1.1053 +extern PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem); 1.1054 +#define _PR_MD_CLOSE_SEMAPHORE _MD_CLOSE_SEMAPHORE 1.1055 + 1.1056 +extern PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname); 1.1057 +#define _PR_MD_DELETE_SEMAPHORE _MD_DELETE_SEMAPHORE 1.1058 + 1.1059 +/* I/O related */ 1.1060 +extern void _PR_MD_INIT_FILEDESC(PRFileDesc *fd); 1.1061 +#define _PR_MD_INIT_FILEDESC _MD_INIT_FILEDESC 1.1062 + 1.1063 +extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd); 1.1064 +#define _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK 1.1065 + 1.1066 +/* File I/O related */ 1.1067 +extern PROsfd _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode); 1.1068 +#define _PR_MD_OPEN _MD_OPEN 1.1069 + 1.1070 +extern PROsfd _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode); 1.1071 +#define _PR_MD_OPEN_FILE _MD_OPEN_FILE 1.1072 + 1.1073 +extern PRInt32 _PR_MD_CLOSE_FILE(PROsfd osfd); 1.1074 +#define _PR_MD_CLOSE_FILE _MD_CLOSE_FILE 1.1075 + 1.1076 +extern PRInt32 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 amount); 1.1077 +#define _PR_MD_READ _MD_READ 1.1078 + 1.1079 +extern PRInt32 _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 amount); 1.1080 +#define _PR_MD_WRITE _MD_WRITE 1.1081 + 1.1082 +extern PRInt32 _PR_MD_WRITEV( 1.1083 + PRFileDesc *fd, const struct PRIOVec *iov, 1.1084 + PRInt32 iov_size, PRIntervalTime timeout); 1.1085 +#define _PR_MD_WRITEV _MD_WRITEV 1.1086 + 1.1087 +extern PRInt32 _PR_MD_FSYNC(PRFileDesc *fd); 1.1088 +#define _PR_MD_FSYNC _MD_FSYNC 1.1089 + 1.1090 +extern PRInt32 _PR_MD_DELETE(const char *name); 1.1091 +#define _PR_MD_DELETE _MD_DELETE 1.1092 + 1.1093 +extern PRInt32 _PR_MD_RENAME(const char *from, const char *to); 1.1094 +#define _PR_MD_RENAME _MD_RENAME 1.1095 + 1.1096 +extern PRInt32 _PR_MD_ACCESS(const char *name, PRAccessHow how); 1.1097 +#define _PR_MD_ACCESS _MD_ACCESS 1.1098 + 1.1099 +extern PRInt32 _PR_MD_STAT(const char *name, struct stat *buf); 1.1100 +#define _PR_MD_STAT _MD_STAT 1.1101 + 1.1102 +extern PRInt32 _PR_MD_MKDIR(const char *name, PRIntn mode); 1.1103 +#define _PR_MD_MKDIR _MD_MKDIR 1.1104 + 1.1105 +extern PRInt32 _PR_MD_MAKE_DIR(const char *name, PRIntn mode); 1.1106 +#define _PR_MD_MAKE_DIR _MD_MAKE_DIR 1.1107 + 1.1108 +extern PRInt32 _PR_MD_RMDIR(const char *name); 1.1109 +#define _PR_MD_RMDIR _MD_RMDIR 1.1110 + 1.1111 +#ifdef MOZ_UNICODE 1.1112 +/* UTF16 File I/O related */ 1.1113 +extern PRStatus _PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *md, const PRUnichar *name); 1.1114 +#define _PR_MD_OPEN_DIR_UTF16 _MD_OPEN_DIR_UTF16 1.1115 + 1.1116 +extern PROsfd _PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, PRIntn mode); 1.1117 +#define _PR_MD_OPEN_FILE_UTF16 _MD_OPEN_FILE_UTF16 1.1118 + 1.1119 +extern PRUnichar * _PR_MD_READ_DIR_UTF16(_MDDirUTF16 *md, PRIntn flags); 1.1120 +#define _PR_MD_READ_DIR_UTF16 _MD_READ_DIR_UTF16 1.1121 + 1.1122 +extern PRInt32 _PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *md); 1.1123 +#define _PR_MD_CLOSE_DIR_UTF16 _MD_CLOSE_DIR_UTF16 1.1124 + 1.1125 +extern PRInt32 _PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info); 1.1126 +#define _PR_MD_GETFILEINFO64_UTF16 _MD_GETFILEINFO64_UTF16 1.1127 +#endif /* MOZ_UNICODE */ 1.1128 + 1.1129 +/* Socket I/O related */ 1.1130 +extern void _PR_MD_INIT_IO(void); 1.1131 +#define _PR_MD_INIT_IO _MD_INIT_IO 1.1132 + 1.1133 +extern PRInt32 _PR_MD_CLOSE_SOCKET(PROsfd osfd); 1.1134 +#define _PR_MD_CLOSE_SOCKET _MD_CLOSE_SOCKET 1.1135 + 1.1136 +extern PRInt32 _PR_MD_CONNECT( 1.1137 + PRFileDesc *fd, const PRNetAddr *addr, 1.1138 + PRUint32 addrlen, PRIntervalTime timeout); 1.1139 +#define _PR_MD_CONNECT _MD_CONNECT 1.1140 + 1.1141 +extern PROsfd _PR_MD_ACCEPT( 1.1142 + PRFileDesc *fd, PRNetAddr *addr, 1.1143 + PRUint32 *addrlen, PRIntervalTime timeout); 1.1144 +#define _PR_MD_ACCEPT _MD_ACCEPT 1.1145 + 1.1146 +extern PRInt32 _PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen); 1.1147 +#define _PR_MD_BIND _MD_BIND 1.1148 + 1.1149 +extern PRInt32 _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog); 1.1150 +#define _PR_MD_LISTEN _MD_LISTEN 1.1151 + 1.1152 +extern PRInt32 _PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how); 1.1153 +#define _PR_MD_SHUTDOWN _MD_SHUTDOWN 1.1154 + 1.1155 +extern PRInt32 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, 1.1156 + PRIntn flags, PRIntervalTime timeout); 1.1157 +#define _PR_MD_RECV _MD_RECV 1.1158 + 1.1159 +extern PRInt32 _PR_MD_SEND( 1.1160 + PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, 1.1161 + PRIntervalTime timeout); 1.1162 +#define _PR_MD_SEND _MD_SEND 1.1163 + 1.1164 +extern PRInt32 _PR_MD_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, 1.1165 + PRNetAddr **raddr, void *buf, PRInt32 amount, 1.1166 + PRIntervalTime timeout); 1.1167 +#define _PR_MD_ACCEPT_READ _MD_ACCEPT_READ 1.1168 + 1.1169 +#ifdef WIN32 1.1170 +extern PROsfd _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *addr, 1.1171 + PRUint32 *addrlen, PRIntervalTime timeout, 1.1172 + PRBool fast, 1.1173 + _PR_AcceptTimeoutCallback callback, 1.1174 + void *callbackArg); 1.1175 + 1.1176 +extern PRInt32 _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, 1.1177 + PRNetAddr **raddr, void *buf, PRInt32 amount, 1.1178 + PRIntervalTime timeout, PRBool fast, 1.1179 + _PR_AcceptTimeoutCallback callback, 1.1180 + void *callbackArg); 1.1181 + 1.1182 +extern void _PR_MD_UPDATE_ACCEPT_CONTEXT(PROsfd s, PROsfd ls); 1.1183 +#define _PR_MD_UPDATE_ACCEPT_CONTEXT _MD_UPDATE_ACCEPT_CONTEXT 1.1184 +/* 1.1185 + * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME. 1.1186 + * We store the value in a PRTime variable for convenience. 1.1187 + * This constant is used by _PR_FileTimeToPRTime(). 1.1188 + * This is defined in ntmisc.c 1.1189 + */ 1.1190 +extern const PRTime _pr_filetime_offset; 1.1191 +#endif /* WIN32 */ 1.1192 + 1.1193 +extern PRInt32 _PR_MD_SENDFILE( 1.1194 + PRFileDesc *sock, PRSendFileData *sfd, 1.1195 + PRInt32 flags, PRIntervalTime timeout); 1.1196 +#define _PR_MD_SENDFILE _MD_SENDFILE 1.1197 + 1.1198 +extern PRStatus _PR_MD_GETSOCKNAME( 1.1199 + PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen); 1.1200 +#define _PR_MD_GETSOCKNAME _MD_GETSOCKNAME 1.1201 + 1.1202 +extern PRStatus _PR_MD_GETPEERNAME( 1.1203 + PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen); 1.1204 +#define _PR_MD_GETPEERNAME _MD_GETPEERNAME 1.1205 + 1.1206 +extern PRStatus _PR_MD_GETSOCKOPT( 1.1207 + PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen); 1.1208 +#define _PR_MD_GETSOCKOPT _MD_GETSOCKOPT 1.1209 + 1.1210 +extern PRStatus _PR_MD_SETSOCKOPT( 1.1211 + PRFileDesc *fd, PRInt32 level, PRInt32 optname, 1.1212 + const char* optval, PRInt32 optlen); 1.1213 +#define _PR_MD_SETSOCKOPT _MD_SETSOCKOPT 1.1214 + 1.1215 +extern PRStatus PR_CALLBACK _PR_SocketGetSocketOption( 1.1216 + PRFileDesc *fd, PRSocketOptionData *data); 1.1217 + 1.1218 +extern PRStatus PR_CALLBACK _PR_SocketSetSocketOption( 1.1219 + PRFileDesc *fd, const PRSocketOptionData *data); 1.1220 + 1.1221 +extern PRInt32 _PR_MD_RECVFROM( 1.1222 + PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, 1.1223 + PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout); 1.1224 +#define _PR_MD_RECVFROM _MD_RECVFROM 1.1225 + 1.1226 +extern PRInt32 _PR_MD_SENDTO( 1.1227 + PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, 1.1228 + const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout); 1.1229 +#define _PR_MD_SENDTO _MD_SENDTO 1.1230 + 1.1231 +extern PRInt32 _PR_MD_SOCKETPAIR(int af, int type, int flags, PROsfd *osfd); 1.1232 +#define _PR_MD_SOCKETPAIR _MD_SOCKETPAIR 1.1233 + 1.1234 +extern PROsfd _PR_MD_SOCKET(int af, int type, int flags); 1.1235 +#define _PR_MD_SOCKET _MD_SOCKET 1.1236 + 1.1237 +extern PRInt32 _PR_MD_SOCKETAVAILABLE(PRFileDesc *fd); 1.1238 +#define _PR_MD_SOCKETAVAILABLE _MD_SOCKETAVAILABLE 1.1239 + 1.1240 +extern PRInt32 _PR_MD_PIPEAVAILABLE(PRFileDesc *fd); 1.1241 +#define _PR_MD_PIPEAVAILABLE _MD_PIPEAVAILABLE 1.1242 + 1.1243 +extern PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, 1.1244 + PRIntervalTime timeout); 1.1245 +#define _PR_MD_PR_POLL _MD_PR_POLL 1.1246 + 1.1247 +/* 1.1248 + * Initialize fd->secret->inheritable for a newly created fd. 1.1249 + * If 'imported' is false, the osfd (i.e., fd->secret->md.osfd) 1.1250 + * was created by NSPR and hence has the OS-dependent default 1.1251 + * inheritable attribute. If 'imported' is true, the osfd was 1.1252 + * not created by NSPR and hence a system call is required to 1.1253 + * query its inheritable attribute. Since we may never need to 1.1254 + * know the inheritable attribute of a fd, a platform may choose 1.1255 + * to initialize fd->secret->inheritable of an imported fd to 1.1256 + * _PR_TRI_UNKNOWN and only pay the cost of the system call 1.1257 + * (in _PR_MD_QUERY_FD_INHERITABLE) when necessary. 1.1258 + */ 1.1259 +extern void _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported); 1.1260 +#define _PR_MD_INIT_FD_INHERITABLE _MD_INIT_FD_INHERITABLE 1.1261 + 1.1262 +extern PRStatus _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable); 1.1263 +#define _PR_MD_SET_FD_INHERITABLE _MD_SET_FD_INHERITABLE 1.1264 + 1.1265 + 1.1266 +#define _PR_PROCESS_TIMEOUT_INTERRUPT_ERRORS(me) \ 1.1267 + if (_PR_PENDING_INTERRUPT(me)) { \ 1.1268 + me->flags &= ~_PR_INTERRUPT; \ 1.1269 + PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); \ 1.1270 + } else { \ 1.1271 + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); \ 1.1272 + } 1.1273 + 1.1274 +extern void *_PR_MD_GET_SP(PRThread *thread); 1.1275 +#define _PR_MD_GET_SP _MD_GET_SP 1.1276 + 1.1277 +#endif /* defined(_PR_PTHREADS) */ 1.1278 + 1.1279 +/************************************************************************/ 1.1280 +/************************************************************************* 1.1281 +** The remainder of the definitions are shared by pthreads and the classic 1.1282 +** NSPR code. These too may be conditionalized. 1.1283 +*************************************************************************/ 1.1284 +/************************************************************************/ 1.1285 + 1.1286 +extern PROffset32 _PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence); 1.1287 +#define _PR_MD_LSEEK _MD_LSEEK 1.1288 + 1.1289 +extern PROffset64 _PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence); 1.1290 +#define _PR_MD_LSEEK64 _MD_LSEEK64 1.1291 + 1.1292 +extern PRInt32 _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info); 1.1293 +#define _PR_MD_GETFILEINFO _MD_GETFILEINFO 1.1294 + 1.1295 +extern PRInt32 _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info); 1.1296 +#define _PR_MD_GETFILEINFO64 _MD_GETFILEINFO64 1.1297 + 1.1298 +extern PRInt32 _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info); 1.1299 +#define _PR_MD_GETOPENFILEINFO _MD_GETOPENFILEINFO 1.1300 + 1.1301 +extern PRInt32 _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info); 1.1302 +#define _PR_MD_GETOPENFILEINFO64 _MD_GETOPENFILEINFO64 1.1303 + 1.1304 + 1.1305 +/*****************************************************************************/ 1.1306 +/************************** File descriptor caching **************************/ 1.1307 +/*****************************************************************************/ 1.1308 +extern void _PR_InitFdCache(void); 1.1309 +extern void _PR_CleanupFdCache(void); 1.1310 +extern PRFileDesc *_PR_Getfd(void); 1.1311 +extern void _PR_Putfd(PRFileDesc *fd); 1.1312 + 1.1313 +/* 1.1314 + * These flags are used by NSPR temporarily in the poll 1.1315 + * descriptor's out_flags field to record the mapping of 1.1316 + * NSPR's poll flags to the system poll flags. 1.1317 + * 1.1318 + * If _PR_POLL_READ_SYS_WRITE bit is set, it means the 1.1319 + * PR_POLL_READ flag specified by the topmost layer is 1.1320 + * mapped to the WRITE flag at the system layer. Similarly 1.1321 + * for the other three _PR_POLL_XXX_SYS_YYY flags. It is 1.1322 + * assumed that the PR_POLL_EXCEPT flag doesn't get mapped 1.1323 + * to other flags. 1.1324 + */ 1.1325 +#define _PR_POLL_READ_SYS_READ 0x1 1.1326 +#define _PR_POLL_READ_SYS_WRITE 0x2 1.1327 +#define _PR_POLL_WRITE_SYS_READ 0x4 1.1328 +#define _PR_POLL_WRITE_SYS_WRITE 0x8 1.1329 + 1.1330 +/* 1.1331 +** These methods are coerced into file descriptor methods table 1.1332 +** when the intended service is inappropriate for the particular 1.1333 +** type of file descriptor. 1.1334 +*/ 1.1335 +extern PRIntn _PR_InvalidInt(void); 1.1336 +extern PRInt16 _PR_InvalidInt16(void); 1.1337 +extern PRInt64 _PR_InvalidInt64(void); 1.1338 +extern PRStatus _PR_InvalidStatus(void); 1.1339 +extern PRFileDesc *_PR_InvalidDesc(void); 1.1340 + 1.1341 +extern PRIOMethods _pr_faulty_methods; 1.1342 + 1.1343 +/* 1.1344 +** The PR_NETADDR_SIZE macro can only be called on a PRNetAddr union 1.1345 +** whose 'family' field is set. It returns the size of the union 1.1346 +** member corresponding to the specified address family. 1.1347 +*/ 1.1348 + 1.1349 +extern PRUintn _PR_NetAddrSize(const PRNetAddr* addr); 1.1350 + 1.1351 +#if defined(_PR_INET6) 1.1352 + 1.1353 +#define PR_NETADDR_SIZE(_addr) _PR_NetAddrSize(_addr) 1.1354 + 1.1355 +#elif defined(_PR_HAVE_MD_SOCKADDR_IN6) 1.1356 + 1.1357 +/* 1.1358 +** Under the following conditions: 1.1359 +** 1. _PR_INET6 is not defined; 1.1360 +** 2. _PR_INET6_PROBE is defined; 1.1361 +** 3. struct sockaddr_in6 has nonstandard fields at the end 1.1362 +** (e.g., on Solaris 8), 1.1363 +** (_addr)->ipv6 is smaller than struct sockaddr_in6, and 1.1364 +** hence we can't pass sizeof((_addr)->ipv6) to socket 1.1365 +** functions such as connect because they would fail with 1.1366 +** EINVAL. 1.1367 +** 1.1368 +** To pass the correct socket address length to socket 1.1369 +** functions, define the macro _PR_HAVE_MD_SOCKADDR_IN6 and 1.1370 +** define struct _md_sockaddr_in6 to be isomorphic to 1.1371 +** struct sockaddr_in6. 1.1372 +*/ 1.1373 + 1.1374 +#if defined(XP_UNIX) || defined(XP_OS2) 1.1375 +#define PR_NETADDR_SIZE(_addr) \ 1.1376 + ((_addr)->raw.family == PR_AF_INET \ 1.1377 + ? sizeof((_addr)->inet) \ 1.1378 + : ((_addr)->raw.family == PR_AF_INET6 \ 1.1379 + ? sizeof(struct _md_sockaddr_in6) \ 1.1380 + : sizeof((_addr)->local))) 1.1381 +#else 1.1382 +#define PR_NETADDR_SIZE(_addr) \ 1.1383 + ((_addr)->raw.family == PR_AF_INET \ 1.1384 + ? sizeof((_addr)->inet) \ 1.1385 + : sizeof(struct _md_sockaddr_in6)) 1.1386 +#endif /* defined(XP_UNIX) */ 1.1387 + 1.1388 +#else 1.1389 + 1.1390 +#if defined(XP_UNIX) || defined(XP_OS2) 1.1391 +#define PR_NETADDR_SIZE(_addr) \ 1.1392 + ((_addr)->raw.family == PR_AF_INET \ 1.1393 + ? sizeof((_addr)->inet) \ 1.1394 + : ((_addr)->raw.family == PR_AF_INET6 \ 1.1395 + ? sizeof((_addr)->ipv6) \ 1.1396 + : sizeof((_addr)->local))) 1.1397 +#else 1.1398 +#define PR_NETADDR_SIZE(_addr) \ 1.1399 + ((_addr)->raw.family == PR_AF_INET \ 1.1400 + ? sizeof((_addr)->inet) \ 1.1401 + : sizeof((_addr)->ipv6)) 1.1402 +#endif /* defined(XP_UNIX) */ 1.1403 + 1.1404 +#endif /* defined(_PR_INET6) */ 1.1405 + 1.1406 +extern PRStatus _PR_MapOptionName( 1.1407 + PRSockOption optname, PRInt32 *level, PRInt32 *name); 1.1408 +extern void _PR_InitThreads( 1.1409 + PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs); 1.1410 + 1.1411 +struct PRLock { 1.1412 +#if defined(_PR_PTHREADS) 1.1413 + pthread_mutex_t mutex; /* the underlying lock */ 1.1414 + _PT_Notified notified; /* array of conditions notified */ 1.1415 + PRBool locked; /* whether the mutex is locked */ 1.1416 + pthread_t owner; /* if locked, current lock owner */ 1.1417 +#elif defined(_PR_BTHREADS) 1.1418 + sem_id semaphoreID; /* the underlying lock */ 1.1419 + int32 benaphoreCount; /* number of people in lock */ 1.1420 + thread_id owner; /* current lock owner */ 1.1421 +#else /* not pthreads or Be threads */ 1.1422 + PRCList links; /* linkage for PRThread.lockList */ 1.1423 + struct PRThread *owner; /* current lock owner */ 1.1424 + PRCList waitQ; /* list of threads waiting for lock */ 1.1425 + PRThreadPriority priority; /* priority of lock */ 1.1426 + PRThreadPriority boostPriority; /* boosted priority of lock owner */ 1.1427 + _MDLock ilock; /* Internal Lock to protect user-level fields */ 1.1428 +#endif 1.1429 +}; 1.1430 + 1.1431 +struct PRCondVar { 1.1432 + PRLock *lock; /* associated lock that protects the condition */ 1.1433 +#if defined(_PR_PTHREADS) 1.1434 + pthread_cond_t cv; /* underlying pthreads condition */ 1.1435 + PRInt32 notify_pending; /* CV has destroy pending notification */ 1.1436 +#elif defined(_PR_BTHREADS) 1.1437 + sem_id sem; /* the underlying lock */ 1.1438 + sem_id handshakeSem; /* the lock for 'notify'-threads waiting for confirmation */ 1.1439 + sem_id signalSem; /* the lock for threads waiting for someone to notify */ 1.1440 + volatile int32 nw; /* the number waiting */ 1.1441 + volatile int32 ns; /* the number signalling */ 1.1442 + long signalBenCount; /* the number waiting on the underlying sem */ 1.1443 +#else /* not pthreads or Be threads */ 1.1444 + PRCList condQ; /* Condition variable wait Q */ 1.1445 + _MDLock ilock; /* Internal Lock to protect condQ */ 1.1446 + _MDCVar md; 1.1447 +#endif 1.1448 +}; 1.1449 + 1.1450 +/************************************************************************/ 1.1451 + 1.1452 +struct PRMonitor { 1.1453 + const char* name; /* monitor name for debugging */ 1.1454 +#if defined(_PR_PTHREADS) 1.1455 + pthread_mutex_t lock; /* lock is only held when accessing fields 1.1456 + * of the PRMonitor, instead of being held 1.1457 + * while the monitor is entered. The only 1.1458 + * exception is notifyTimes, which is 1.1459 + * protected by the monitor. */ 1.1460 + pthread_t owner; /* the owner of the monitor or invalid */ 1.1461 + pthread_cond_t entryCV; /* for threads waiting to enter the monitor */ 1.1462 + 1.1463 + pthread_cond_t waitCV; /* for threads waiting on the monitor */ 1.1464 + PRInt32 refCount; /* reference count, an atomic variable. 1.1465 + * PR_NewMonitor adds a reference to the 1.1466 + * newly created PRMonitor, and 1.1467 + * PR_DestroyMonitor releases that reference. 1.1468 + * PR_ExitMonitor adds a reference before 1.1469 + * unlocking the internal lock if it needs to 1.1470 + * signal entryCV, and releases the reference 1.1471 + * after signaling entryCV. */ 1.1472 +#else /* defined(_PR_PTHREADS) */ 1.1473 + PRLock lock; /* lock is only held when accessing fields 1.1474 + * of the PRMonitor, instead of being held 1.1475 + * while the monitor is entered. The only 1.1476 + * exception is notifyTimes, which is 1.1477 + * protected by the monitor. */ 1.1478 + PRThread *owner; /* the owner of the monitor or invalid */ 1.1479 + PRCondVar entryCV; /* for threads waiting to enter the monitor */ 1.1480 + 1.1481 + PRCondVar waitCV; /* for threads waiting on the monitor */ 1.1482 +#endif /* defined(_PR_PTHREADS) */ 1.1483 + PRUint32 entryCount; /* # of times re-entered */ 1.1484 + PRIntn notifyTimes; /* number of pending notifies for waitCV. 1.1485 + * The special value -1 means a broadcast 1.1486 + * (PR_NotifyAll). */ 1.1487 +}; 1.1488 + 1.1489 +/************************************************************************/ 1.1490 + 1.1491 +struct PRSemaphore { 1.1492 +#if defined(_PR_BTHREADS) 1.1493 + sem_id sem; 1.1494 + int32 benaphoreCount; 1.1495 +#else 1.1496 + PRCondVar *cvar; /* associated lock and condition variable queue */ 1.1497 + PRUintn count; /* the value of the counting semaphore */ 1.1498 + PRUint32 waiters; /* threads waiting on the semaphore */ 1.1499 +#if defined(_PR_PTHREADS) 1.1500 +#else /* defined(_PR_PTHREADS) */ 1.1501 + _MDSemaphore md; 1.1502 +#endif /* defined(_PR_PTHREADS) */ 1.1503 +#endif /* defined(_PR_BTHREADS) */ 1.1504 +}; 1.1505 + 1.1506 +/*************************************************************************/ 1.1507 + 1.1508 +struct PRSem { 1.1509 +#ifdef _PR_HAVE_POSIX_SEMAPHORES 1.1510 + sem_t *sem; 1.1511 +#elif defined(_PR_HAVE_SYSV_SEMAPHORES) 1.1512 + int semid; 1.1513 +#elif defined(WIN32) 1.1514 + HANDLE sem; 1.1515 +#else 1.1516 + PRInt8 notused; 1.1517 +#endif 1.1518 +}; 1.1519 + 1.1520 +/*************************************************************************/ 1.1521 + 1.1522 +struct PRStackStr { 1.1523 + /* head MUST be at offset 0; assembly language code relies on this */ 1.1524 +#if defined(AIX) 1.1525 + volatile PRStackElem prstk_head; 1.1526 +#else 1.1527 + PRStackElem prstk_head; 1.1528 +#endif 1.1529 + 1.1530 + PRLock *prstk_lock; 1.1531 + char *prstk_name; 1.1532 +}; 1.1533 + 1.1534 +/************************************************************************/ 1.1535 + 1.1536 +/* XXX this needs to be exported (sigh) */ 1.1537 +struct PRThreadStack { 1.1538 + PRCList links; 1.1539 + PRUintn flags; 1.1540 + 1.1541 + char *allocBase; /* base of stack's allocated memory */ 1.1542 + PRUint32 allocSize; /* size of stack's allocated memory */ 1.1543 + char *stackBottom; /* bottom of stack from C's point of view */ 1.1544 + char *stackTop; /* top of stack from C's point of view */ 1.1545 + PRUint32 stackSize; /* size of usable portion of the stack */ 1.1546 + 1.1547 + PRSegment *seg; 1.1548 + PRThread* thr; /* back pointer to thread owning this stack */ 1.1549 + 1.1550 +#if defined(_PR_PTHREADS) 1.1551 +#else /* defined(_PR_PTHREADS) */ 1.1552 + _MDThreadStack md; 1.1553 +#endif /* defined(_PR_PTHREADS) */ 1.1554 +}; 1.1555 + 1.1556 +extern void _PR_DestroyThreadPrivate(PRThread*); 1.1557 + 1.1558 +typedef void (PR_CALLBACK *_PRStartFn)(void *); 1.1559 + 1.1560 +struct PRThread { 1.1561 + PRUint32 state; /* thread's creation state */ 1.1562 + PRThreadPriority priority; /* apparent priority, loosly defined */ 1.1563 + 1.1564 + void *arg; /* argument to the client's entry point */ 1.1565 + _PRStartFn startFunc; /* the root of the client's thread */ 1.1566 + 1.1567 + PRThreadStack *stack; /* info about thread's stack (for GC) */ 1.1568 + void *environment; /* pointer to execution environment */ 1.1569 + 1.1570 + PRThreadDumpProc dump; /* dump thread info out */ 1.1571 + void *dumpArg; /* argument for the dump function */ 1.1572 + 1.1573 + /* 1.1574 + ** Per thread private data 1.1575 + */ 1.1576 + PRUint32 tpdLength; /* thread's current vector length */ 1.1577 + void **privateData; /* private data vector or NULL */ 1.1578 + PRErrorCode errorCode; /* current NSPR error code | zero */ 1.1579 + PRInt32 osErrorCode; /* mapping of errorCode | zero */ 1.1580 + PRIntn errorStringLength; /* textLength from last call to PR_SetErrorText() */ 1.1581 + PRInt32 errorStringSize; /* malloc()'d size of buffer | zero */ 1.1582 + char *errorString; /* current error string | NULL */ 1.1583 + char *name; /* thread's name */ 1.1584 + 1.1585 +#if defined(_PR_PTHREADS) 1.1586 + pthread_t id; /* pthread identifier for the thread */ 1.1587 + PRBool idSet; /* whether 'id' has been set. Protected by 1.1588 + * pt_book.ml. */ 1.1589 +#ifdef _PR_NICE_PRIORITY_SCHEDULING 1.1590 + pid_t tid; /* Linux-specific kernel thread ID */ 1.1591 +#endif 1.1592 + PRBool okToDelete; /* ok to delete the PRThread struct? */ 1.1593 + PRCondVar *waiting; /* where the thread is waiting | NULL */ 1.1594 + void *sp; /* recorded sp for garbage collection */ 1.1595 + PRThread *next, *prev; /* simple linked list of all threads */ 1.1596 + PRUint32 suspend; /* used to store suspend and resume flags */ 1.1597 +#ifdef PT_NO_SIGTIMEDWAIT 1.1598 + pthread_mutex_t suspendResumeMutex; 1.1599 + pthread_cond_t suspendResumeCV; 1.1600 +#endif 1.1601 + PRUint32 interrupt_blocked; /* interrupt blocked */ 1.1602 + struct pollfd *syspoll_list; /* Unix polling list used by PR_Poll */ 1.1603 + PRUint32 syspoll_count; /* number of elements in syspoll_list */ 1.1604 +#if defined(_PR_POLL_WITH_SELECT) 1.1605 + int *selectfd_list; /* Unix fd's that PR_Poll selects on */ 1.1606 + PRUint32 selectfd_count; /* number of elements in selectfd_list */ 1.1607 +#endif 1.1608 +#elif defined(_PR_BTHREADS) 1.1609 + PRUint32 flags; 1.1610 + _MDThread md; 1.1611 + PRBool io_pending; 1.1612 + PRInt32 io_fd; 1.1613 + PRBool io_suspended; 1.1614 +#else /* not pthreads or Be threads */ 1.1615 + _MDLock threadLock; /* Lock to protect thread state variables. 1.1616 + * Protects the following fields: 1.1617 + * state 1.1618 + * priority 1.1619 + * links 1.1620 + * wait 1.1621 + * cpu 1.1622 + */ 1.1623 + PRUint32 queueCount; 1.1624 + PRUint32 waitCount; 1.1625 + 1.1626 + PRCList active; /* on list of all active threads */ 1.1627 + PRCList links; 1.1628 + PRCList waitQLinks; /* when thread is PR_Wait'ing */ 1.1629 + PRCList lockList; /* list of locks currently holding */ 1.1630 + PRIntervalTime sleep; /* sleep time when thread is sleeping */ 1.1631 + struct _wait { 1.1632 + struct PRLock *lock; 1.1633 + struct PRCondVar *cvar; 1.1634 + } wait; 1.1635 + 1.1636 + PRUint32 id; 1.1637 + PRUint32 flags; 1.1638 + PRUint32 no_sched; /* Don't schedule the thread to run. 1.1639 + * This flag has relevance only when 1.1640 + * multiple NSPR CPUs are created. 1.1641 + * When a thread is de-scheduled, there 1.1642 + * is a narrow window of time in which 1.1643 + * the thread is put on the run queue 1.1644 + * but the scheduler is actually using 1.1645 + * the stack of this thread. It is safe 1.1646 + * to run this thread on a different CPU 1.1647 + * only when its stack is not in use on 1.1648 + * any other CPU. The no_sched flag is 1.1649 + * set during this interval to prevent 1.1650 + * the thread from being scheduled on a 1.1651 + * different CPU. 1.1652 + */ 1.1653 + 1.1654 + /* thread termination condition variable for join */ 1.1655 + PRCondVar *term; 1.1656 + 1.1657 + _PRCPU *cpu; /* cpu to which this thread is bound */ 1.1658 + PRUint32 threadAllocatedOnStack;/* boolean */ 1.1659 + 1.1660 + /* When an async IO is in progress and a second async IO cannot be 1.1661 + * initiated, the io_pending flag is set to true. Some platforms will 1.1662 + * not use the io_pending flag. If the io_pending flag is true, then 1.1663 + * io_fd is the OS-file descriptor on which IO is pending. 1.1664 + */ 1.1665 + PRBool io_pending; 1.1666 + PRInt32 io_fd; 1.1667 + 1.1668 + /* If a timeout occurs or if an outstanding IO is interrupted and the 1.1669 + * OS doesn't support a real cancellation (NT or MAC), then the 1.1670 + * io_suspended flag will be set to true. The thread will be resumed 1.1671 + * but may run into trouble issuing additional IOs until the io_pending 1.1672 + * flag can be cleared 1.1673 + */ 1.1674 + PRBool io_suspended; 1.1675 + 1.1676 + _MDThread md; 1.1677 +#endif 1.1678 +}; 1.1679 + 1.1680 +struct PRProcessAttr { 1.1681 + PRFileDesc *stdinFd; 1.1682 + PRFileDesc *stdoutFd; 1.1683 + PRFileDesc *stderrFd; 1.1684 + char *currentDirectory; 1.1685 + char *fdInheritBuffer; 1.1686 + PRSize fdInheritBufferSize; 1.1687 + PRSize fdInheritBufferUsed; 1.1688 +}; 1.1689 + 1.1690 +struct PRProcess { 1.1691 + _MDProcess md; 1.1692 +}; 1.1693 + 1.1694 +struct PRFileMap { 1.1695 + PRFileDesc *fd; 1.1696 + PRFileMapProtect prot; 1.1697 + _MDFileMap md; 1.1698 +}; 1.1699 + 1.1700 +/************************************************************************/ 1.1701 + 1.1702 +/* 1.1703 +** File descriptors of the NSPR layer can be in one of the 1.1704 +** following states (stored in the 'state' field of struct 1.1705 +** PRFilePrivate): 1.1706 +** - _PR_FILEDESC_OPEN: The OS fd is open. 1.1707 +** - _PR_FILEDESC_CLOSED: The OS fd is closed. The PRFileDesc 1.1708 +** is still open but is unusable. The only operation allowed 1.1709 +** on the PRFileDesc is PR_Close(). 1.1710 +** - _PR_FILEDESC_FREED: The OS fd is closed and the PRFileDesc 1.1711 +** structure is freed. 1.1712 +*/ 1.1713 + 1.1714 +#define _PR_FILEDESC_OPEN 0xaaaaaaaa /* 1010101... */ 1.1715 +#define _PR_FILEDESC_CLOSED 0x55555555 /* 0101010... */ 1.1716 +#define _PR_FILEDESC_FREED 0x11111111 1.1717 + 1.1718 +/* 1.1719 +** A boolean type with an additional "unknown" state 1.1720 +*/ 1.1721 + 1.1722 +typedef enum { 1.1723 + _PR_TRI_TRUE = 1, 1.1724 + _PR_TRI_FALSE = 0, 1.1725 + _PR_TRI_UNKNOWN = -1 1.1726 +} _PRTriStateBool; 1.1727 + 1.1728 +struct PRFilePrivate { 1.1729 + PRInt32 state; 1.1730 + PRBool nonblocking; 1.1731 + _PRTriStateBool inheritable; 1.1732 + PRFileDesc *next; 1.1733 + PRIntn lockCount; /* 0: not locked 1.1734 + * -1: a native lockfile call is in progress 1.1735 + * > 0: # times the file is locked */ 1.1736 +#ifdef _PR_HAVE_PEEK_BUFFER 1.1737 + char *peekBuffer; 1.1738 + PRInt32 peekBufSize; 1.1739 + PRInt32 peekBytes; 1.1740 +#endif 1.1741 +#if !defined(_PR_HAVE_O_APPEND) 1.1742 + PRBool appendMode; /* Some platforms don't have O_APPEND or its 1.1743 + * equivalent, so they have to seek to end of 1.1744 + * file on write if the file was opened in 1.1745 + * append mode. See Bugzilla 4090, 276330. */ 1.1746 +#endif 1.1747 + _MDFileDesc md; 1.1748 +#ifdef _PR_NEED_SECRET_AF 1.1749 + PRUint16 af; /* If the platform's implementation of accept() 1.1750 + * requires knowing the address family of the 1.1751 + * socket, we save the address family here. */ 1.1752 +#endif 1.1753 +}; 1.1754 + 1.1755 +#ifdef _WIN64 1.1756 +#define PR_PRIdOSFD "lld" /* for printing PROsfd */ 1.1757 +#define PR_PRIxOSFD "llx" 1.1758 +#define PR_SCNdOSFD "lld" /* for scanning PROsfd */ 1.1759 +#define PR_SCNxOSFD "llx" 1.1760 +#else 1.1761 +#define PR_PRIdOSFD "ld" /* for printing PROsfd */ 1.1762 +#define PR_PRIxOSFD "lx" 1.1763 +#define PR_SCNdOSFD "ld" /* for scanning PROsfd */ 1.1764 +#define PR_SCNxOSFD "lx" 1.1765 +#endif 1.1766 + 1.1767 +struct PRDir { 1.1768 + PRDirEntry d; 1.1769 + _MDDir md; 1.1770 +}; 1.1771 + 1.1772 +#ifdef MOZ_UNICODE 1.1773 +struct PRDirUTF16 { 1.1774 + PRDirEntry d; 1.1775 + _MDDirUTF16 md; 1.1776 +}; 1.1777 +#endif /* MOZ_UNICODE */ 1.1778 + 1.1779 +extern void _PR_InitLocks(void); 1.1780 +extern void _PR_InitSegs(void); 1.1781 +extern void _PR_InitStacks(void); 1.1782 +extern void _PR_InitTPD(void); 1.1783 +extern void _PR_InitMem(void); 1.1784 +extern void _PR_InitEnv(void); 1.1785 +extern void _PR_InitCMon(void); 1.1786 +extern void _PR_InitIO(void); 1.1787 +extern void _PR_InitLog(void); 1.1788 +extern void _PR_InitNet(void); 1.1789 +extern void _PR_InitClock(void); 1.1790 +extern void _PR_InitLinker(void); 1.1791 +extern void _PR_InitAtomic(void); 1.1792 +extern void _PR_InitCPUs(void); 1.1793 +extern void _PR_InitDtoa(void); 1.1794 +extern void _PR_InitTime(void); 1.1795 +extern void _PR_InitMW(void); 1.1796 +extern void _PR_InitRWLocks(void); 1.1797 +extern void _PR_CleanupThread(PRThread *thread); 1.1798 +extern void _PR_CleanupCallOnce(void); 1.1799 +extern void _PR_CleanupMW(void); 1.1800 +extern void _PR_CleanupTime(void); 1.1801 +extern void _PR_CleanupDtoa(void); 1.1802 +extern void _PR_ShutdownLinker(void); 1.1803 +extern void _PR_CleanupEnv(void); 1.1804 +extern void _PR_CleanupIO(void); 1.1805 +extern void _PR_CleanupCMon(void); 1.1806 +extern void _PR_CleanupNet(void); 1.1807 +extern void _PR_CleanupLayerCache(void); 1.1808 +extern void _PR_CleanupStacks(void); 1.1809 +#ifdef WINNT 1.1810 +extern void _PR_CleanupCPUs(void); 1.1811 +#endif 1.1812 +extern void _PR_CleanupThreads(void); 1.1813 +extern void _PR_CleanupTPD(void); 1.1814 +extern void _PR_Cleanup(void); 1.1815 +extern void _PR_LogCleanup(void); 1.1816 +extern void _PR_InitLayerCache(void); 1.1817 + 1.1818 +extern PRBool _pr_initialized; 1.1819 +extern void _PR_ImplicitInitialization(void); 1.1820 +extern PRBool _PR_Obsolete(const char *obsolete, const char *preferred); 1.1821 + 1.1822 +/************************************************************************/ 1.1823 + 1.1824 +struct PRSegment { 1.1825 + void *vaddr; 1.1826 + PRUint32 size; 1.1827 + PRUintn flags; 1.1828 +#if defined(_PR_PTHREADS) 1.1829 +#else /* defined(_PR_PTHREADS) */ 1.1830 + _MDSegment md; 1.1831 +#endif /* defined(_PR_PTHREADS) */ 1.1832 +}; 1.1833 + 1.1834 +/* PRSegment.flags */ 1.1835 +#define _PR_SEG_VM 0x1 1.1836 + 1.1837 +/************************************************************************/ 1.1838 + 1.1839 +extern PRInt32 _pr_pageSize; 1.1840 +extern PRInt32 _pr_pageShift; 1.1841 + 1.1842 +extern PRLogModuleInfo *_pr_clock_lm; 1.1843 +extern PRLogModuleInfo *_pr_cmon_lm; 1.1844 +extern PRLogModuleInfo *_pr_io_lm; 1.1845 +extern PRLogModuleInfo *_pr_cvar_lm; 1.1846 +extern PRLogModuleInfo *_pr_mon_lm; 1.1847 +extern PRLogModuleInfo *_pr_linker_lm; 1.1848 +extern PRLogModuleInfo *_pr_sched_lm; 1.1849 +extern PRLogModuleInfo *_pr_thread_lm; 1.1850 +extern PRLogModuleInfo *_pr_gc_lm; 1.1851 + 1.1852 +extern PRFileDesc *_pr_stdin; 1.1853 +extern PRFileDesc *_pr_stdout; 1.1854 +extern PRFileDesc *_pr_stderr; 1.1855 + 1.1856 +/* Zone allocator */ 1.1857 +/* 1.1858 +** The zone allocator code has hardcoded pthread types and 1.1859 +** functions, so it can only be used in the pthreads version. 1.1860 +** This can be fixed by replacing the hardcoded pthread types 1.1861 +** and functions with macros that expand to the native thread 1.1862 +** types and functions on each platform. 1.1863 +*/ 1.1864 +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) 1.1865 +#define _PR_ZONE_ALLOCATOR 1.1866 +#endif 1.1867 + 1.1868 +#ifdef _PR_ZONE_ALLOCATOR 1.1869 +extern void _PR_InitZones(void); 1.1870 +extern void _PR_DestroyZones(void); 1.1871 +#endif 1.1872 + 1.1873 +/* Overriding malloc, free, etc. */ 1.1874 +#if !defined(_PR_NO_PREEMPT) && defined(XP_UNIX) \ 1.1875 + && !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) \ 1.1876 + && !defined(PURIFY) \ 1.1877 + && !defined(DARWIN) \ 1.1878 + && !defined(QNX) \ 1.1879 + && !(defined (UNIXWARE) && defined (USE_SVR4_THREADS)) 1.1880 +#define _PR_OVERRIDE_MALLOC 1.1881 +#endif 1.1882 + 1.1883 +/************************************************************************* 1.1884 +* External machine-dependent code provided by each OS. * * 1.1885 +*************************************************************************/ 1.1886 + 1.1887 +/* Initialization related */ 1.1888 +extern void _PR_MD_EARLY_INIT(void); 1.1889 +#define _PR_MD_EARLY_INIT _MD_EARLY_INIT 1.1890 + 1.1891 +extern void _PR_MD_INTERVAL_INIT(void); 1.1892 +#define _PR_MD_INTERVAL_INIT _MD_INTERVAL_INIT 1.1893 + 1.1894 +NSPR_API(void) _PR_MD_FINAL_INIT(void); 1.1895 +#define _PR_MD_FINAL_INIT _MD_FINAL_INIT 1.1896 + 1.1897 +extern void _PR_MD_EARLY_CLEANUP(void); 1.1898 +#define _PR_MD_EARLY_CLEANUP _MD_EARLY_CLEANUP 1.1899 + 1.1900 +/* Process control */ 1.1901 + 1.1902 +extern PRProcess * _PR_MD_CREATE_PROCESS( 1.1903 + const char *path, 1.1904 + char *const *argv, 1.1905 + char *const *envp, 1.1906 + const PRProcessAttr *attr); 1.1907 +#define _PR_MD_CREATE_PROCESS _MD_CREATE_PROCESS 1.1908 + 1.1909 +extern PRStatus _PR_MD_DETACH_PROCESS(PRProcess *process); 1.1910 +#define _PR_MD_DETACH_PROCESS _MD_DETACH_PROCESS 1.1911 + 1.1912 +extern PRStatus _PR_MD_WAIT_PROCESS(PRProcess *process, PRInt32 *exitCode); 1.1913 +#define _PR_MD_WAIT_PROCESS _MD_WAIT_PROCESS 1.1914 + 1.1915 +extern PRStatus _PR_MD_KILL_PROCESS(PRProcess *process); 1.1916 +#define _PR_MD_KILL_PROCESS _MD_KILL_PROCESS 1.1917 + 1.1918 +/* Current Time */ 1.1919 +NSPR_API(PRTime) _PR_MD_NOW(void); 1.1920 +#define _PR_MD_NOW _MD_NOW 1.1921 + 1.1922 +/* Environment related */ 1.1923 +extern char* _PR_MD_GET_ENV(const char *name); 1.1924 +#define _PR_MD_GET_ENV _MD_GET_ENV 1.1925 + 1.1926 +extern PRIntn _PR_MD_PUT_ENV(const char *name); 1.1927 +#define _PR_MD_PUT_ENV _MD_PUT_ENV 1.1928 + 1.1929 +/* Atomic operations */ 1.1930 + 1.1931 +extern void _PR_MD_INIT_ATOMIC(void); 1.1932 +#define _PR_MD_INIT_ATOMIC _MD_INIT_ATOMIC 1.1933 + 1.1934 +extern PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *); 1.1935 +#define _PR_MD_ATOMIC_INCREMENT _MD_ATOMIC_INCREMENT 1.1936 + 1.1937 +extern PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *, PRInt32); 1.1938 +#define _PR_MD_ATOMIC_ADD _MD_ATOMIC_ADD 1.1939 + 1.1940 +extern PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *); 1.1941 +#define _PR_MD_ATOMIC_DECREMENT _MD_ATOMIC_DECREMENT 1.1942 + 1.1943 +extern PRInt32 _PR_MD_ATOMIC_SET(PRInt32 *, PRInt32); 1.1944 +#define _PR_MD_ATOMIC_SET _MD_ATOMIC_SET 1.1945 + 1.1946 +/* Garbage collection */ 1.1947 + 1.1948 +/* 1.1949 +** Save the registers that the GC would find interesting into the thread 1.1950 +** "t". isCurrent will be non-zero if the thread state that is being 1.1951 +** saved is the currently executing thread. Return the address of the 1.1952 +** first register to be scanned as well as the number of registers to 1.1953 +** scan in "np". 1.1954 +** 1.1955 +** If "isCurrent" is non-zero then it is allowed for the thread context 1.1956 +** area to be used as scratch storage to hold just the registers 1.1957 +** necessary for scanning. 1.1958 +*/ 1.1959 +extern PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np); 1.1960 + 1.1961 +/* Time intervals */ 1.1962 + 1.1963 +extern PRIntervalTime _PR_MD_GET_INTERVAL(void); 1.1964 +#define _PR_MD_GET_INTERVAL _MD_GET_INTERVAL 1.1965 + 1.1966 +extern PRIntervalTime _PR_MD_INTERVAL_PER_SEC(void); 1.1967 +#define _PR_MD_INTERVAL_PER_SEC _MD_INTERVAL_PER_SEC 1.1968 + 1.1969 +/* Affinity masks */ 1.1970 + 1.1971 +extern PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask ); 1.1972 +#define _PR_MD_SETTHREADAFFINITYMASK _MD_SETTHREADAFFINITYMASK 1.1973 + 1.1974 +extern PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask); 1.1975 +#define _PR_MD_GETTHREADAFFINITYMASK _MD_GETTHREADAFFINITYMASK 1.1976 + 1.1977 +/* File locking */ 1.1978 + 1.1979 +extern PRStatus _PR_MD_LOCKFILE(PROsfd osfd); 1.1980 +#define _PR_MD_LOCKFILE _MD_LOCKFILE 1.1981 + 1.1982 +extern PRStatus _PR_MD_TLOCKFILE(PROsfd osfd); 1.1983 +#define _PR_MD_TLOCKFILE _MD_TLOCKFILE 1.1984 + 1.1985 +extern PRStatus _PR_MD_UNLOCKFILE(PROsfd osfd); 1.1986 +#define _PR_MD_UNLOCKFILE _MD_UNLOCKFILE 1.1987 + 1.1988 +/* Memory-mapped files */ 1.1989 + 1.1990 +extern PRStatus _PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size); 1.1991 +#define _PR_MD_CREATE_FILE_MAP _MD_CREATE_FILE_MAP 1.1992 + 1.1993 +extern PRInt32 _PR_MD_GET_MEM_MAP_ALIGNMENT(void); 1.1994 +#define _PR_MD_GET_MEM_MAP_ALIGNMENT _MD_GET_MEM_MAP_ALIGNMENT 1.1995 + 1.1996 +extern void * _PR_MD_MEM_MAP( 1.1997 + PRFileMap *fmap, 1.1998 + PROffset64 offset, 1.1999 + PRUint32 len); 1.2000 +#define _PR_MD_MEM_MAP _MD_MEM_MAP 1.2001 + 1.2002 +extern PRStatus _PR_MD_MEM_UNMAP(void *addr, PRUint32 size); 1.2003 +#define _PR_MD_MEM_UNMAP _MD_MEM_UNMAP 1.2004 + 1.2005 +extern PRStatus _PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap); 1.2006 +#define _PR_MD_CLOSE_FILE_MAP _MD_CLOSE_FILE_MAP 1.2007 + 1.2008 +extern PRStatus _PR_MD_SYNC_MEM_MAP( 1.2009 + PRFileDesc *fd, 1.2010 + void *addr, 1.2011 + PRUint32 len); 1.2012 +#define _PR_MD_SYNC_MEM_MAP _MD_SYNC_MEM_MAP 1.2013 + 1.2014 +/* Named Shared Memory */ 1.2015 + 1.2016 +/* 1.2017 +** Declare PRSharedMemory. 1.2018 +*/ 1.2019 +struct PRSharedMemory 1.2020 +{ 1.2021 + char *ipcname; /* after conversion to native */ 1.2022 + PRSize size; /* from open */ 1.2023 + PRIntn mode; /* from open */ 1.2024 + PRIntn flags; /* from open */ 1.2025 +#if defined(PR_HAVE_POSIX_NAMED_SHARED_MEMORY) 1.2026 + int id; 1.2027 +#elif defined(PR_HAVE_SYSV_NAMED_SHARED_MEMORY) 1.2028 + int id; 1.2029 +#elif defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY) 1.2030 + HANDLE handle; 1.2031 +#else 1.2032 + PRUint32 nothing; /* placeholder, nothing behind here */ 1.2033 +#endif 1.2034 + PRUint32 ident; /* guard word at end of struct */ 1.2035 +#define _PR_SHM_IDENT 0xdeadbad 1.2036 +}; 1.2037 + 1.2038 +extern PRSharedMemory * _MD_OpenSharedMemory( 1.2039 + const char *name, 1.2040 + PRSize size, 1.2041 + PRIntn flags, 1.2042 + PRIntn mode 1.2043 +); 1.2044 +#define _PR_MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory 1.2045 + 1.2046 +extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ); 1.2047 +#define _PR_MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory 1.2048 + 1.2049 +extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ); 1.2050 +#define _PR_MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory 1.2051 + 1.2052 +extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ); 1.2053 +#define _PR_MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory 1.2054 + 1.2055 +extern PRStatus _MD_DeleteSharedMemory( const char *name ); 1.2056 +#define _PR_MD_DELETE_SHARED_MEMORY _MD_DeleteSharedMemory 1.2057 + 1.2058 +extern PRFileMap* _md_OpenAnonFileMap( 1.2059 + const char *dirName, 1.2060 + PRSize size, 1.2061 + PRFileMapProtect prot 1.2062 +); 1.2063 +#define _PR_MD_OPEN_ANON_FILE_MAP _md_OpenAnonFileMap 1.2064 + 1.2065 +extern PRStatus _md_ExportFileMapAsString( 1.2066 + PRFileMap *fm, 1.2067 + PRSize bufSize, 1.2068 + char *buf 1.2069 +); 1.2070 +#define _PR_MD_EXPORT_FILE_MAP_AS_STRING _md_ExportFileMapAsString 1.2071 + 1.2072 +extern PRFileMap * _md_ImportFileMapFromString( 1.2073 + const char *fmstring 1.2074 +); 1.2075 +#define _PR_MD_IMPORT_FILE_MAP_FROM_STRING _md_ImportFileMapFromString 1.2076 + 1.2077 + 1.2078 + 1.2079 +/* Interprocess communications (IPC) */ 1.2080 + 1.2081 +/* 1.2082 + * The maximum length of an NSPR IPC name, including the 1.2083 + * terminating null byte. 1.2084 + */ 1.2085 +#define PR_IPC_NAME_SIZE 1024 1.2086 + 1.2087 +/* 1.2088 + * Types of NSPR IPC objects 1.2089 + */ 1.2090 +typedef enum { 1.2091 + _PRIPCSem, /* semaphores */ 1.2092 + _PRIPCShm /* shared memory segments */ 1.2093 +} _PRIPCType; 1.2094 + 1.2095 +/* 1.2096 + * Make a native IPC name from an NSPR IPC name. 1.2097 + */ 1.2098 +extern PRStatus _PR_MakeNativeIPCName( 1.2099 + const char *name, /* NSPR IPC name */ 1.2100 + char *result, /* result buffer */ 1.2101 + PRIntn size, /* size of result buffer */ 1.2102 + _PRIPCType type /* type of IPC object */ 1.2103 +); 1.2104 + 1.2105 +/* Socket call error code */ 1.2106 + 1.2107 +NSPR_API(PRInt32) _PR_MD_GET_SOCKET_ERROR(void); 1.2108 +#define _PR_MD_GET_SOCKET_ERROR _MD_GET_SOCKET_ERROR 1.2109 + 1.2110 +/* Get name of current host */ 1.2111 +extern PRStatus _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen); 1.2112 +#define _PR_MD_GETHOSTNAME _MD_GETHOSTNAME 1.2113 + 1.2114 +extern PRStatus _PR_MD_GETSYSINFO(PRSysInfo cmd, char *name, PRUint32 namelen); 1.2115 +#define _PR_MD_GETSYSINFO _MD_GETSYSINFO 1.2116 + 1.2117 +/* File descriptor inheritance */ 1.2118 + 1.2119 +/* 1.2120 + * If fd->secret->inheritable is _PR_TRI_UNKNOWN and we need to 1.2121 + * know the inheritable attribute of the fd, call this function 1.2122 + * to find that out. This typically requires a system call. 1.2123 + */ 1.2124 +extern void _PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd); 1.2125 +#define _PR_MD_QUERY_FD_INHERITABLE _MD_QUERY_FD_INHERITABLE 1.2126 + 1.2127 +/* --- PR_GetRandomNoise() related things --- */ 1.2128 + 1.2129 +extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size ); 1.2130 +#define _PR_MD_GET_RANDOM_NOISE(buf,size) _PR_MD_GetRandomNoise((buf),(size)) 1.2131 +extern PRSize _pr_CopyLowBits( void *dest, PRSize dstlen, void *src, PRSize srclen ); 1.2132 + 1.2133 +/* end PR_GetRandomNoise() related */ 1.2134 + 1.2135 +#ifdef XP_BEOS 1.2136 + 1.2137 +extern PRLock *_connectLock; 1.2138 + 1.2139 +typedef struct _ConnectListNode { 1.2140 + PRInt32 osfd; 1.2141 + PRNetAddr addr; 1.2142 + PRUint32 addrlen; 1.2143 + PRIntervalTime timeout; 1.2144 +} ConnectListNode; 1.2145 + 1.2146 +extern ConnectListNode connectList[64]; 1.2147 + 1.2148 +extern PRUint32 connectCount; 1.2149 + 1.2150 +#endif /* XP_BEOS */ 1.2151 + 1.2152 +PR_END_EXTERN_C 1.2153 + 1.2154 +#endif /* primpl_h___ */