| OLD | NEW |
| (Empty) |
| 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
| 2 /* This Source Code Form is subject to the terms of the Mozilla Public | |
| 3 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 5 | |
| 6 #ifndef primpl_h___ | |
| 7 #define primpl_h___ | |
| 8 | |
| 9 /* | |
| 10 * HP-UX 10.10's pthread.h (DCE threads) includes dce/cma.h, which | |
| 11 * has: | |
| 12 * #define sigaction _sigaction_sys | |
| 13 * This macro causes chaos if signal.h gets included before pthread.h. | |
| 14 * To be safe, we include pthread.h first. | |
| 15 */ | |
| 16 | |
| 17 #if defined(_PR_PTHREADS) | |
| 18 #include <pthread.h> | |
| 19 #endif | |
| 20 | |
| 21 #if defined(_PR_BTHREADS) | |
| 22 #include <kernel/OS.h> | |
| 23 #endif | |
| 24 | |
| 25 #ifdef WIN32 | |
| 26 /* | |
| 27 * Allow use of functions and symbols first defined in Win2k. | |
| 28 */ | |
| 29 #if !defined(WINVER) || (WINVER < 0x0500) | |
| 30 #undef WINVER | |
| 31 #define WINVER 0x0500 | |
| 32 #endif | |
| 33 #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) | |
| 34 #undef _WIN32_WINNT | |
| 35 #define _WIN32_WINNT 0x0500 | |
| 36 #endif | |
| 37 #endif /* WIN32 */ | |
| 38 | |
| 39 #include "nspr.h" | |
| 40 #include "prpriv.h" | |
| 41 | |
| 42 typedef struct PRSegment PRSegment; | |
| 43 | |
| 44 #include "md/prosdep.h" | |
| 45 #include "obsolete/probslet.h" | |
| 46 | |
| 47 #ifdef _PR_HAVE_POSIX_SEMAPHORES | |
| 48 #include <semaphore.h> | |
| 49 #elif defined(_PR_HAVE_SYSV_SEMAPHORES) | |
| 50 #include <sys/sem.h> | |
| 51 #endif | |
| 52 | |
| 53 /************************************************************************* | |
| 54 ***** A Word about Model Dependent Function Naming Convention *********** | |
| 55 *************************************************************************/ | |
| 56 | |
| 57 /* | |
| 58 NSPR 2.0 must implement its function across a range of platforms | |
| 59 including: MAC, Windows/16, Windows/95, Windows/NT, and several | |
| 60 variants of Unix. Each implementation shares common code as well | |
| 61 as having platform dependent portions. This standard describes how | |
| 62 the model dependent portions are to be implemented. | |
| 63 | |
| 64 In header file pr/include/primpl.h, each publicly declared | |
| 65 platform dependent function is declared as: | |
| 66 | |
| 67 NSPR_API void _PR_MD_FUNCTION( long arg1, long arg2 ); | |
| 68 #define _PR_MD_FUNCTION _MD_FUNCTION | |
| 69 | |
| 70 In header file pr/include/md/<platform>/_<platform>.h, | |
| 71 each #define'd macro is redefined as one of: | |
| 72 | |
| 73 #define _MD_FUNCTION <blanks> | |
| 74 #define _MD_FUNCTION <expanded macro> | |
| 75 #define _MD_FUNCTION <osFunction> | |
| 76 #define _MD_FUNCTION <_MD_Function> | |
| 77 | |
| 78 Where: | |
| 79 | |
| 80 <blanks> is no definition at all. In this case, the function is not implemented | |
| 81 and is never called for this platform. | |
| 82 For example: | |
| 83 #define _MD_INIT_CPUS() | |
| 84 | |
| 85 <expanded macro> is a C language macro expansion. | |
| 86 For example: | |
| 87 #define _MD_CLEAN_THREAD(_thread) \ | |
| 88 PR_BEGIN_MACRO \ | |
| 89 PR_DestroyCondVar(_thread->md.asyncIOCVar); \ | |
| 90 PR_DestroyLock(_thread->md.asyncIOLock); \ | |
| 91 PR_END_MACRO | |
| 92 | |
| 93 <osFunction> is some function implemented by the host operating system. | |
| 94 For example: | |
| 95 #define _MD_EXIT exit | |
| 96 | |
| 97 <_MD_function> is the name of a function implemented for this platform in | |
| 98 pr/src/md/<platform>/<soruce>.c file. | |
| 99 For example: | |
| 100 #define _MD_GETFILEINFO _MD_GetFileInfo | |
| 101 | |
| 102 In <source>.c, the implementation is: | |
| 103 PR_IMPLEMENT(PRInt32) _MD_GetFileInfo(const char *fn, PRFileInfo *info); | |
| 104 */ | |
| 105 | |
| 106 PR_BEGIN_EXTERN_C | |
| 107 | |
| 108 typedef struct _MDLock _MDLock; | |
| 109 typedef struct _MDCVar _MDCVar; | |
| 110 typedef struct _MDSegment _MDSegment; | |
| 111 typedef struct _MDThread _MDThread; | |
| 112 typedef struct _MDThreadStack _MDThreadStack; | |
| 113 typedef struct _MDSemaphore _MDSemaphore; | |
| 114 typedef struct _MDDir _MDDir; | |
| 115 #ifdef MOZ_UNICODE | |
| 116 typedef struct _MDDirUTF16 _MDDirUTF16; | |
| 117 #endif /* MOZ_UNICODE */ | |
| 118 typedef struct _MDFileDesc _MDFileDesc; | |
| 119 typedef struct _MDProcess _MDProcess; | |
| 120 typedef struct _MDFileMap _MDFileMap; | |
| 121 | |
| 122 #if defined(_PR_PTHREADS) | |
| 123 | |
| 124 /* | |
| 125 ** The following definitions are unique to implementing NSPR using pthreads. | |
| 126 ** Since pthreads defines most of the thread and thread synchronization | |
| 127 ** stuff, this is a pretty small set. | |
| 128 */ | |
| 129 | |
| 130 #define PT_CV_NOTIFIED_LENGTH 6 | |
| 131 typedef struct _PT_Notified _PT_Notified; | |
| 132 struct _PT_Notified | |
| 133 { | |
| 134 PRIntn length; /* # of used entries in this structure */ | |
| 135 struct | |
| 136 { | |
| 137 PRCondVar *cv; /* the condition variable notified */ | |
| 138 PRIntn times; /* and the number of times notified */ | |
| 139 } cv[PT_CV_NOTIFIED_LENGTH]; | |
| 140 _PT_Notified *link; /* link to another of these | NULL */ | |
| 141 }; | |
| 142 | |
| 143 /* | |
| 144 * bits defined for pthreads 'state' field | |
| 145 */ | |
| 146 #define PT_THREAD_DETACHED 0x01 /* thread can't be joined */ | |
| 147 #define PT_THREAD_GLOBAL 0x02 /* a global thread (unlikely) */ | |
| 148 #define PT_THREAD_SYSTEM 0x04 /* system (not user) thread */ | |
| 149 #define PT_THREAD_PRIMORD 0x08 /* this is the primordial thread */ | |
| 150 #define PT_THREAD_ABORTED 0x10 /* thread has been interrupted */ | |
| 151 #define PT_THREAD_GCABLE 0x20 /* thread is garbage collectible */ | |
| 152 #define PT_THREAD_SUSPENDED 0x40 /* thread has been suspended */ | |
| 153 #define PT_THREAD_FOREIGN 0x80 /* thread is not one of ours */ | |
| 154 #define PT_THREAD_BOUND 0x100 /* a bound-global thread */ | |
| 155 | |
| 156 #define _PT_THREAD_INTERRUPTED(thr) \ | |
| 157 (!(thr->interrupt_blocked) && (thr->state & PT_THREAD_ABORTED)) | |
| 158 #define _PT_THREAD_BLOCK_INTERRUPT(thr) \ | |
| 159 (thr->interrupt_blocked = 1) | |
| 160 #define _PT_THREAD_UNBLOCK_INTERRUPT(thr) \ | |
| 161 (thr->interrupt_blocked = 0) | |
| 162 | |
| 163 #define _PT_IS_GCABLE_THREAD(thr) ((thr)->state & PT_THREAD_GCABLE) | |
| 164 | |
| 165 /* | |
| 166 ** Possible values for thread's suspend field | |
| 167 ** Note that the first two can be the same as they are really mutually exclusive
, | |
| 168 ** i.e. both cannot be happening at the same time. We have two symbolic names | |
| 169 ** just as a mnemonic. | |
| 170 **/ | |
| 171 #define PT_THREAD_RESUMED 0x80 /* thread has been resumed */ | |
| 172 #define PT_THREAD_SETGCABLE 0x100 /* set the GCAble flag */ | |
| 173 | |
| 174 #if defined(DEBUG) | |
| 175 | |
| 176 typedef struct PTDebug | |
| 177 { | |
| 178 PRTime timeStarted; | |
| 179 PRUintn locks_created, locks_destroyed; | |
| 180 PRUintn locks_acquired, locks_released; | |
| 181 PRUintn cvars_created, cvars_destroyed; | |
| 182 PRUintn cvars_notified, delayed_cv_deletes; | |
| 183 } PTDebug; | |
| 184 | |
| 185 #endif /* defined(DEBUG) */ | |
| 186 | |
| 187 NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg); | |
| 188 | |
| 189 #else /* defined(_PR_PTHREADS) */ | |
| 190 | |
| 191 NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg); | |
| 192 | |
| 193 /* | |
| 194 ** This section is contains those parts needed to implement NSPR on | |
| 195 ** platforms in general. One would assume that the pthreads implementation | |
| 196 ** included lots of the same types, at least conceptually. | |
| 197 */ | |
| 198 | |
| 199 /* | |
| 200 * Local threads only. No multiple CPU support and hence all the | |
| 201 * following routines are no-op. | |
| 202 */ | |
| 203 #ifdef _PR_LOCAL_THREADS_ONLY | |
| 204 | |
| 205 #define _PR_MD_SUSPEND_THREAD(thread) | |
| 206 #define _PR_MD_RESUME_THREAD(thread) | |
| 207 #define _PR_MD_SUSPEND_CPU(cpu) | |
| 208 #define _PR_MD_RESUME_CPU(cpu) | |
| 209 #define _PR_MD_BEGIN_SUSPEND_ALL() | |
| 210 #define _PR_MD_END_SUSPEND_ALL() | |
| 211 #define _PR_MD_BEGIN_RESUME_ALL() | |
| 212 #define _PR_MD_END_RESUME_ALL() | |
| 213 #define _PR_MD_INIT_ATTACHED_THREAD(thread) PR_FAILURE | |
| 214 | |
| 215 #endif | |
| 216 | |
| 217 typedef struct _PRCPUQueue _PRCPUQueue; | |
| 218 typedef struct _PRCPU _PRCPU; | |
| 219 typedef struct _MDCPU _MDCPU; | |
| 220 | |
| 221 struct _PRCPUQueue { | |
| 222 _MDLock runQLock; /* lock for the run + wait queues */ | |
| 223 _MDLock sleepQLock; /* lock for the run + wait queues */ | |
| 224 _MDLock miscQLock; /* lock for the run + wait queues */ | |
| 225 | |
| 226 PRCList runQ[PR_PRIORITY_LAST + 1]; /* run queue for this CPU */ | |
| 227 PRUint32 runQReadyMask; | |
| 228 PRCList sleepQ; | |
| 229 PRIntervalTime sleepQmax; | |
| 230 PRCList pauseQ; | |
| 231 PRCList suspendQ; | |
| 232 PRCList waitingToJoinQ; | |
| 233 | |
| 234 PRUintn numCPUs; /* number of CPUs using this Q */ | |
| 235 }; | |
| 236 | |
| 237 struct _PRCPU { | |
| 238 PRCList links; /* link list of CPUs */ | |
| 239 PRUint32 id; /* id for this CPU */ | |
| 240 | |
| 241 union { | |
| 242 PRInt32 bits; | |
| 243 PRUint8 missed[4]; | |
| 244 } u; | |
| 245 PRIntn where; /* index into u.missed */ | |
| 246 PRPackedBool paused; /* cpu is paused */ | |
| 247 PRPackedBool exit; /* cpu should exit */ | |
| 248 | |
| 249 PRThread *thread; /* native thread for this CPUThread */ | |
| 250 PRThread *idle_thread; /* user-level idle thread for this CPUThread */ | |
| 251 | |
| 252 PRIntervalTime last_clock; /* the last time we went into | |
| 253 * _PR_ClockInterrupt() on this CPU | |
| 254 */ | |
| 255 | |
| 256 _PRCPUQueue *queue; | |
| 257 | |
| 258 _MDCPU md; | |
| 259 }; | |
| 260 | |
| 261 typedef struct _PRInterruptTable { | |
| 262 const char *name; | |
| 263 PRUintn missed_bit; | |
| 264 void (*handler)(void); | |
| 265 } _PRInterruptTable; | |
| 266 | |
| 267 #define _PR_CPU_PTR(_qp) \ | |
| 268 ((_PRCPU*) ((char*) (_qp) - offsetof(_PRCPU,links))) | |
| 269 | |
| 270 #if !defined(IRIX) && !defined(WIN32) && !defined(XP_OS2) \ | |
| 271 && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)) | |
| 272 #define _MD_GET_ATTACHED_THREAD() (_PR_MD_CURRENT_THREAD()) | |
| 273 #endif | |
| 274 | |
| 275 #ifdef _PR_LOCAL_THREADS_ONLY | |
| 276 | |
| 277 NSPR_API(struct _PRCPU *) _pr_currentCPU; | |
| 278 NSPR_API(PRThread *) _pr_currentThread; | |
| 279 NSPR_API(PRThread *) _pr_lastThread; | |
| 280 NSPR_API(PRInt32) _pr_intsOff; | |
| 281 | |
| 282 #define _MD_CURRENT_CPU() (_pr_currentCPU) | |
| 283 #define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = (_cpu)) | |
| 284 #define _MD_CURRENT_THREAD() (_pr_currentThread) | |
| 285 #define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread)) | |
| 286 #define _MD_LAST_THREAD() (_pr_lastThread) | |
| 287 #define _MD_SET_LAST_THREAD(t) (_pr_lastThread = t) | |
| 288 | |
| 289 #define _MD_GET_INTSOFF() (_pr_intsOff) | |
| 290 #define _MD_SET_INTSOFF(_val) (_pr_intsOff = _val) | |
| 291 | |
| 292 | |
| 293 /* The unbalanced curly braces in these two macros are intentional */ | |
| 294 #define _PR_LOCK_HEAP() { PRIntn _is; if (_pr_currentCPU) _PR_INTSOFF(_is); | |
| 295 #define _PR_UNLOCK_HEAP() if (_pr_currentCPU) _PR_INTSON(_is); } | |
| 296 | |
| 297 #endif /* _PR_LOCAL_THREADS_ONLY */ | |
| 298 | |
| 299 extern PRInt32 _native_threads_only; | |
| 300 | |
| 301 #if defined(_PR_GLOBAL_THREADS_ONLY) | |
| 302 | |
| 303 #define _MD_GET_INTSOFF() 0 | |
| 304 #define _MD_SET_INTSOFF(_val) | |
| 305 #define _PR_INTSOFF(_is) | |
| 306 #define _PR_FAST_INTSON(_is) | |
| 307 #define _PR_INTSON(_is) | |
| 308 #define _PR_THREAD_LOCK(_thread) | |
| 309 #define _PR_THREAD_UNLOCK(_thread) | |
| 310 #define _PR_RUNQ_LOCK(cpu) | |
| 311 #define _PR_RUNQ_UNLOCK(cpu) | |
| 312 #define _PR_SLEEPQ_LOCK(thread) | |
| 313 #define _PR_SLEEPQ_UNLOCK(thread) | |
| 314 #define _PR_MISCQ_LOCK(thread) | |
| 315 #define _PR_MISCQ_UNLOCK(thread) | |
| 316 #define _PR_CPU_LIST_LOCK() | |
| 317 #define _PR_CPU_LIST_UNLOCK() | |
| 318 | |
| 319 #define _PR_ADD_RUNQ(_thread, _cpu, _pri) | |
| 320 #define _PR_DEL_RUNQ(_thread) | |
| 321 #define _PR_ADD_SLEEPQ(_thread, _timeout) | |
| 322 #define _PR_DEL_SLEEPQ(_thread, _propogate) | |
| 323 #define _PR_ADD_JOINQ(_thread, _cpu) | |
| 324 #define _PR_DEL_JOINQ(_thread) | |
| 325 #define _PR_ADD_SUSPENDQ(_thread, _cpu) | |
| 326 #define _PR_DEL_SUSPENDQ(_thread) | |
| 327 | |
| 328 #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) | |
| 329 | |
| 330 #define _PR_IS_NATIVE_THREAD(thread) 1 | |
| 331 #define _PR_IS_NATIVE_THREAD_SUPPORTED() 1 | |
| 332 | |
| 333 #else | |
| 334 | |
| 335 #define _PR_INTSOFF(_is) \ | |
| 336 PR_BEGIN_MACRO \ | |
| 337 (_is) = _PR_MD_GET_INTSOFF(); \ | |
| 338 _PR_MD_SET_INTSOFF(1); \ | |
| 339 PR_END_MACRO | |
| 340 | |
| 341 #define _PR_FAST_INTSON(_is) \ | |
| 342 PR_BEGIN_MACRO \ | |
| 343 _PR_MD_SET_INTSOFF(_is); \ | |
| 344 PR_END_MACRO | |
| 345 | |
| 346 #define _PR_INTSON(_is) \ | |
| 347 PR_BEGIN_MACRO \ | |
| 348 if ((_is == 0) && (_PR_MD_CURRENT_CPU())->u.bits) \ | |
| 349 _PR_IntsOn((_PR_MD_CURRENT_CPU())); \ | |
| 350 _PR_MD_SET_INTSOFF(_is); \ | |
| 351 PR_END_MACRO | |
| 352 | |
| 353 #ifdef _PR_LOCAL_THREADS_ONLY | |
| 354 | |
| 355 #define _PR_IS_NATIVE_THREAD(thread) 0 | |
| 356 #define _PR_THREAD_LOCK(_thread) | |
| 357 #define _PR_THREAD_UNLOCK(_thread) | |
| 358 #define _PR_RUNQ_LOCK(cpu) | |
| 359 #define _PR_RUNQ_UNLOCK(cpu) | |
| 360 #define _PR_SLEEPQ_LOCK(thread) | |
| 361 #define _PR_SLEEPQ_UNLOCK(thread) | |
| 362 #define _PR_MISCQ_LOCK(thread) | |
| 363 #define _PR_MISCQ_UNLOCK(thread) | |
| 364 #define _PR_CPU_LIST_LOCK() | |
| 365 #define _PR_CPU_LIST_UNLOCK() | |
| 366 | |
| 367 #define _PR_ADD_RUNQ(_thread, _cpu, _pri) \ | |
| 368 PR_BEGIN_MACRO \ | |
| 369 PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \ | |
| 370 _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \ | |
| 371 PR_END_MACRO | |
| 372 | |
| 373 #define _PR_DEL_RUNQ(_thread) \ | |
| 374 PR_BEGIN_MACRO \ | |
| 375 _PRCPU *_cpu = _thread->cpu; \ | |
| 376 PRInt32 _pri = _thread->priority; \ | |
| 377 PR_REMOVE_LINK(&(_thread)->links); \ | |
| 378 if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \ | |
| 379 _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \ | |
| 380 PR_END_MACRO | |
| 381 | |
| 382 #define _PR_ADD_SLEEPQ(_thread, _timeout) \ | |
| 383 _PR_AddSleepQ(_thread, _timeout); | |
| 384 | |
| 385 #define _PR_DEL_SLEEPQ(_thread, _propogate) \ | |
| 386 _PR_DelSleepQ(_thread, _propogate); | |
| 387 | |
| 388 #define _PR_ADD_JOINQ(_thread, _cpu) \ | |
| 389 PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu)); | |
| 390 | |
| 391 #define _PR_DEL_JOINQ(_thread) \ | |
| 392 PR_REMOVE_LINK(&(_thread)->links); | |
| 393 | |
| 394 #define _PR_ADD_SUSPENDQ(_thread, _cpu) \ | |
| 395 PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu)); | |
| 396 | |
| 397 #define _PR_DEL_SUSPENDQ(_thread) \ | |
| 398 PR_REMOVE_LINK(&(_thread)->links); | |
| 399 | |
| 400 #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) | |
| 401 | |
| 402 #define _PR_IS_NATIVE_THREAD_SUPPORTED() 0 | |
| 403 | |
| 404 #else /* _PR_LOCAL_THREADS_ONLY */ | |
| 405 | |
| 406 /* These are for the "combined" thread model */ | |
| 407 | |
| 408 #define _PR_THREAD_LOCK(_thread) \ | |
| 409 _PR_MD_LOCK(&(_thread)->threadLock); | |
| 410 | |
| 411 #define _PR_THREAD_UNLOCK(_thread) \ | |
| 412 _PR_MD_UNLOCK(&(_thread)->threadLock); | |
| 413 | |
| 414 #define _PR_RUNQ_LOCK(_cpu) \ | |
| 415 PR_BEGIN_MACRO \ | |
| 416 _PR_MD_LOCK(&(_cpu)->queue->runQLock );\ | |
| 417 PR_END_MACRO | |
| 418 | |
| 419 #define _PR_RUNQ_UNLOCK(_cpu) \ | |
| 420 PR_BEGIN_MACRO \ | |
| 421 _PR_MD_UNLOCK(&(_cpu)->queue->runQLock );\ | |
| 422 PR_END_MACRO | |
| 423 | |
| 424 #define _PR_SLEEPQ_LOCK(_cpu) \ | |
| 425 _PR_MD_LOCK(&(_cpu)->queue->sleepQLock ); | |
| 426 | |
| 427 #define _PR_SLEEPQ_UNLOCK(_cpu) \ | |
| 428 _PR_MD_UNLOCK(&(_cpu)->queue->sleepQLock ); | |
| 429 | |
| 430 #define _PR_MISCQ_LOCK(_cpu) \ | |
| 431 _PR_MD_LOCK(&(_cpu)->queue->miscQLock ); | |
| 432 | |
| 433 #define _PR_MISCQ_UNLOCK(_cpu) \ | |
| 434 _PR_MD_UNLOCK(&(_cpu)->queue->miscQLock ); | |
| 435 | |
| 436 #define _PR_CPU_LIST_LOCK() _PR_MD_LOCK(&_pr_cpuLock) | |
| 437 #define _PR_CPU_LIST_UNLOCK() _PR_MD_UNLOCK(&_pr_cpuLock) | |
| 438 | |
| 439 #define QUEUE_RUN 0x1 | |
| 440 #define QUEUE_SLEEP 0x2 | |
| 441 #define QUEUE_JOIN 0x4 | |
| 442 #define QUEUE_SUSPEND 0x8 | |
| 443 #define QUEUE_LOCK 0x10 | |
| 444 | |
| 445 #define _PR_ADD_RUNQ(_thread, _cpu, _pri) \ | |
| 446 PR_BEGIN_MACRO \ | |
| 447 PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \ | |
| 448 _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \ | |
| 449 PR_ASSERT((_thread)->queueCount == 0); \ | |
| 450 (_thread)->queueCount = QUEUE_RUN; \ | |
| 451 PR_END_MACRO | |
| 452 | |
| 453 #define _PR_DEL_RUNQ(_thread) \ | |
| 454 PR_BEGIN_MACRO \ | |
| 455 _PRCPU *_cpu = _thread->cpu; \ | |
| 456 PRInt32 _pri = _thread->priority; \ | |
| 457 PR_REMOVE_LINK(&(_thread)->links); \ | |
| 458 if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \ | |
| 459 _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \ | |
| 460 PR_ASSERT((_thread)->queueCount == QUEUE_RUN);\ | |
| 461 (_thread)->queueCount = 0; \ | |
| 462 PR_END_MACRO | |
| 463 | |
| 464 #define _PR_ADD_SLEEPQ(_thread, _timeout) \ | |
| 465 PR_ASSERT((_thread)->queueCount == 0); \ | |
| 466 (_thread)->queueCount = QUEUE_SLEEP; \ | |
| 467 _PR_AddSleepQ(_thread, _timeout); | |
| 468 | |
| 469 #define _PR_DEL_SLEEPQ(_thread, _propogate) \ | |
| 470 PR_ASSERT((_thread)->queueCount == QUEUE_SLEEP);\ | |
| 471 (_thread)->queueCount = 0; \ | |
| 472 _PR_DelSleepQ(_thread, _propogate); | |
| 473 | |
| 474 #define _PR_ADD_JOINQ(_thread, _cpu) \ | |
| 475 PR_ASSERT((_thread)->queueCount == 0); \ | |
| 476 (_thread)->queueCount = QUEUE_JOIN; \ | |
| 477 PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu)); | |
| 478 | |
| 479 #define _PR_DEL_JOINQ(_thread) \ | |
| 480 PR_ASSERT((_thread)->queueCount == QUEUE_JOIN);\ | |
| 481 (_thread)->queueCount = 0; \ | |
| 482 PR_REMOVE_LINK(&(_thread)->links); | |
| 483 | |
| 484 #define _PR_ADD_SUSPENDQ(_thread, _cpu) \ | |
| 485 PR_ASSERT((_thread)->queueCount == 0); \ | |
| 486 (_thread)->queueCount = QUEUE_SUSPEND; \ | |
| 487 PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu)); | |
| 488 | |
| 489 #define _PR_DEL_SUSPENDQ(_thread) \ | |
| 490 PR_ASSERT((_thread)->queueCount == QUEUE_SUSPEND);\ | |
| 491 (_thread)->queueCount = 0; \ | |
| 492 PR_REMOVE_LINK(&(_thread)->links); | |
| 493 | |
| 494 #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) \ | |
| 495 (_thread)->cpu = (_newCPU); | |
| 496 | |
| 497 #define _PR_IS_NATIVE_THREAD(thread) (thread->flags & _PR_GLOBAL_SCOPE) | |
| 498 #define _PR_IS_NATIVE_THREAD_SUPPORTED() 1 | |
| 499 | |
| 500 #endif /* _PR_LOCAL_THREADS_ONLY */ | |
| 501 | |
| 502 #endif /* _PR_GLOBAL_THREADS_ONLY */ | |
| 503 | |
| 504 #define _PR_SET_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 1 | |
| 505 #define _PR_CLEAR_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 0 | |
| 506 | |
| 507 extern _PRInterruptTable _pr_interruptTable[]; | |
| 508 | |
| 509 /* Bits for _pr_interruptState.u.missed[0,1] */ | |
| 510 #define _PR_MISSED_CLOCK 0x1 | |
| 511 #define _PR_MISSED_IO 0x2 | |
| 512 #define _PR_MISSED_CHILD 0x4 | |
| 513 | |
| 514 extern void _PR_IntsOn(_PRCPU *cpu); | |
| 515 | |
| 516 NSPR_API(void) _PR_WakeupCPU(void); | |
| 517 NSPR_API(void) _PR_PauseCPU(void); | |
| 518 | |
| 519 /************************************************************************/ | |
| 520 | |
| 521 #define _PR_LOCK_LOCK(_lock) \ | |
| 522 _PR_MD_LOCK(&(_lock)->ilock); | |
| 523 #define _PR_LOCK_UNLOCK(_lock) \ | |
| 524 _PR_MD_UNLOCK(&(_lock)->ilock); | |
| 525 | |
| 526 extern void _PR_UnblockLockWaiter(PRLock *lock); | |
| 527 | |
| 528 #define _PR_LOCK_PTR(_qp) \ | |
| 529 ((PRLock*) ((char*) (_qp) - offsetof(PRLock,links))) | |
| 530 | |
| 531 /************************************************************************/ | |
| 532 | |
| 533 #define _PR_CVAR_LOCK(_cvar) \ | |
| 534 _PR_MD_LOCK(&(_cvar)->ilock); | |
| 535 #define _PR_CVAR_UNLOCK(_cvar) \ | |
| 536 _PR_MD_UNLOCK(&(_cvar)->ilock); | |
| 537 | |
| 538 extern PRStatus _PR_WaitCondVar( | |
| 539 PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout); | |
| 540 extern PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen)
; | |
| 541 | |
| 542 NSPR_API(void) _PR_Notify(PRMonitor *mon, PRBool all, PRBool sticky); | |
| 543 | |
| 544 /* PRThread.flags */ | |
| 545 #define _PR_SYSTEM 0x01 | |
| 546 #define _PR_INTERRUPT 0x02 | |
| 547 #define _PR_ATTACHED 0x04 /* created via PR_AttachThread */ | |
| 548 #define _PR_PRIMORDIAL 0x08 /* the thread that called PR_Init */ | |
| 549 #define _PR_ON_SLEEPQ 0x10 /* thread is on the sleepQ */ | |
| 550 #define _PR_ON_PAUSEQ 0x20 /* thread is on the pauseQ */ | |
| 551 #define _PR_SUSPENDING 0x40 /* thread wants to suspend */ | |
| 552 #define _PR_GLOBAL_SCOPE 0x80 /* thread is global scope */ | |
| 553 #define _PR_IDLE_THREAD 0x200 /* this is an idle thread */ | |
| 554 #define _PR_GCABLE_THREAD 0x400 /* this is a collectable thread */ | |
| 555 #define _PR_BOUND_THREAD 0x800 /* a bound thread */ | |
| 556 #define _PR_INTERRUPT_BLOCKED 0x1000 /* interrupts blocked */ | |
| 557 | |
| 558 /* PRThread.state */ | |
| 559 #define _PR_UNBORN 0 | |
| 560 #define _PR_RUNNABLE 1 | |
| 561 #define _PR_RUNNING 2 | |
| 562 #define _PR_LOCK_WAIT 3 | |
| 563 #define _PR_COND_WAIT 4 | |
| 564 #define _PR_JOIN_WAIT 5 | |
| 565 #define _PR_IO_WAIT 6 | |
| 566 #define _PR_SUSPENDED 7 | |
| 567 #define _PR_DEAD_STATE 8 /* for debugging */ | |
| 568 | |
| 569 /* PRThreadStack.flags */ | |
| 570 #define _PR_STACK_VM 0x1 /* using vm instead of malloc */ | |
| 571 #define _PR_STACK_MAPPED 0x2 /* vm is mapped */ | |
| 572 #define _PR_STACK_PRIMORDIAL 0x4 /* stack for primordial thread */ | |
| 573 | |
| 574 /* | |
| 575 ** If the default stcksize from the client is zero, we need to pick a machine | |
| 576 ** dependent value. This is only for standard user threads. For custom threads
, | |
| 577 ** 0 has a special meaning. | |
| 578 ** Adjust stackSize. Round up to a page boundary. | |
| 579 */ | |
| 580 | |
| 581 #ifndef _MD_MINIMUM_STACK_SIZE | |
| 582 #define _MD_MINIMUM_STACK_SIZE 0 | |
| 583 #endif | |
| 584 | |
| 585 #if (!defined(HAVE_CUSTOM_USER_THREADS)) | |
| 586 #define _PR_ADJUST_STACKSIZE(stackSize) \ | |
| 587 PR_BEGIN_MACRO \ | |
| 588 if (stackSize == 0) \ | |
| 589 stackSize = _MD_DEFAULT_STACK_SIZE; \ | |
| 590 if (stackSize < _MD_MINIMUM_STACK_SIZE) \ | |
| 591 stackSize = _MD_MINIMUM_STACK_SIZE; \ | |
| 592 stackSize = (stackSize + (1 << _pr_pageShift) - 1) >> _pr_pageShift; \ | |
| 593 stackSize <<= _pr_pageShift; \ | |
| 594 PR_END_MACRO | |
| 595 #else | |
| 596 #define _PR_ADJUST_STACKSIZE(stackSize) | |
| 597 #endif | |
| 598 | |
| 599 #define _PR_IS_GCABLE_THREAD(thr) ((thr)->flags & _PR_GCABLE_THREAD) | |
| 600 | |
| 601 #define _PR_PENDING_INTERRUPT(thr) \ | |
| 602 (!((thr)->flags & _PR_INTERRUPT_BLOCKED) && ((thr)->flags & _PR_
INTERRUPT)) | |
| 603 #define _PR_THREAD_BLOCK_INTERRUPT(thr) \ | |
| 604 (thr->flags |= _PR_INTERRUPT_BLOCKED) | |
| 605 #define _PR_THREAD_UNBLOCK_INTERRUPT(thr) \ | |
| 606 (thr->flags &= ~_PR_INTERRUPT_BLOCKED) | |
| 607 | |
| 608 #define _PR_THREAD_PTR(_qp) \ | |
| 609 ((PRThread*) ((char*) (_qp) - offsetof(PRThread,links))) | |
| 610 | |
| 611 #define _PR_ACTIVE_THREAD_PTR(_qp) \ | |
| 612 ((PRThread*) ((char*) (_qp) - offsetof(PRThread,active))) | |
| 613 | |
| 614 #define _PR_THREAD_CONDQ_PTR(_qp) \ | |
| 615 ((PRThread*) ((char*) (_qp) - offsetof(PRThread,waitQLinks))) | |
| 616 | |
| 617 #define _PR_THREAD_MD_TO_PTR(_md) \ | |
| 618 ((PRThread*) ((char*) (_md) - offsetof(PRThread,md))) | |
| 619 | |
| 620 #define _PR_THREAD_STACK_TO_PTR(_stack) \ | |
| 621 ((PRThread*) (_stack->thr)) | |
| 622 | |
| 623 extern PRCList _pr_active_local_threadQ; | |
| 624 extern PRCList _pr_active_global_threadQ; | |
| 625 extern PRCList _pr_cpuQ; | |
| 626 extern _MDLock _pr_cpuLock; | |
| 627 extern PRInt32 _pr_md_idle_cpus; | |
| 628 | |
| 629 #define _PR_ACTIVE_LOCAL_THREADQ() _pr_active_local_threadQ | |
| 630 #define _PR_ACTIVE_GLOBAL_THREADQ() _pr_active_global_threadQ | |
| 631 #define _PR_CPUQ() _pr_cpuQ | |
| 632 #define _PR_RUNQ(_cpu) ((_cpu)->queue->runQ) | |
| 633 #define _PR_RUNQREADYMASK(_cpu) ((_cpu)->queue->runQReadyMask) | |
| 634 #define _PR_SLEEPQ(_cpu) ((_cpu)->queue->sleepQ) | |
| 635 #define _PR_SLEEPQMAX(_cpu) ((_cpu)->queue->sleepQmax) | |
| 636 #define _PR_PAUSEQ(_cpu) ((_cpu)->queue->pauseQ) | |
| 637 #define _PR_SUSPENDQ(_cpu) ((_cpu)->queue->suspendQ) | |
| 638 #define _PR_WAITINGTOJOINQ(_cpu) ((_cpu)->queue->waitingToJoinQ) | |
| 639 | |
| 640 extern PRUint32 _pr_recycleThreads; /* Flag for behavior on thread cleanup */ | |
| 641 extern PRLock *_pr_deadQLock; | |
| 642 extern PRUint32 _pr_numNativeDead; | |
| 643 extern PRUint32 _pr_numUserDead; | |
| 644 extern PRCList _pr_deadNativeQ; | |
| 645 extern PRCList _pr_deadUserQ; | |
| 646 #define _PR_DEADNATIVEQ _pr_deadNativeQ | |
| 647 #define _PR_DEADUSERQ _pr_deadUserQ | |
| 648 #define _PR_DEADQ_LOCK PR_Lock(_pr_deadQLock); | |
| 649 #define _PR_DEADQ_UNLOCK PR_Unlock(_pr_deadQLock); | |
| 650 #define _PR_INC_DEADNATIVE (_pr_numNativeDead++) | |
| 651 #define _PR_DEC_DEADNATIVE (_pr_numNativeDead--) | |
| 652 #define _PR_NUM_DEADNATIVE (_pr_numNativeDead) | |
| 653 #define _PR_INC_DEADUSER (_pr_numUserDead++) | |
| 654 #define _PR_DEC_DEADUSER (_pr_numUserDead--) | |
| 655 #define _PR_NUM_DEADUSER (_pr_numUserDead) | |
| 656 | |
| 657 extern PRUint32 _pr_utid; | |
| 658 | |
| 659 extern struct _PRCPU *_pr_primordialCPU; | |
| 660 | |
| 661 extern PRLock *_pr_activeLock; /* lock for userActive and systemActive
*/ | |
| 662 extern PRInt32 _pr_userActive; /* number of active user threads */ | |
| 663 extern PRInt32 _pr_systemActive; /* number of active system threads */ | |
| 664 extern PRInt32 _pr_primordialExitCount; /* number of user threads left | |
| 665 * before the primordial thread | |
| 666 * can exit. */ | |
| 667 extern PRCondVar *_pr_primordialExitCVar; /* the condition variable for | |
| 668 * notifying the primordial thread | |
| 669 * when all other user threads | |
| 670 * have terminated. */ | |
| 671 | |
| 672 extern PRUintn _pr_maxPTDs; | |
| 673 | |
| 674 extern PRLock *_pr_terminationCVLock; | |
| 675 | |
| 676 /************************************************************************* | |
| 677 * Internal routines either called by PR itself or from machine-dependent * | |
| 678 * code. * | |
| 679 *************************************************************************/ | |
| 680 | |
| 681 extern void _PR_ClockInterrupt(void); | |
| 682 | |
| 683 extern void _PR_Schedule(void); | |
| 684 extern void _PR_SetThreadPriority( | |
| 685 PRThread* thread, PRThreadPriority priority); | |
| 686 | |
| 687 /*********************************************************************** | |
| 688 ** FUNCTION: _PR_NewSegment() | |
| 689 ** DESCRIPTION: | |
| 690 ** Allocate a memory segment. The "size" value is rounded up to the | |
| 691 ** native system page size and a page aligned portion of memory is | |
| 692 ** returned. This memory is not part of the malloc heap. If "vaddr" is | |
| 693 ** not NULL then PR tries to allocate the segment at the desired virtual | |
| 694 ** address. | |
| 695 ** INPUTS: size: size of the desired memory segment | |
| 696 ** vaddr: address at which the newly aquired segment is to be | |
| 697 ** mapped into memory. | |
| 698 ** OUTPUTS: a memory segment is allocated, a PRSegment is allocated | |
| 699 ** RETURN: pointer to PRSegment | |
| 700 ***********************************************************************/ | |
| 701 extern PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr); | |
| 702 | |
| 703 /*********************************************************************** | |
| 704 ** FUNCTION: _PR_DestroySegment() | |
| 705 ** DESCRIPTION: | |
| 706 ** The memory segment and the PRSegment are freed | |
| 707 ** INPUTS: seg: pointer to PRSegment to be freed | |
| 708 ** OUTPUTS: the the PRSegment and its associated memory segment are freed | |
| 709 ** RETURN: void | |
| 710 ***********************************************************************/ | |
| 711 extern void _PR_DestroySegment(PRSegment *seg); | |
| 712 | |
| 713 extern PRThreadStack * _PR_NewStack(PRUint32 stackSize); | |
| 714 extern void _PR_FreeStack(PRThreadStack *stack); | |
| 715 extern PRBool _PR_NotifyThread (PRThread *thread, PRThread *me); | |
| 716 extern void _PR_NotifyLockedThread (PRThread *thread); | |
| 717 | |
| 718 NSPR_API(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout); | |
| 719 NSPR_API(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time); | |
| 720 | |
| 721 extern void _PR_AddThreadToRunQ(PRThread *me, PRThread *thread); | |
| 722 | |
| 723 NSPR_API(PRThread*) _PR_CreateThread(PRThreadType type, | |
| 724 void (*start)(void *arg), | |
| 725 void *arg, | |
| 726 PRThreadPriority priority, | |
| 727 PRThreadScope scope, | |
| 728 PRThreadState state, | |
| 729 PRUint32 stackSize, | |
| 730 PRUint32 flags); | |
| 731 | |
| 732 extern void _PR_NativeDestroyThread(PRThread *thread); | |
| 733 extern void _PR_UserDestroyThread(PRThread *thread); | |
| 734 | |
| 735 extern PRThread* _PRI_AttachThread( | |
| 736 PRThreadType type, PRThreadPriority priority, | |
| 737 PRThreadStack *stack, PRUint32 flags); | |
| 738 | |
| 739 extern void _PRI_DetachThread(void); | |
| 740 | |
| 741 | |
| 742 #define _PR_IO_PENDING(_thread) ((_thread)->io_pending) | |
| 743 | |
| 744 NSPR_API(void) _PR_MD_INIT_CPUS(); | |
| 745 #define _PR_MD_INIT_CPUS _MD_INIT_CPUS | |
| 746 | |
| 747 NSPR_API(void) _PR_MD_WAKEUP_CPUS(); | |
| 748 #define _PR_MD_WAKEUP_CPUS _MD_WAKEUP_CPUS | |
| 749 | |
| 750 /* Interrupts related */ | |
| 751 | |
| 752 NSPR_API(void) _PR_MD_START_INTERRUPTS(void); | |
| 753 #define _PR_MD_START_INTERRUPTS _MD_START_INTERRUPTS | |
| 754 | |
| 755 NSPR_API(void) _PR_MD_STOP_INTERRUPTS(void); | |
| 756 #define _PR_MD_STOP_INTERRUPTS _MD_STOP_INTERRUPTS | |
| 757 | |
| 758 NSPR_API(void) _PR_MD_ENABLE_CLOCK_INTERRUPTS(void); | |
| 759 #define _PR_MD_ENABLE_CLOCK_INTERRUPTS _MD_ENABLE_CLOCK_INTERRUPTS | |
| 760 | |
| 761 NSPR_API(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void); | |
| 762 #define _PR_MD_DISABLE_CLOCK_INTERRUPTS _MD_DISABLE_CLOCK_INTERRUPTS | |
| 763 | |
| 764 NSPR_API(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void); | |
| 765 #define _PR_MD_BLOCK_CLOCK_INTERRUPTS _MD_BLOCK_CLOCK_INTERRUPTS | |
| 766 | |
| 767 NSPR_API(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void); | |
| 768 #define _PR_MD_UNBLOCK_CLOCK_INTERRUPTS _MD_UNBLOCK_CLOCK_INTERRUPTS | |
| 769 | |
| 770 /* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and | |
| 771 * awaken a thread which is waiting on a lock or cvar. | |
| 772 */ | |
| 773 extern PRStatus _PR_MD_WAIT(PRThread *, PRIntervalTime timeout); | |
| 774 #define _PR_MD_WAIT _MD_WAIT | |
| 775 | |
| 776 extern PRStatus _PR_MD_WAKEUP_WAITER(PRThread *); | |
| 777 #define _PR_MD_WAKEUP_WAITER _MD_WAKEUP_WAITER | |
| 778 | |
| 779 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ | |
| 780 NSPR_API(void) _PR_MD_CLOCK_INTERRUPT(void); | |
| 781 #define _PR_MD_CLOCK_INTERRUPT _MD_CLOCK_INTERRUPT | |
| 782 #endif | |
| 783 | |
| 784 /* Stack debugging */ | |
| 785 NSPR_API(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone); | |
| 786 #define _PR_MD_INIT_STACK _MD_INIT_STACK | |
| 787 | |
| 788 NSPR_API(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts); | |
| 789 #define _PR_MD_CLEAR_STACK _MD_CLEAR_STACK | |
| 790 | |
| 791 /* CPU related */ | |
| 792 NSPR_API(PRInt32) _PR_MD_GET_INTSOFF(void); | |
| 793 #define _PR_MD_GET_INTSOFF _MD_GET_INTSOFF | |
| 794 | |
| 795 NSPR_API(void) _PR_MD_SET_INTSOFF(PRInt32 _val); | |
| 796 #define _PR_MD_SET_INTSOFF _MD_SET_INTSOFF | |
| 797 | |
| 798 NSPR_API(_PRCPU*) _PR_MD_CURRENT_CPU(void); | |
| 799 #define _PR_MD_CURRENT_CPU _MD_CURRENT_CPU | |
| 800 | |
| 801 NSPR_API(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu); | |
| 802 #define _PR_MD_SET_CURRENT_CPU _MD_SET_CURRENT_CPU | |
| 803 | |
| 804 NSPR_API(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu); | |
| 805 #define _PR_MD_INIT_RUNNING_CPU _MD_INIT_RUNNING_CPU | |
| 806 | |
| 807 /* | |
| 808 * Returns the number of threads awoken or 0 if a timeout occurred; | |
| 809 */ | |
| 810 extern PRInt32 _PR_MD_PAUSE_CPU(PRIntervalTime timeout); | |
| 811 #define _PR_MD_PAUSE_CPU _MD_PAUSE_CPU | |
| 812 | |
| 813 extern void _PR_MD_CLEANUP_BEFORE_EXIT(void); | |
| 814 #define _PR_MD_CLEANUP_BEFORE_EXIT _MD_CLEANUP_BEFORE_EXIT | |
| 815 | |
| 816 extern void _PR_MD_EXIT(PRIntn status); | |
| 817 #define _PR_MD_EXIT _MD_EXIT | |
| 818 | |
| 819 /* Locks related */ | |
| 820 | |
| 821 NSPR_API(void) _PR_MD_INIT_LOCKS(void); | |
| 822 #define _PR_MD_INIT_LOCKS _MD_INIT_LOCKS | |
| 823 | |
| 824 NSPR_API(PRStatus) _PR_MD_NEW_LOCK(_MDLock *md); | |
| 825 #define _PR_MD_NEW_LOCK _MD_NEW_LOCK | |
| 826 | |
| 827 NSPR_API(void) _PR_MD_FREE_LOCK(_MDLock *md); | |
| 828 #define _PR_MD_FREE_LOCK _MD_FREE_LOCK | |
| 829 | |
| 830 NSPR_API(void) _PR_MD_LOCK(_MDLock *md); | |
| 831 #define _PR_MD_LOCK _MD_LOCK | |
| 832 | |
| 833 /* Return 0 on success, a nonzero value on failure. */ | |
| 834 NSPR_API(PRIntn) _PR_MD_TEST_AND_LOCK(_MDLock *md); | |
| 835 #define _PR_MD_TEST_AND_LOCK _MD_TEST_AND_LOCK | |
| 836 | |
| 837 NSPR_API(void) _PR_MD_UNLOCK(_MDLock *md); | |
| 838 #define _PR_MD_UNLOCK _MD_UNLOCK | |
| 839 | |
| 840 NSPR_API(void) _PR_MD_IOQ_LOCK(void); | |
| 841 #define _PR_MD_IOQ_LOCK _MD_IOQ_LOCK | |
| 842 | |
| 843 NSPR_API(void) _PR_MD_IOQ_UNLOCK(void); | |
| 844 #define _PR_MD_IOQ_UNLOCK _MD_IOQ_UNLOCK | |
| 845 | |
| 846 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ | |
| 847 /* Semaphore related -- only for native threads */ | |
| 848 #ifdef HAVE_CVAR_BUILT_ON_SEM | |
| 849 NSPR_API(void) _PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value); | |
| 850 #define _PR_MD_NEW_SEM _MD_NEW_SEM | |
| 851 | |
| 852 NSPR_API(void) _PR_MD_DESTROY_SEM(_MDSemaphore *md); | |
| 853 #define _PR_MD_DESTROY_SEM _MD_DESTROY_SEM | |
| 854 | |
| 855 NSPR_API(PRStatus) _PR_MD_TIMED_WAIT_SEM( | |
| 856 _MDSemaphore *md, PRIntervalTime timeout); | |
| 857 #define _PR_MD_TIMED_WAIT_SEM _MD_TIMED_WAIT_SEM | |
| 858 | |
| 859 NSPR_API(PRStatus) _PR_MD_WAIT_SEM(_MDSemaphore *md); | |
| 860 #define _PR_MD_WAIT_SEM _MD_WAIT_SEM | |
| 861 | |
| 862 NSPR_API(void) _PR_MD_POST_SEM(_MDSemaphore *md); | |
| 863 #define _PR_MD_POST_SEM _MD_POST_SEM | |
| 864 #endif /* HAVE_CVAR_BUILT_ON_SEM */ | |
| 865 | |
| 866 #endif | |
| 867 | |
| 868 /* Condition Variables related -- only for native threads */ | |
| 869 | |
| 870 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ | |
| 871 NSPR_API(PRInt32) _PR_MD_NEW_CV(_MDCVar *md); | |
| 872 #define _PR_MD_NEW_CV _MD_NEW_CV | |
| 873 | |
| 874 NSPR_API(void) _PR_MD_FREE_CV(_MDCVar *md); | |
| 875 #define _PR_MD_FREE_CV _MD_FREE_CV | |
| 876 | |
| 877 NSPR_API(void) _PR_MD_WAIT_CV( | |
| 878 _MDCVar *mdCVar,_MDLock *mdLock,PRIntervalTime timeout); | |
| 879 #define _PR_MD_WAIT_CV _MD_WAIT_CV | |
| 880 | |
| 881 NSPR_API(void) _PR_MD_NOTIFY_CV(_MDCVar *md, _MDLock *lock); | |
| 882 #define _PR_MD_NOTIFY_CV _MD_NOTIFY_CV | |
| 883 | |
| 884 NSPR_API(void) _PR_MD_NOTIFYALL_CV(_MDCVar *md, _MDLock *lock); | |
| 885 #define _PR_MD_NOTIFYALL_CV _MD_NOTIFYALL_CV | |
| 886 #endif /* _PR_LOCAL_THREADS_ONLY */ | |
| 887 | |
| 888 /* Threads related */ | |
| 889 NSPR_API(PRThread*) _PR_MD_CURRENT_THREAD(void); | |
| 890 #define _PR_MD_CURRENT_THREAD _MD_CURRENT_THREAD | |
| 891 | |
| 892 NSPR_API(PRThread*) _PR_MD_GET_ATTACHED_THREAD(void); | |
| 893 #define _PR_MD_GET_ATTACHED_THREAD _MD_GET_ATTACHED_THREAD | |
| 894 | |
| 895 NSPR_API(PRThread*) _PR_MD_LAST_THREAD(void); | |
| 896 #define _PR_MD_LAST_THREAD _MD_LAST_THREAD | |
| 897 | |
| 898 NSPR_API(void) _PR_MD_SET_CURRENT_THREAD(PRThread *thread); | |
| 899 #define _PR_MD_SET_CURRENT_THREAD _MD_SET_CURRENT_THREAD | |
| 900 | |
| 901 NSPR_API(void) _PR_MD_SET_LAST_THREAD(PRThread *thread); | |
| 902 #define _PR_MD_SET_LAST_THREAD _MD_SET_LAST_THREAD | |
| 903 | |
| 904 extern PRStatus _PR_MD_INIT_THREAD(PRThread *thread); | |
| 905 #define _PR_MD_INIT_THREAD _MD_INIT_THREAD | |
| 906 | |
| 907 extern void _PR_MD_EXIT_THREAD(PRThread *thread); | |
| 908 #define _PR_MD_EXIT_THREAD _MD_EXIT_THREAD | |
| 909 | |
| 910 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ | |
| 911 | |
| 912 NSPR_API(PRStatus) _PR_MD_INIT_ATTACHED_THREAD(PRThread *thread); | |
| 913 #define _PR_MD_INIT_ATTACHED_THREAD _MD_INIT_ATTACHED_THREAD | |
| 914 | |
| 915 extern void _PR_MD_SUSPEND_THREAD(PRThread *thread); | |
| 916 #define _PR_MD_SUSPEND_THREAD _MD_SUSPEND_THREAD | |
| 917 | |
| 918 extern void _PR_MD_RESUME_THREAD(PRThread *thread); | |
| 919 #define _PR_MD_RESUME_THREAD _MD_RESUME_THREAD | |
| 920 | |
| 921 extern void _PR_MD_SUSPEND_CPU(_PRCPU *cpu); | |
| 922 #define _PR_MD_SUSPEND_CPU _MD_SUSPEND_CPU | |
| 923 | |
| 924 extern void _PR_MD_RESUME_CPU(_PRCPU *cpu); | |
| 925 #define _PR_MD_RESUME_CPU _MD_RESUME_CPU | |
| 926 | |
| 927 extern void _PR_MD_BEGIN_SUSPEND_ALL(void); | |
| 928 #define _PR_MD_BEGIN_SUSPEND_ALL _MD_BEGIN_SUSPEND_ALL | |
| 929 | |
| 930 extern void _PR_MD_END_SUSPEND_ALL(void); | |
| 931 #define _PR_MD_END_SUSPEND_ALL _MD_END_SUSPEND_ALL | |
| 932 | |
| 933 extern void _PR_MD_BEGIN_RESUME_ALL(void); | |
| 934 #define _PR_MD_BEGIN_RESUME_ALL _MD_BEGIN_RESUME_ALL | |
| 935 | |
| 936 extern void _PR_MD_END_RESUME_ALL(void); | |
| 937 #define _PR_MD_END_RESUME_ALL _MD_END_RESUME_ALL | |
| 938 | |
| 939 #if defined(IRIX) | |
| 940 NSPR_API(void) _PR_IRIX_CHILD_PROCESS(void); | |
| 941 #endif /* IRIX */ | |
| 942 | |
| 943 #endif /* !_PR_LOCAL_THREADS_ONLY */ | |
| 944 | |
| 945 extern void _PR_MD_CLEAN_THREAD(PRThread *thread); | |
| 946 #define _PR_MD_CLEAN_THREAD _MD_CLEAN_THREAD | |
| 947 | |
| 948 #ifdef HAVE_CUSTOM_USER_THREADS | |
| 949 extern void _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *); | |
| 950 #define _PR_MD_CREATE_PRIMORDIAL_USER_THREAD _MD_CREATE_PRIMORDIAL_USER_THREA
D | |
| 951 | |
| 952 extern PRThread* _PR_MD_CREATE_USER_THREAD( | |
| 953 PRUint32 stacksize, | |
| 954 void (*start)(void *), | |
| 955 void *arg); | |
| 956 #define _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD | |
| 957 #endif | |
| 958 | |
| 959 extern PRStatus _PR_MD_CREATE_THREAD( | |
| 960 PRThread *thread, | |
| 961 void (*start) (void *), | |
| 962 PRThreadPriority priority, | |
| 963 PRThreadScope scope, | |
| 964 PRThreadState state, | |
| 965 PRUint32 stackSize); | |
| 966 #define _PR_MD_CREATE_THREAD _MD_CREATE_THREAD | |
| 967 | |
| 968 extern void _PR_MD_JOIN_THREAD(_MDThread *md); | |
| 969 #define _PR_MD_JOIN_THREAD _MD_JOIN_THREAD | |
| 970 | |
| 971 extern void _PR_MD_END_THREAD(void); | |
| 972 #define _PR_MD_END_THREAD _MD_END_THREAD | |
| 973 | |
| 974 extern void _PR_MD_YIELD(void); | |
| 975 #define _PR_MD_YIELD _MD_YIELD | |
| 976 | |
| 977 extern void _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri); | |
| 978 #define _PR_MD_SET_PRIORITY _MD_SET_PRIORITY | |
| 979 | |
| 980 extern void _PR_MD_SET_CURRENT_THREAD_NAME(const char *name); | |
| 981 #define _PR_MD_SET_CURRENT_THREAD_NAME _MD_SET_CURRENT_THREAD_NAME | |
| 982 | |
| 983 NSPR_API(void) _PR_MD_SUSPENDALL(void); | |
| 984 #define _PR_MD_SUSPENDALL _MD_SUSPENDALL | |
| 985 | |
| 986 NSPR_API(void) _PR_MD_RESUMEALL(void); | |
| 987 #define _PR_MD_RESUMEALL _MD_RESUMEALL | |
| 988 | |
| 989 extern void _PR_MD_INIT_CONTEXT( | |
| 990 PRThread *thread, char *top, void (*start) (void), PRBool *status); | |
| 991 #define _PR_MD_INIT_CONTEXT _MD_INIT_CONTEXT | |
| 992 | |
| 993 extern void _PR_MD_SWITCH_CONTEXT(PRThread *thread); | |
| 994 #define _PR_MD_SWITCH_CONTEXT _MD_SWITCH_CONTEXT | |
| 995 | |
| 996 extern void _PR_MD_RESTORE_CONTEXT(PRThread *thread); | |
| 997 #define _PR_MD_RESTORE_CONTEXT _MD_RESTORE_CONTEXT | |
| 998 | |
| 999 /* Segment related */ | |
| 1000 extern void _PR_MD_INIT_SEGS(void); | |
| 1001 #define _PR_MD_INIT_SEGS _MD_INIT_SEGS | |
| 1002 | |
| 1003 extern PRStatus _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr)
; | |
| 1004 #define _PR_MD_ALLOC_SEGMENT _MD_ALLOC_SEGMENT | |
| 1005 | |
| 1006 extern void _PR_MD_FREE_SEGMENT(PRSegment *seg); | |
| 1007 #define _PR_MD_FREE_SEGMENT _MD_FREE_SEGMENT | |
| 1008 | |
| 1009 /* Directory enumeration related */ | |
| 1010 extern PRStatus _PR_MD_OPEN_DIR(_MDDir *md,const char *name); | |
| 1011 #define _PR_MD_OPEN_DIR _MD_OPEN_DIR | |
| 1012 | |
| 1013 extern char * _PR_MD_READ_DIR(_MDDir *md, PRIntn flags); | |
| 1014 #define _PR_MD_READ_DIR _MD_READ_DIR | |
| 1015 | |
| 1016 extern PRInt32 _PR_MD_CLOSE_DIR(_MDDir *md); | |
| 1017 #define _PR_MD_CLOSE_DIR _MD_CLOSE_DIR | |
| 1018 | |
| 1019 /* Named semaphores related */ | |
| 1020 extern PRSem * _PR_MD_OPEN_SEMAPHORE( | |
| 1021 const char *osname, PRIntn flags, PRIntn mode, PRUintn value); | |
| 1022 #define _PR_MD_OPEN_SEMAPHORE _MD_OPEN_SEMAPHORE | |
| 1023 | |
| 1024 extern PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem); | |
| 1025 #define _PR_MD_WAIT_SEMAPHORE _MD_WAIT_SEMAPHORE | |
| 1026 | |
| 1027 extern PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem); | |
| 1028 #define _PR_MD_POST_SEMAPHORE _MD_POST_SEMAPHORE | |
| 1029 | |
| 1030 extern PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem); | |
| 1031 #define _PR_MD_CLOSE_SEMAPHORE _MD_CLOSE_SEMAPHORE | |
| 1032 | |
| 1033 extern PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname); | |
| 1034 #define _PR_MD_DELETE_SEMAPHORE _MD_DELETE_SEMAPHORE | |
| 1035 | |
| 1036 /* I/O related */ | |
| 1037 extern void _PR_MD_INIT_FILEDESC(PRFileDesc *fd); | |
| 1038 #define _PR_MD_INIT_FILEDESC _MD_INIT_FILEDESC | |
| 1039 | |
| 1040 extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd); | |
| 1041 #define _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK | |
| 1042 | |
| 1043 /* File I/O related */ | |
| 1044 extern PROsfd _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode); | |
| 1045 #define _PR_MD_OPEN _MD_OPEN | |
| 1046 | |
| 1047 extern PROsfd _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode); | |
| 1048 #define _PR_MD_OPEN_FILE _MD_OPEN_FILE | |
| 1049 | |
| 1050 extern PRInt32 _PR_MD_CLOSE_FILE(PROsfd osfd); | |
| 1051 #define _PR_MD_CLOSE_FILE _MD_CLOSE_FILE | |
| 1052 | |
| 1053 extern PRInt32 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 amount); | |
| 1054 #define _PR_MD_READ _MD_READ | |
| 1055 | |
| 1056 extern PRInt32 _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 amount); | |
| 1057 #define _PR_MD_WRITE _MD_WRITE | |
| 1058 | |
| 1059 extern PRInt32 _PR_MD_WRITEV( | |
| 1060 PRFileDesc *fd, const struct PRIOVec *iov, | |
| 1061 PRInt32 iov_size, PRIntervalTime timeout); | |
| 1062 #define _PR_MD_WRITEV _MD_WRITEV | |
| 1063 | |
| 1064 extern PRInt32 _PR_MD_FSYNC(PRFileDesc *fd); | |
| 1065 #define _PR_MD_FSYNC _MD_FSYNC | |
| 1066 | |
| 1067 extern PRInt32 _PR_MD_DELETE(const char *name); | |
| 1068 #define _PR_MD_DELETE _MD_DELETE | |
| 1069 | |
| 1070 extern PRInt32 _PR_MD_RENAME(const char *from, const char *to); | |
| 1071 #define _PR_MD_RENAME _MD_RENAME | |
| 1072 | |
| 1073 extern PRInt32 _PR_MD_ACCESS(const char *name, PRAccessHow how); | |
| 1074 #define _PR_MD_ACCESS _MD_ACCESS | |
| 1075 | |
| 1076 extern PRInt32 _PR_MD_STAT(const char *name, struct stat *buf); | |
| 1077 #define _PR_MD_STAT _MD_STAT | |
| 1078 | |
| 1079 extern PRInt32 _PR_MD_MKDIR(const char *name, PRIntn mode); | |
| 1080 #define _PR_MD_MKDIR _MD_MKDIR | |
| 1081 | |
| 1082 extern PRInt32 _PR_MD_MAKE_DIR(const char *name, PRIntn mode); | |
| 1083 #define _PR_MD_MAKE_DIR _MD_MAKE_DIR | |
| 1084 | |
| 1085 extern PRInt32 _PR_MD_RMDIR(const char *name); | |
| 1086 #define _PR_MD_RMDIR _MD_RMDIR | |
| 1087 | |
| 1088 #ifdef MOZ_UNICODE | |
| 1089 /* UTF16 File I/O related */ | |
| 1090 extern PRStatus _PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *md, const PRUnichar *name); | |
| 1091 #define _PR_MD_OPEN_DIR_UTF16 _MD_OPEN_DIR_UTF16 | |
| 1092 | |
| 1093 extern PROsfd _PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, PRIn
tn mode); | |
| 1094 #define _PR_MD_OPEN_FILE_UTF16 _MD_OPEN_FILE_UTF16 | |
| 1095 | |
| 1096 extern PRUnichar * _PR_MD_READ_DIR_UTF16(_MDDirUTF16 *md, PRIntn flags); | |
| 1097 #define _PR_MD_READ_DIR_UTF16 _MD_READ_DIR_UTF16 | |
| 1098 | |
| 1099 extern PRInt32 _PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *md); | |
| 1100 #define _PR_MD_CLOSE_DIR_UTF16 _MD_CLOSE_DIR_UTF16 | |
| 1101 | |
| 1102 extern PRInt32 _PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *inf
o); | |
| 1103 #define _PR_MD_GETFILEINFO64_UTF16 _MD_GETFILEINFO64_UTF16 | |
| 1104 #endif /* MOZ_UNICODE */ | |
| 1105 | |
| 1106 /* Socket I/O related */ | |
| 1107 extern void _PR_MD_INIT_IO(void); | |
| 1108 #define _PR_MD_INIT_IO _MD_INIT_IO | |
| 1109 | |
| 1110 extern PRInt32 _PR_MD_CLOSE_SOCKET(PROsfd osfd); | |
| 1111 #define _PR_MD_CLOSE_SOCKET _MD_CLOSE_SOCKET | |
| 1112 | |
| 1113 extern PRInt32 _PR_MD_CONNECT( | |
| 1114 PRFileDesc *fd, const PRNetAddr *addr, | |
| 1115 PRUint32 addrlen, PRIntervalTime timeout); | |
| 1116 #define _PR_MD_CONNECT _MD_CONNECT | |
| 1117 | |
| 1118 extern PROsfd _PR_MD_ACCEPT( | |
| 1119 PRFileDesc *fd, PRNetAddr *addr, | |
| 1120 PRUint32 *addrlen, PRIntervalTime timeout); | |
| 1121 #define _PR_MD_ACCEPT _MD_ACCEPT | |
| 1122 | |
| 1123 extern PRInt32 _PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrl
en); | |
| 1124 #define _PR_MD_BIND _MD_BIND | |
| 1125 | |
| 1126 extern PRInt32 _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog); | |
| 1127 #define _PR_MD_LISTEN _MD_LISTEN | |
| 1128 | |
| 1129 extern PRInt32 _PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how); | |
| 1130 #define _PR_MD_SHUTDOWN _MD_SHUTDOWN | |
| 1131 | |
| 1132 extern PRInt32 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, | |
| 1133 PRIntn flags, PRIntervalTime timeout); | |
| 1134 #define _PR_MD_RECV _MD_RECV | |
| 1135 | |
| 1136 extern PRInt32 _PR_MD_SEND( | |
| 1137 PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, | |
| 1138 PRIntervalTime timeout); | |
| 1139 #define _PR_MD_SEND _MD_SEND | |
| 1140 | |
| 1141 extern PRInt32 _PR_MD_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, | |
| 1142 PRNetAddr **raddr, void *buf, PRInt32 amount, | |
| 1143 PRIntervalTime timeout); | |
| 1144 #define _PR_MD_ACCEPT_READ _MD_ACCEPT_READ | |
| 1145 | |
| 1146 #ifdef WIN32 | |
| 1147 extern PROsfd _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *addr, | |
| 1148 PRUint32 *addrlen, PRIntervalTime timeout, | |
| 1149 PRBool fast, | |
| 1150 _PR_AcceptTimeoutCallback callback, | |
| 1151 void *callbackArg); | |
| 1152 | |
| 1153 extern PRInt32 _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, | |
| 1154 PRNetAddr **raddr, void *buf, PRInt32 amount, | |
| 1155 PRIntervalTime timeout, PRBool fast, | |
| 1156 _PR_AcceptTimeoutCallback callback, | |
| 1157 void *callbackArg); | |
| 1158 | |
| 1159 extern void _PR_MD_UPDATE_ACCEPT_CONTEXT(PROsfd s, PROsfd ls); | |
| 1160 #define _PR_MD_UPDATE_ACCEPT_CONTEXT _MD_UPDATE_ACCEPT_CONTEXT | |
| 1161 /* | |
| 1162 * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME. | |
| 1163 * We store the value in a PRTime variable for convenience. | |
| 1164 * This constant is used by _PR_FileTimeToPRTime(). | |
| 1165 * This is defined in ntmisc.c | |
| 1166 */ | |
| 1167 extern const PRTime _pr_filetime_offset; | |
| 1168 #endif /* WIN32 */ | |
| 1169 | |
| 1170 extern PRInt32 _PR_MD_SENDFILE( | |
| 1171 PRFileDesc *sock, PRSendFileData *sfd, | |
| 1172 PRInt32 flags, PRIntervalTime timeout); | |
| 1173 #define _PR_MD_SENDFILE _MD_SENDFILE | |
| 1174 | |
| 1175 extern PRStatus _PR_MD_GETSOCKNAME( | |
| 1176 PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen); | |
| 1177 #define _PR_MD_GETSOCKNAME _MD_GETSOCKNAME | |
| 1178 | |
| 1179 extern PRStatus _PR_MD_GETPEERNAME( | |
| 1180 PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen); | |
| 1181 #define _PR_MD_GETPEERNAME _MD_GETPEERNAME | |
| 1182 | |
| 1183 extern PRStatus _PR_MD_GETSOCKOPT( | |
| 1184 PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optle
n); | |
| 1185 #define _PR_MD_GETSOCKOPT _MD_GETSOCKOPT | |
| 1186 | |
| 1187 extern PRStatus _PR_MD_SETSOCKOPT( | |
| 1188 PRFileDesc *fd, PRInt32 level, PRInt32 optname, | |
| 1189 const char* optval, PRInt32 optlen); | |
| 1190 #define _PR_MD_SETSOCKOPT _MD_SETSOCKOPT | |
| 1191 | |
| 1192 extern PRStatus PR_CALLBACK _PR_SocketGetSocketOption( | |
| 1193 PRFileDesc *fd, PRSocketOptionData *data); | |
| 1194 | |
| 1195 extern PRStatus PR_CALLBACK _PR_SocketSetSocketOption( | |
| 1196 PRFileDesc *fd, const PRSocketOptionData *data); | |
| 1197 | |
| 1198 extern PRInt32 _PR_MD_RECVFROM( | |
| 1199 PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, | |
| 1200 PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout); | |
| 1201 #define _PR_MD_RECVFROM _MD_RECVFROM | |
| 1202 | |
| 1203 extern PRInt32 _PR_MD_SENDTO( | |
| 1204 PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, | |
| 1205 const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout); | |
| 1206 #define _PR_MD_SENDTO _MD_SENDTO | |
| 1207 | |
| 1208 extern PRInt32 _PR_MD_SOCKETPAIR(int af, int type, int flags, PROsfd *osfd); | |
| 1209 #define _PR_MD_SOCKETPAIR _MD_SOCKETPAIR | |
| 1210 | |
| 1211 extern PROsfd _PR_MD_SOCKET(int af, int type, int flags); | |
| 1212 #define _PR_MD_SOCKET _MD_SOCKET | |
| 1213 | |
| 1214 extern PRInt32 _PR_MD_SOCKETAVAILABLE(PRFileDesc *fd); | |
| 1215 #define _PR_MD_SOCKETAVAILABLE _MD_SOCKETAVAILABLE | |
| 1216 | |
| 1217 extern PRInt32 _PR_MD_PIPEAVAILABLE(PRFileDesc *fd); | |
| 1218 #define _PR_MD_PIPEAVAILABLE _MD_PIPEAVAILABLE | |
| 1219 | |
| 1220 extern PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, | |
| 1221
PRIntervalTime timeout); | |
| 1222 #define _PR_MD_PR_POLL _MD_PR_POLL | |
| 1223 | |
| 1224 /* | |
| 1225 * Initialize fd->secret->inheritable for a newly created fd. | |
| 1226 * If 'imported' is false, the osfd (i.e., fd->secret->md.osfd) | |
| 1227 * was created by NSPR and hence has the OS-dependent default | |
| 1228 * inheritable attribute. If 'imported' is true, the osfd was | |
| 1229 * not created by NSPR and hence a system call is required to | |
| 1230 * query its inheritable attribute. Since we may never need to | |
| 1231 * know the inheritable attribute of a fd, a platform may choose | |
| 1232 * to initialize fd->secret->inheritable of an imported fd to | |
| 1233 * _PR_TRI_UNKNOWN and only pay the cost of the system call | |
| 1234 * (in _PR_MD_QUERY_FD_INHERITABLE) when necessary. | |
| 1235 */ | |
| 1236 extern void _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported); | |
| 1237 #define _PR_MD_INIT_FD_INHERITABLE _MD_INIT_FD_INHERITABLE | |
| 1238 | |
| 1239 extern PRStatus _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable); | |
| 1240 #define _PR_MD_SET_FD_INHERITABLE _MD_SET_FD_INHERITABLE | |
| 1241 | |
| 1242 | |
| 1243 #define _PR_PROCESS_TIMEOUT_INTERRUPT_ERRORS(me) \ | |
| 1244 if (_PR_PENDING_INTERRUPT(me)) { \ | |
| 1245 me->flags &= ~_PR_INTERRUPT; \ | |
| 1246 PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); \ | |
| 1247 } else { \ | |
| 1248 PR_SetError(PR_IO_TIMEOUT_ERROR, 0); \ | |
| 1249 } | |
| 1250 | |
| 1251 extern void *_PR_MD_GET_SP(PRThread *thread); | |
| 1252 #define _PR_MD_GET_SP _MD_GET_SP | |
| 1253 | |
| 1254 #endif /* defined(_PR_PTHREADS) */ | |
| 1255 | |
| 1256 /************************************************************************/ | |
| 1257 /************************************************************************* | |
| 1258 ** The remainder of the definitions are shared by pthreads and the classic | |
| 1259 ** NSPR code. These too may be conditionalized. | |
| 1260 *************************************************************************/ | |
| 1261 /************************************************************************/ | |
| 1262 | |
| 1263 extern PROffset32 _PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence w
hence); | |
| 1264 #define _PR_MD_LSEEK _MD_LSEEK | |
| 1265 | |
| 1266 extern PROffset64 _PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence
whence); | |
| 1267 #define _PR_MD_LSEEK64 _MD_LSEEK64 | |
| 1268 | |
| 1269 extern PRInt32 _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info); | |
| 1270 #define _PR_MD_GETFILEINFO _MD_GETFILEINFO | |
| 1271 | |
| 1272 extern PRInt32 _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info); | |
| 1273 #define _PR_MD_GETFILEINFO64 _MD_GETFILEINFO64 | |
| 1274 | |
| 1275 extern PRInt32 _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info); | |
| 1276 #define _PR_MD_GETOPENFILEINFO _MD_GETOPENFILEINFO | |
| 1277 | |
| 1278 extern PRInt32 _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info
); | |
| 1279 #define _PR_MD_GETOPENFILEINFO64 _MD_GETOPENFILEINFO64 | |
| 1280 | |
| 1281 | |
| 1282 /*****************************************************************************/ | |
| 1283 /************************** File descriptor caching **************************/ | |
| 1284 /*****************************************************************************/ | |
| 1285 extern void _PR_InitFdCache(void); | |
| 1286 extern void _PR_CleanupFdCache(void); | |
| 1287 extern PRFileDesc *_PR_Getfd(void); | |
| 1288 extern void _PR_Putfd(PRFileDesc *fd); | |
| 1289 | |
| 1290 /* | |
| 1291 * These flags are used by NSPR temporarily in the poll | |
| 1292 * descriptor's out_flags field to record the mapping of | |
| 1293 * NSPR's poll flags to the system poll flags. | |
| 1294 * | |
| 1295 * If _PR_POLL_READ_SYS_WRITE bit is set, it means the | |
| 1296 * PR_POLL_READ flag specified by the topmost layer is | |
| 1297 * mapped to the WRITE flag at the system layer. Similarly | |
| 1298 * for the other three _PR_POLL_XXX_SYS_YYY flags. It is | |
| 1299 * assumed that the PR_POLL_EXCEPT flag doesn't get mapped | |
| 1300 * to other flags. | |
| 1301 */ | |
| 1302 #define _PR_POLL_READ_SYS_READ 0x1 | |
| 1303 #define _PR_POLL_READ_SYS_WRITE 0x2 | |
| 1304 #define _PR_POLL_WRITE_SYS_READ 0x4 | |
| 1305 #define _PR_POLL_WRITE_SYS_WRITE 0x8 | |
| 1306 | |
| 1307 /* | |
| 1308 ** These methods are coerced into file descriptor methods table | |
| 1309 ** when the intended service is inappropriate for the particular | |
| 1310 ** type of file descriptor. | |
| 1311 */ | |
| 1312 extern PRIntn _PR_InvalidInt(void); | |
| 1313 extern PRInt16 _PR_InvalidInt16(void); | |
| 1314 extern PRInt64 _PR_InvalidInt64(void); | |
| 1315 extern PRStatus _PR_InvalidStatus(void); | |
| 1316 extern PRFileDesc *_PR_InvalidDesc(void); | |
| 1317 | |
| 1318 extern PRIOMethods _pr_faulty_methods; | |
| 1319 | |
| 1320 /* | |
| 1321 ** The PR_NETADDR_SIZE macro can only be called on a PRNetAddr union | |
| 1322 ** whose 'family' field is set. It returns the size of the union | |
| 1323 ** member corresponding to the specified address family. | |
| 1324 */ | |
| 1325 | |
| 1326 extern PRUintn _PR_NetAddrSize(const PRNetAddr* addr); | |
| 1327 | |
| 1328 #if defined(_PR_INET6) | |
| 1329 | |
| 1330 #define PR_NETADDR_SIZE(_addr) _PR_NetAddrSize(_addr) | |
| 1331 | |
| 1332 #elif defined(_PR_HAVE_MD_SOCKADDR_IN6) | |
| 1333 | |
| 1334 /* | |
| 1335 ** Under the following conditions: | |
| 1336 ** 1. _PR_INET6 is not defined; | |
| 1337 ** 2. _PR_INET6_PROBE is defined; | |
| 1338 ** 3. struct sockaddr_in6 has nonstandard fields at the end | |
| 1339 ** (e.g., on Solaris 8), | |
| 1340 ** (_addr)->ipv6 is smaller than struct sockaddr_in6, and | |
| 1341 ** hence we can't pass sizeof((_addr)->ipv6) to socket | |
| 1342 ** functions such as connect because they would fail with | |
| 1343 ** EINVAL. | |
| 1344 ** | |
| 1345 ** To pass the correct socket address length to socket | |
| 1346 ** functions, define the macro _PR_HAVE_MD_SOCKADDR_IN6 and | |
| 1347 ** define struct _md_sockaddr_in6 to be isomorphic to | |
| 1348 ** struct sockaddr_in6. | |
| 1349 */ | |
| 1350 | |
| 1351 #if defined(XP_UNIX) || defined(XP_OS2) | |
| 1352 #define PR_NETADDR_SIZE(_addr) \ | |
| 1353 ((_addr)->raw.family == PR_AF_INET \ | |
| 1354 ? sizeof((_addr)->inet) \ | |
| 1355 : ((_addr)->raw.family == PR_AF_INET6 \ | |
| 1356 ? sizeof(struct _md_sockaddr_in6) \ | |
| 1357 : sizeof((_addr)->local))) | |
| 1358 #else | |
| 1359 #define PR_NETADDR_SIZE(_addr) \ | |
| 1360 ((_addr)->raw.family == PR_AF_INET \ | |
| 1361 ? sizeof((_addr)->inet) \ | |
| 1362 : sizeof(struct _md_sockaddr_in6)) | |
| 1363 #endif /* defined(XP_UNIX) */ | |
| 1364 | |
| 1365 #else | |
| 1366 | |
| 1367 #if defined(XP_UNIX) || defined(XP_OS2) | |
| 1368 #define PR_NETADDR_SIZE(_addr) \ | |
| 1369 ((_addr)->raw.family == PR_AF_INET \ | |
| 1370 ? sizeof((_addr)->inet) \ | |
| 1371 : ((_addr)->raw.family == PR_AF_INET6 \ | |
| 1372 ? sizeof((_addr)->ipv6) \ | |
| 1373 : sizeof((_addr)->local))) | |
| 1374 #else | |
| 1375 #define PR_NETADDR_SIZE(_addr) \ | |
| 1376 ((_addr)->raw.family == PR_AF_INET \ | |
| 1377 ? sizeof((_addr)->inet) \ | |
| 1378 : sizeof((_addr)->ipv6)) | |
| 1379 #endif /* defined(XP_UNIX) */ | |
| 1380 | |
| 1381 #endif /* defined(_PR_INET6) */ | |
| 1382 | |
| 1383 extern PRStatus _PR_MapOptionName( | |
| 1384 PRSockOption optname, PRInt32 *level, PRInt32 *name); | |
| 1385 extern void _PR_InitThreads( | |
| 1386 PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs); | |
| 1387 | |
| 1388 struct PRLock { | |
| 1389 #if defined(_PR_PTHREADS) | |
| 1390 pthread_mutex_t mutex; /* the underlying lock */ | |
| 1391 _PT_Notified notified; /* array of conditions notified */ | |
| 1392 PRBool locked; /* whether the mutex is locked */ | |
| 1393 pthread_t owner; /* if locked, current lock owner */ | |
| 1394 #elif defined(_PR_BTHREADS) | |
| 1395 sem_id semaphoreID; /* the underlying lock */ | |
| 1396 int32 benaphoreCount; /* number of people in lock */ | |
| 1397 thread_id owner; /* current lock owner */ | |
| 1398 #else /* not pthreads or Be threads */ | |
| 1399 PRCList links; /* linkage for PRThread.lockList */ | |
| 1400 struct PRThread *owner; /* current lock owner */ | |
| 1401 PRCList waitQ; /* list of threads waiting for lock */ | |
| 1402 PRThreadPriority priority; /* priority of lock */ | |
| 1403 PRThreadPriority boostPriority; /* boosted priority of lock owner */ | |
| 1404 _MDLock ilock; /* Internal Lock to protect user-level field
s */ | |
| 1405 #endif | |
| 1406 }; | |
| 1407 | |
| 1408 extern void _PR_InitLocks(void); | |
| 1409 | |
| 1410 struct PRCondVar { | |
| 1411 PRLock *lock; /* associated lock that protects the condition *
/ | |
| 1412 #if defined(_PR_PTHREADS) | |
| 1413 pthread_cond_t cv; /* underlying pthreads condition */ | |
| 1414 PRInt32 notify_pending; /* CV has destroy pending notification */ | |
| 1415 #elif defined(_PR_BTHREADS) | |
| 1416 sem_id sem; /* the underlying lock */ | |
| 1417 sem_id handshakeSem; /* the lock for 'notify'-threads waiting for con
firmation */ | |
| 1418 sem_id signalSem; /* the lock for threads waiting for someone to n
otify */ | |
| 1419 volatile int32 nw; /* the number waiting */ | |
| 1420 volatile int32 ns; /* the number signalling */ | |
| 1421 long signalBenCount; /* the number waiting on the underlying sem */ | |
| 1422 #else /* not pthreads or Be threads */ | |
| 1423 PRCList condQ; /* Condition variable wait Q */ | |
| 1424 _MDLock ilock; /* Internal Lock to protect condQ */ | |
| 1425 _MDCVar md; | |
| 1426 #endif | |
| 1427 }; | |
| 1428 | |
| 1429 /************************************************************************/ | |
| 1430 | |
| 1431 struct PRMonitor { | |
| 1432 const char* name; /* monitor name for debugging */ | |
| 1433 #if defined(_PR_PTHREADS) | |
| 1434 PRLock lock; /* the lock structure */ | |
| 1435 pthread_t owner; /* the owner of the lock or invalid */ | |
| 1436 PRCondVar *cvar; /* condition variable queue */ | |
| 1437 #else /* defined(_PR_PTHREADS) */ | |
| 1438 PRCondVar *cvar; /* associated lock and condition variable queue
*/ | |
| 1439 #endif /* defined(_PR_PTHREADS) */ | |
| 1440 PRUint32 entryCount; /* # of times re-entered */ | |
| 1441 }; | |
| 1442 | |
| 1443 /************************************************************************/ | |
| 1444 | |
| 1445 struct PRSemaphore { | |
| 1446 #if defined(_PR_BTHREADS) | |
| 1447 sem_id sem; | |
| 1448 int32 benaphoreCount; | |
| 1449 #else | |
| 1450 PRCondVar *cvar; /* associated lock and condition variable queue */ | |
| 1451 PRUintn count; /* the value of the counting semaphore */ | |
| 1452 PRUint32 waiters; /* threads waiting on the semaphore */ | |
| 1453 #if defined(_PR_PTHREADS) | |
| 1454 #else /* defined(_PR_PTHREADS) */ | |
| 1455 _MDSemaphore md; | |
| 1456 #endif /* defined(_PR_PTHREADS) */ | |
| 1457 #endif /* defined(_PR_BTHREADS) */ | |
| 1458 }; | |
| 1459 | |
| 1460 NSPR_API(void) _PR_InitSem(void); | |
| 1461 | |
| 1462 /*************************************************************************/ | |
| 1463 | |
| 1464 struct PRSem { | |
| 1465 #ifdef _PR_HAVE_POSIX_SEMAPHORES | |
| 1466 sem_t *sem; | |
| 1467 #elif defined(_PR_HAVE_SYSV_SEMAPHORES) | |
| 1468 int semid; | |
| 1469 #elif defined(WIN32) | |
| 1470 HANDLE sem; | |
| 1471 #else | |
| 1472 PRInt8 notused; | |
| 1473 #endif | |
| 1474 }; | |
| 1475 | |
| 1476 /*************************************************************************/ | |
| 1477 | |
| 1478 struct PRStackStr { | |
| 1479 /* head MUST be at offset 0; assembly language code relies on this */ | |
| 1480 #if defined(AIX) | |
| 1481 volatile PRStackElem prstk_head; | |
| 1482 #else | |
| 1483 PRStackElem prstk_head; | |
| 1484 #endif | |
| 1485 | |
| 1486 PRLock *prstk_lock; | |
| 1487 char *prstk_name; | |
| 1488 }; | |
| 1489 | |
| 1490 /************************************************************************/ | |
| 1491 | |
| 1492 /* XXX this needs to be exported (sigh) */ | |
| 1493 struct PRThreadStack { | |
| 1494 PRCList links; | |
| 1495 PRUintn flags; | |
| 1496 | |
| 1497 char *allocBase; /* base of stack's allocated memory */ | |
| 1498 PRUint32 allocSize; /* size of stack's allocated memory */ | |
| 1499 char *stackBottom; /* bottom of stack from C's point of view */ | |
| 1500 char *stackTop; /* top of stack from C's point of view */ | |
| 1501 PRUint32 stackSize; /* size of usable portion of the stack */ | |
| 1502 | |
| 1503 PRSegment *seg; | |
| 1504 PRThread* thr; /* back pointer to thread owning this stack */ | |
| 1505 | |
| 1506 #if defined(_PR_PTHREADS) | |
| 1507 #else /* defined(_PR_PTHREADS) */ | |
| 1508 _MDThreadStack md; | |
| 1509 #endif /* defined(_PR_PTHREADS) */ | |
| 1510 }; | |
| 1511 | |
| 1512 extern void _PR_DestroyThreadPrivate(PRThread*); | |
| 1513 | |
| 1514 typedef void (PR_CALLBACK *_PRStartFn)(void *); | |
| 1515 | |
| 1516 struct PRThread { | |
| 1517 PRUint32 state; /* thread's creation state */ | |
| 1518 PRThreadPriority priority; /* apparent priority, loosly defined */ | |
| 1519 | |
| 1520 void *arg; /* argument to the client's entry point */ | |
| 1521 _PRStartFn startFunc; /* the root of the client's thread */ | |
| 1522 | |
| 1523 PRThreadStack *stack; /* info about thread's stack (for GC) */ | |
| 1524 void *environment; /* pointer to execution environment */ | |
| 1525 | |
| 1526 PRThreadDumpProc dump; /* dump thread info out */ | |
| 1527 void *dumpArg; /* argument for the dump function */ | |
| 1528 | |
| 1529 /* | |
| 1530 ** Per thread private data | |
| 1531 */ | |
| 1532 PRUint32 tpdLength; /* thread's current vector length */ | |
| 1533 void **privateData; /* private data vector or NULL */ | |
| 1534 PRErrorCode errorCode; /* current NSPR error code | zero */ | |
| 1535 PRInt32 osErrorCode; /* mapping of errorCode | zero */ | |
| 1536 PRIntn errorStringLength; /* textLength from last call to PR_SetErrorT
ext() */ | |
| 1537 PRInt32 errorStringSize; /* malloc()'d size of buffer | zero */ | |
| 1538 char *errorString; /* current error string | NULL */ | |
| 1539 char *name; /* thread's name */ | |
| 1540 | |
| 1541 #if defined(_PR_PTHREADS) | |
| 1542 pthread_t id; /* pthread identifier for the thread */ | |
| 1543 PRBool okToDelete; /* ok to delete the PRThread struct? */ | |
| 1544 PRCondVar *waiting; /* where the thread is waiting | NULL */ | |
| 1545 void *sp; /* recorded sp for garbage collection */ | |
| 1546 PRThread *next, *prev; /* simple linked list of all threads */ | |
| 1547 PRUint32 suspend; /* used to store suspend and resume flags */ | |
| 1548 #ifdef PT_NO_SIGTIMEDWAIT | |
| 1549 pthread_mutex_t suspendResumeMutex; | |
| 1550 pthread_cond_t suspendResumeCV; | |
| 1551 #endif | |
| 1552 PRUint32 interrupt_blocked; /* interrupt blocked */ | |
| 1553 struct pollfd *syspoll_list; /* Unix polling list used by PR_Poll */ | |
| 1554 PRUint32 syspoll_count; /* number of elements in syspoll_list */ | |
| 1555 #if defined(_PR_POLL_WITH_SELECT) | |
| 1556 int *selectfd_list; /* Unix fd's that PR_Poll selects on */ | |
| 1557 PRUint32 selectfd_count; /* number of elements in selectfd_list */ | |
| 1558 #endif | |
| 1559 #elif defined(_PR_BTHREADS) | |
| 1560 PRUint32 flags; | |
| 1561 _MDThread md; | |
| 1562 PRBool io_pending; | |
| 1563 PRInt32 io_fd; | |
| 1564 PRBool io_suspended; | |
| 1565 #else /* not pthreads or Be threads */ | |
| 1566 _MDLock threadLock; /* Lock to protect thread state variables. | |
| 1567 * Protects the following fields: | |
| 1568 * state | |
| 1569 * priority | |
| 1570 * links | |
| 1571 * wait | |
| 1572 * cpu | |
| 1573 */ | |
| 1574 PRUint32 queueCount; | |
| 1575 PRUint32 waitCount; | |
| 1576 | |
| 1577 PRCList active; /* on list of all active threads */ | |
| 1578 PRCList links; | |
| 1579 PRCList waitQLinks; /* when thread is PR_Wait'ing */ | |
| 1580 PRCList lockList; /* list of locks currently holding */ | |
| 1581 PRIntervalTime sleep; /* sleep time when thread is sleeping */ | |
| 1582 struct _wait { | |
| 1583 struct PRLock *lock; | |
| 1584 struct PRCondVar *cvar; | |
| 1585 } wait; | |
| 1586 | |
| 1587 PRUint32 id; | |
| 1588 PRUint32 flags; | |
| 1589 PRUint32 no_sched; /* Don't schedule the thread to run. | |
| 1590 * This flag has relevance only when | |
| 1591 * multiple NSPR CPUs are created. | |
| 1592 * When a thread is de-scheduled, there | |
| 1593 * is a narrow window of time in which | |
| 1594 * the thread is put on the run queue | |
| 1595 * but the scheduler is actually using | |
| 1596 * the stack of this thread. It is safe | |
| 1597 * to run this thread on a different CPU | |
| 1598 * only when its stack is not in use on | |
| 1599 * any other CPU. The no_sched flag is | |
| 1600 * set during this interval to prevent | |
| 1601 * the thread from being scheduled on a | |
| 1602 * different CPU. | |
| 1603 */ | |
| 1604 | |
| 1605 /* thread termination condition variable for join */ | |
| 1606 PRCondVar *term; | |
| 1607 | |
| 1608 _PRCPU *cpu; /* cpu to which this thread is bound */ | |
| 1609 PRUint32 threadAllocatedOnStack;/* boolean */ | |
| 1610 | |
| 1611 /* When an async IO is in progress and a second async IO cannot be | |
| 1612 * initiated, the io_pending flag is set to true. Some platforms will | |
| 1613 * not use the io_pending flag. If the io_pending flag is true, then | |
| 1614 * io_fd is the OS-file descriptor on which IO is pending. | |
| 1615 */ | |
| 1616 PRBool io_pending; | |
| 1617 PRInt32 io_fd; | |
| 1618 | |
| 1619 /* If a timeout occurs or if an outstanding IO is interrupted and the | |
| 1620 * OS doesn't support a real cancellation (NT or MAC), then the | |
| 1621 * io_suspended flag will be set to true. The thread will be resumed | |
| 1622 * but may run into trouble issuing additional IOs until the io_pending | |
| 1623 * flag can be cleared | |
| 1624 */ | |
| 1625 PRBool io_suspended; | |
| 1626 | |
| 1627 _MDThread md; | |
| 1628 #endif | |
| 1629 }; | |
| 1630 | |
| 1631 struct PRProcessAttr { | |
| 1632 PRFileDesc *stdinFd; | |
| 1633 PRFileDesc *stdoutFd; | |
| 1634 PRFileDesc *stderrFd; | |
| 1635 char *currentDirectory; | |
| 1636 char *fdInheritBuffer; | |
| 1637 PRSize fdInheritBufferSize; | |
| 1638 PRSize fdInheritBufferUsed; | |
| 1639 }; | |
| 1640 | |
| 1641 struct PRProcess { | |
| 1642 _MDProcess md; | |
| 1643 }; | |
| 1644 | |
| 1645 struct PRFileMap { | |
| 1646 PRFileDesc *fd; | |
| 1647 PRFileMapProtect prot; | |
| 1648 _MDFileMap md; | |
| 1649 }; | |
| 1650 | |
| 1651 /************************************************************************/ | |
| 1652 | |
| 1653 /* | |
| 1654 ** File descriptors of the NSPR layer can be in one of the | |
| 1655 ** following states (stored in the 'state' field of struct | |
| 1656 ** PRFilePrivate): | |
| 1657 ** - _PR_FILEDESC_OPEN: The OS fd is open. | |
| 1658 ** - _PR_FILEDESC_CLOSED: The OS fd is closed. The PRFileDesc | |
| 1659 ** is still open but is unusable. The only operation allowed | |
| 1660 ** on the PRFileDesc is PR_Close(). | |
| 1661 ** - _PR_FILEDESC_FREED: The OS fd is closed and the PRFileDesc | |
| 1662 ** structure is freed. | |
| 1663 */ | |
| 1664 | |
| 1665 #define _PR_FILEDESC_OPEN 0xaaaaaaaa /* 1010101... */ | |
| 1666 #define _PR_FILEDESC_CLOSED 0x55555555 /* 0101010... */ | |
| 1667 #define _PR_FILEDESC_FREED 0x11111111 | |
| 1668 | |
| 1669 /* | |
| 1670 ** A boolean type with an additional "unknown" state | |
| 1671 */ | |
| 1672 | |
| 1673 typedef enum { | |
| 1674 _PR_TRI_TRUE = 1, | |
| 1675 _PR_TRI_FALSE = 0, | |
| 1676 _PR_TRI_UNKNOWN = -1 | |
| 1677 } _PRTriStateBool; | |
| 1678 | |
| 1679 struct PRFilePrivate { | |
| 1680 PRInt32 state; | |
| 1681 PRBool nonblocking; | |
| 1682 _PRTriStateBool inheritable; | |
| 1683 PRFileDesc *next; | |
| 1684 PRIntn lockCount; /* 0: not locked | |
| 1685 * -1: a native lockfile call is in progress | |
| 1686 * > 0: # times the file is locked */ | |
| 1687 #ifdef _PR_HAVE_PEEK_BUFFER | |
| 1688 char *peekBuffer; | |
| 1689 PRInt32 peekBufSize; | |
| 1690 PRInt32 peekBytes; | |
| 1691 #endif | |
| 1692 #if !defined(_PR_HAVE_O_APPEND) | |
| 1693 PRBool appendMode; /* Some platforms don't have O_APPEND or its | |
| 1694 * equivalent, so they have to seek to end of | |
| 1695 * file on write if the file was opened in | |
| 1696 * append mode. See Bugzilla 4090, 276330. */ | |
| 1697 #endif | |
| 1698 _MDFileDesc md; | |
| 1699 #ifdef _PR_NEED_SECRET_AF | |
| 1700 PRUint16 af; /* If the platform's implementation of accept() | |
| 1701 * requires knowing the address family of the | |
| 1702 * socket, we save the address family here. */ | |
| 1703 #endif | |
| 1704 }; | |
| 1705 | |
| 1706 #ifdef _WIN64 | |
| 1707 #define PR_PRIdOSFD "lld" /* for printing PROsfd */ | |
| 1708 #define PR_PRIxOSFD "llx" | |
| 1709 #define PR_SCNdOSFD "lld" /* for scanning PROsfd */ | |
| 1710 #define PR_SCNxOSFD "llx" | |
| 1711 #else | |
| 1712 #define PR_PRIdOSFD "ld" /* for printing PROsfd */ | |
| 1713 #define PR_PRIxOSFD "lx" | |
| 1714 #define PR_SCNdOSFD "ld" /* for scanning PROsfd */ | |
| 1715 #define PR_SCNxOSFD "lx" | |
| 1716 #endif | |
| 1717 | |
| 1718 struct PRDir { | |
| 1719 PRDirEntry d; | |
| 1720 _MDDir md; | |
| 1721 }; | |
| 1722 | |
| 1723 #ifdef MOZ_UNICODE | |
| 1724 struct PRDirUTF16 { | |
| 1725 PRDirEntry d; | |
| 1726 _MDDirUTF16 md; | |
| 1727 }; | |
| 1728 #endif /* MOZ_UNICODE */ | |
| 1729 | |
| 1730 extern void _PR_InitSegs(void); | |
| 1731 extern void _PR_InitStacks(void); | |
| 1732 extern void _PR_InitTPD(void); | |
| 1733 extern void _PR_InitMem(void); | |
| 1734 extern void _PR_InitEnv(void); | |
| 1735 extern void _PR_InitCMon(void); | |
| 1736 extern void _PR_InitIO(void); | |
| 1737 extern void _PR_InitLog(void); | |
| 1738 extern void _PR_InitNet(void); | |
| 1739 extern void _PR_InitClock(void); | |
| 1740 extern void _PR_InitLinker(void); | |
| 1741 extern void _PR_InitAtomic(void); | |
| 1742 extern void _PR_InitCPUs(void); | |
| 1743 extern void _PR_InitDtoa(void); | |
| 1744 extern void _PR_InitTime(void); | |
| 1745 extern void _PR_InitMW(void); | |
| 1746 extern void _PR_InitRWLocks(void); | |
| 1747 extern void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me); | |
| 1748 extern void _PR_CleanupThread(PRThread *thread); | |
| 1749 extern void _PR_CleanupCallOnce(void); | |
| 1750 extern void _PR_CleanupMW(void); | |
| 1751 extern void _PR_CleanupTime(void); | |
| 1752 extern void _PR_CleanupDtoa(void); | |
| 1753 extern void _PR_ShutdownLinker(void); | |
| 1754 extern void _PR_CleanupEnv(void); | |
| 1755 extern void _PR_CleanupIO(void); | |
| 1756 extern void _PR_CleanupCMon(void); | |
| 1757 extern void _PR_CleanupNet(void); | |
| 1758 extern void _PR_CleanupLayerCache(void); | |
| 1759 extern void _PR_CleanupStacks(void); | |
| 1760 #ifdef WINNT | |
| 1761 extern void _PR_CleanupCPUs(void); | |
| 1762 #endif | |
| 1763 extern void _PR_CleanupThreads(void); | |
| 1764 extern void _PR_CleanupTPD(void); | |
| 1765 extern void _PR_Cleanup(void); | |
| 1766 extern void _PR_LogCleanup(void); | |
| 1767 extern void _PR_InitLayerCache(void); | |
| 1768 | |
| 1769 extern PRBool _pr_initialized; | |
| 1770 extern void _PR_ImplicitInitialization(void); | |
| 1771 extern PRBool _PR_Obsolete(const char *obsolete, const char *preferred); | |
| 1772 | |
| 1773 /************************************************************************/ | |
| 1774 | |
| 1775 struct PRSegment { | |
| 1776 void *vaddr; | |
| 1777 PRUint32 size; | |
| 1778 PRUintn flags; | |
| 1779 #if defined(_PR_PTHREADS) | |
| 1780 #else /* defined(_PR_PTHREADS) */ | |
| 1781 _MDSegment md; | |
| 1782 #endif /* defined(_PR_PTHREADS) */ | |
| 1783 }; | |
| 1784 | |
| 1785 /* PRSegment.flags */ | |
| 1786 #define _PR_SEG_VM 0x1 | |
| 1787 | |
| 1788 /************************************************************************/ | |
| 1789 | |
| 1790 extern PRInt32 _pr_pageSize; | |
| 1791 extern PRInt32 _pr_pageShift; | |
| 1792 | |
| 1793 extern PRLogModuleInfo *_pr_clock_lm; | |
| 1794 extern PRLogModuleInfo *_pr_cmon_lm; | |
| 1795 extern PRLogModuleInfo *_pr_io_lm; | |
| 1796 extern PRLogModuleInfo *_pr_cvar_lm; | |
| 1797 extern PRLogModuleInfo *_pr_mon_lm; | |
| 1798 extern PRLogModuleInfo *_pr_linker_lm; | |
| 1799 extern PRLogModuleInfo *_pr_sched_lm; | |
| 1800 extern PRLogModuleInfo *_pr_thread_lm; | |
| 1801 extern PRLogModuleInfo *_pr_gc_lm; | |
| 1802 | |
| 1803 extern PRFileDesc *_pr_stdin; | |
| 1804 extern PRFileDesc *_pr_stdout; | |
| 1805 extern PRFileDesc *_pr_stderr; | |
| 1806 | |
| 1807 /* Zone allocator */ | |
| 1808 /* | |
| 1809 ** The zone allocator code has hardcoded pthread types and | |
| 1810 ** functions, so it can only be used in the pthreads version. | |
| 1811 ** This can be fixed by replacing the hardcoded pthread types | |
| 1812 ** and functions with macros that expand to the native thread | |
| 1813 ** types and functions on each platform. | |
| 1814 */ | |
| 1815 #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) | |
| 1816 #define _PR_ZONE_ALLOCATOR | |
| 1817 #endif | |
| 1818 | |
| 1819 #ifdef _PR_ZONE_ALLOCATOR | |
| 1820 extern void _PR_InitZones(void); | |
| 1821 extern void _PR_DestroyZones(void); | |
| 1822 #endif | |
| 1823 | |
| 1824 /* Overriding malloc, free, etc. */ | |
| 1825 #if !defined(_PR_NO_PREEMPT) && defined(XP_UNIX) \ | |
| 1826 && !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) \ | |
| 1827 && !defined(PURIFY) \ | |
| 1828 && !defined(DARWIN) \ | |
| 1829 && !defined(QNX) \ | |
| 1830 && !(defined (UNIXWARE) && defined (USE_SVR4_THREADS)) | |
| 1831 #define _PR_OVERRIDE_MALLOC | |
| 1832 #endif | |
| 1833 | |
| 1834 /************************************************************************* | |
| 1835 * External machine-dependent code provided by each OS. *
* | |
| 1836 *************************************************************************/ | |
| 1837 | |
| 1838 /* Initialization related */ | |
| 1839 extern void _PR_MD_EARLY_INIT(void); | |
| 1840 #define _PR_MD_EARLY_INIT _MD_EARLY_INIT | |
| 1841 | |
| 1842 extern void _PR_MD_INTERVAL_INIT(void); | |
| 1843 #define _PR_MD_INTERVAL_INIT _MD_INTERVAL_INIT | |
| 1844 | |
| 1845 NSPR_API(void) _PR_MD_FINAL_INIT(void); | |
| 1846 #define _PR_MD_FINAL_INIT _MD_FINAL_INIT | |
| 1847 | |
| 1848 extern void _PR_MD_EARLY_CLEANUP(void); | |
| 1849 #define _PR_MD_EARLY_CLEANUP _MD_EARLY_CLEANUP | |
| 1850 | |
| 1851 /* Process control */ | |
| 1852 | |
| 1853 extern PRProcess * _PR_MD_CREATE_PROCESS( | |
| 1854 const char *path, | |
| 1855 char *const *argv, | |
| 1856 char *const *envp, | |
| 1857 const PRProcessAttr *attr); | |
| 1858 #define _PR_MD_CREATE_PROCESS _MD_CREATE_PROCESS | |
| 1859 | |
| 1860 extern PRStatus _PR_MD_DETACH_PROCESS(PRProcess *process); | |
| 1861 #define _PR_MD_DETACH_PROCESS _MD_DETACH_PROCESS | |
| 1862 | |
| 1863 extern PRStatus _PR_MD_WAIT_PROCESS(PRProcess *process, PRInt32 *exitCode); | |
| 1864 #define _PR_MD_WAIT_PROCESS _MD_WAIT_PROCESS | |
| 1865 | |
| 1866 extern PRStatus _PR_MD_KILL_PROCESS(PRProcess *process); | |
| 1867 #define _PR_MD_KILL_PROCESS _MD_KILL_PROCESS | |
| 1868 | |
| 1869 /* Current Time */ | |
| 1870 NSPR_API(PRTime) _PR_MD_NOW(void); | |
| 1871 #define _PR_MD_NOW _MD_NOW | |
| 1872 | |
| 1873 /* Environment related */ | |
| 1874 extern char* _PR_MD_GET_ENV(const char *name); | |
| 1875 #define _PR_MD_GET_ENV _MD_GET_ENV | |
| 1876 | |
| 1877 extern PRIntn _PR_MD_PUT_ENV(const char *name); | |
| 1878 #define _PR_MD_PUT_ENV _MD_PUT_ENV | |
| 1879 | |
| 1880 /* Atomic operations */ | |
| 1881 | |
| 1882 extern void _PR_MD_INIT_ATOMIC(void); | |
| 1883 #define _PR_MD_INIT_ATOMIC _MD_INIT_ATOMIC | |
| 1884 | |
| 1885 extern PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *); | |
| 1886 #define _PR_MD_ATOMIC_INCREMENT _MD_ATOMIC_INCREMENT | |
| 1887 | |
| 1888 extern PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *, PRInt32); | |
| 1889 #define _PR_MD_ATOMIC_ADD _MD_ATOMIC_ADD | |
| 1890 | |
| 1891 extern PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *); | |
| 1892 #define _PR_MD_ATOMIC_DECREMENT _MD_ATOMIC_DECREMENT | |
| 1893 | |
| 1894 extern PRInt32 _PR_MD_ATOMIC_SET(PRInt32 *, PRInt32); | |
| 1895 #define _PR_MD_ATOMIC_SET _MD_ATOMIC_SET | |
| 1896 | |
| 1897 /* Garbage collection */ | |
| 1898 | |
| 1899 /* | |
| 1900 ** Save the registers that the GC would find interesting into the thread | |
| 1901 ** "t". isCurrent will be non-zero if the thread state that is being | |
| 1902 ** saved is the currently executing thread. Return the address of the | |
| 1903 ** first register to be scanned as well as the number of registers to | |
| 1904 ** scan in "np". | |
| 1905 ** | |
| 1906 ** If "isCurrent" is non-zero then it is allowed for the thread context | |
| 1907 ** area to be used as scratch storage to hold just the registers | |
| 1908 ** necessary for scanning. | |
| 1909 */ | |
| 1910 extern PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np); | |
| 1911 | |
| 1912 /* Time intervals */ | |
| 1913 | |
| 1914 extern PRIntervalTime _PR_MD_GET_INTERVAL(void); | |
| 1915 #define _PR_MD_GET_INTERVAL _MD_GET_INTERVAL | |
| 1916 | |
| 1917 extern PRIntervalTime _PR_MD_INTERVAL_PER_SEC(void); | |
| 1918 #define _PR_MD_INTERVAL_PER_SEC _MD_INTERVAL_PER_SEC | |
| 1919 | |
| 1920 /* Affinity masks */ | |
| 1921 | |
| 1922 extern PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask ); | |
| 1923 #define _PR_MD_SETTHREADAFFINITYMASK _MD_SETTHREADAFFINITYMASK | |
| 1924 | |
| 1925 extern PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask); | |
| 1926 #define _PR_MD_GETTHREADAFFINITYMASK _MD_GETTHREADAFFINITYMASK | |
| 1927 | |
| 1928 /* File locking */ | |
| 1929 | |
| 1930 extern PRStatus _PR_MD_LOCKFILE(PROsfd osfd); | |
| 1931 #define _PR_MD_LOCKFILE _MD_LOCKFILE | |
| 1932 | |
| 1933 extern PRStatus _PR_MD_TLOCKFILE(PROsfd osfd); | |
| 1934 #define _PR_MD_TLOCKFILE _MD_TLOCKFILE | |
| 1935 | |
| 1936 extern PRStatus _PR_MD_UNLOCKFILE(PROsfd osfd); | |
| 1937 #define _PR_MD_UNLOCKFILE _MD_UNLOCKFILE | |
| 1938 | |
| 1939 /* Memory-mapped files */ | |
| 1940 | |
| 1941 extern PRStatus _PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size); | |
| 1942 #define _PR_MD_CREATE_FILE_MAP _MD_CREATE_FILE_MAP | |
| 1943 | |
| 1944 extern PRInt32 _PR_MD_GET_MEM_MAP_ALIGNMENT(void); | |
| 1945 #define _PR_MD_GET_MEM_MAP_ALIGNMENT _MD_GET_MEM_MAP_ALIGNMENT | |
| 1946 | |
| 1947 extern void * _PR_MD_MEM_MAP( | |
| 1948 PRFileMap *fmap, | |
| 1949 PROffset64 offset, | |
| 1950 PRUint32 len); | |
| 1951 #define _PR_MD_MEM_MAP _MD_MEM_MAP | |
| 1952 | |
| 1953 extern PRStatus _PR_MD_MEM_UNMAP(void *addr, PRUint32 size); | |
| 1954 #define _PR_MD_MEM_UNMAP _MD_MEM_UNMAP | |
| 1955 | |
| 1956 extern PRStatus _PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap); | |
| 1957 #define _PR_MD_CLOSE_FILE_MAP _MD_CLOSE_FILE_MAP | |
| 1958 | |
| 1959 /* Named Shared Memory */ | |
| 1960 | |
| 1961 /* | |
| 1962 ** Declare PRSharedMemory. | |
| 1963 */ | |
| 1964 struct PRSharedMemory | |
| 1965 { | |
| 1966 char *ipcname; /* after conversion to native */ | |
| 1967 PRSize size; /* from open */ | |
| 1968 PRIntn mode; /* from open */ | |
| 1969 PRIntn flags; /* from open */ | |
| 1970 #if defined(PR_HAVE_POSIX_NAMED_SHARED_MEMORY) | |
| 1971 int id; | |
| 1972 #elif defined(PR_HAVE_SYSV_NAMED_SHARED_MEMORY) | |
| 1973 int id; | |
| 1974 #elif defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY) | |
| 1975 HANDLE handle; | |
| 1976 #else | |
| 1977 PRUint32 nothing; /* placeholder, nothing behind here */ | |
| 1978 #endif | |
| 1979 PRUint32 ident; /* guard word at end of struct */ | |
| 1980 #define _PR_SHM_IDENT 0xdeadbad | |
| 1981 }; | |
| 1982 | |
| 1983 extern PRSharedMemory * _MD_OpenSharedMemory( | |
| 1984 const char *name, | |
| 1985 PRSize size, | |
| 1986 PRIntn flags, | |
| 1987 PRIntn mode | |
| 1988 ); | |
| 1989 #define _PR_MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory | |
| 1990 | |
| 1991 extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ); | |
| 1992 #define _PR_MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory | |
| 1993 | |
| 1994 extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ); | |
| 1995 #define _PR_MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory | |
| 1996 | |
| 1997 extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ); | |
| 1998 #define _PR_MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory | |
| 1999 | |
| 2000 extern PRStatus _MD_DeleteSharedMemory( const char *name ); | |
| 2001 #define _PR_MD_DELETE_SHARED_MEMORY _MD_DeleteSharedMemory | |
| 2002 | |
| 2003 extern PRFileMap* _md_OpenAnonFileMap( | |
| 2004 const char *dirName, | |
| 2005 PRSize size, | |
| 2006 PRFileMapProtect prot | |
| 2007 ); | |
| 2008 #define _PR_MD_OPEN_ANON_FILE_MAP _md_OpenAnonFileMap | |
| 2009 | |
| 2010 extern PRStatus _md_ExportFileMapAsString( | |
| 2011 PRFileMap *fm, | |
| 2012 PRSize bufSize, | |
| 2013 char *buf | |
| 2014 ); | |
| 2015 #define _PR_MD_EXPORT_FILE_MAP_AS_STRING _md_ExportFileMapAsString | |
| 2016 | |
| 2017 extern PRFileMap * _md_ImportFileMapFromString( | |
| 2018 const char *fmstring | |
| 2019 ); | |
| 2020 #define _PR_MD_IMPORT_FILE_MAP_FROM_STRING _md_ImportFileMapFromString | |
| 2021 | |
| 2022 | |
| 2023 | |
| 2024 /* Interprocess communications (IPC) */ | |
| 2025 | |
| 2026 /* | |
| 2027 * The maximum length of an NSPR IPC name, including the | |
| 2028 * terminating null byte. | |
| 2029 */ | |
| 2030 #define PR_IPC_NAME_SIZE 1024 | |
| 2031 | |
| 2032 /* | |
| 2033 * Types of NSPR IPC objects | |
| 2034 */ | |
| 2035 typedef enum { | |
| 2036 _PRIPCSem, /* semaphores */ | |
| 2037 _PRIPCShm /* shared memory segments */ | |
| 2038 } _PRIPCType; | |
| 2039 | |
| 2040 /* | |
| 2041 * Make a native IPC name from an NSPR IPC name. | |
| 2042 */ | |
| 2043 extern PRStatus _PR_MakeNativeIPCName( | |
| 2044 const char *name, /* NSPR IPC name */ | |
| 2045 char *result, /* result buffer */ | |
| 2046 PRIntn size, /* size of result buffer */ | |
| 2047 _PRIPCType type /* type of IPC object */ | |
| 2048 ); | |
| 2049 | |
| 2050 /* Socket call error code */ | |
| 2051 | |
| 2052 NSPR_API(PRInt32) _PR_MD_GET_SOCKET_ERROR(void); | |
| 2053 #define _PR_MD_GET_SOCKET_ERROR _MD_GET_SOCKET_ERROR | |
| 2054 | |
| 2055 /* Get name of current host */ | |
| 2056 extern PRStatus _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen); | |
| 2057 #define _PR_MD_GETHOSTNAME _MD_GETHOSTNAME | |
| 2058 | |
| 2059 extern PRStatus _PR_MD_GETSYSINFO(PRSysInfo cmd, char *name, PRUint32 namelen); | |
| 2060 #define _PR_MD_GETSYSINFO _MD_GETSYSINFO | |
| 2061 | |
| 2062 /* File descriptor inheritance */ | |
| 2063 | |
| 2064 /* | |
| 2065 * If fd->secret->inheritable is _PR_TRI_UNKNOWN and we need to | |
| 2066 * know the inheritable attribute of the fd, call this function | |
| 2067 * to find that out. This typically requires a system call. | |
| 2068 */ | |
| 2069 extern void _PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd); | |
| 2070 #define _PR_MD_QUERY_FD_INHERITABLE _MD_QUERY_FD_INHERITABLE | |
| 2071 | |
| 2072 /* --- PR_GetRandomNoise() related things --- */ | |
| 2073 | |
| 2074 extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size ); | |
| 2075 #define _PR_MD_GET_RANDOM_NOISE(buf,size) _PR_MD_GetRandomNoise((buf),(size)) | |
| 2076 extern PRSize _pr_CopyLowBits( void *dest, PRSize dstlen, void *src, PRSize srcl
en ); | |
| 2077 | |
| 2078 /* end PR_GetRandomNoise() related */ | |
| 2079 | |
| 2080 #ifdef XP_BEOS | |
| 2081 | |
| 2082 extern PRLock *_connectLock; | |
| 2083 | |
| 2084 typedef struct _ConnectListNode { | |
| 2085 PRInt32 osfd; | |
| 2086 PRNetAddr addr; | |
| 2087 PRUint32 addrlen; | |
| 2088 PRIntervalTime timeout; | |
| 2089 } ConnectListNode; | |
| 2090 | |
| 2091 extern ConnectListNode connectList[64]; | |
| 2092 | |
| 2093 extern PRUint32 connectCount; | |
| 2094 | |
| 2095 #endif /* XP_BEOS */ | |
| 2096 | |
| 2097 PR_END_EXTERN_C | |
| 2098 | |
| 2099 #endif /* primpl_h___ */ | |
| OLD | NEW |