VirtualBox

Changeset 101805 in vbox for trunk/src/libs/xpcom18a4


Ignore:
Timestamp:
Nov 5, 2023 9:36:46 AM (17 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
159901
Message:

libs/xpcom: Start cutting out code only built when _PR_PTHREADS is not set which is never the case for us, bugref:10545

Location:
trunk/src/libs/xpcom18a4
Files:
2 deleted
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/Makefile.kmk

    r101804 r101805  
    523523        nsprpub/pr/src/linking/prlink.c \
    524524        nsprpub/pr/src/md/prosdep.c \
    525         nsprpub/pr/src/memory/prseg.c \
    526525        nsprpub/pr/src/memory/prshm.c \
    527526        nsprpub/pr/src/memory/prshma.c \
  • trunk/src/libs/xpcom18a4/nsprpub/pr/include/private/primpl.h

    r101777 r101805  
    4747 */
    4848
    49 #if defined(_PR_PTHREADS)
    5049#include <pthread.h>
    51 #endif
    52 
    53 #if defined(_PR_BTHREADS)
    54 #include <kernel/OS.h>
    55 #endif
    56 
    57 #ifdef WINNT
    58 /* Need to force service-pack 3 extensions to be defined by
    59 ** setting _WIN32_WINNT to NT 4.0 for winsock.h, winbase.h, winnt.h.
    60 */
    61 #ifndef  _WIN32_WINNT
    62     #define _WIN32_WINNT 0x0400
    63 #elif   (_WIN32_WINNT < 0x0400)
    64     #undef  _WIN32_WINNT
    65     #define _WIN32_WINNT 0x0400
    66 #endif /* _WIN32_WINNT */
    67 #endif /* WINNT */
    6850
    6951#include "nspr.h"
     
    159141typedef struct _MDFileMap _MDFileMap;
    160142
    161 #if defined(_PR_PTHREADS)
    162 
    163143/*
    164144** The following definitions are unique to implementing NSPR using pthreads.
     
    225205
    226206NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
    227 
    228 #else /* defined(_PR_PTHREADS) */
    229 
    230 NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
    231 
    232 /*
    233 ** This section is contains those parts needed to implement NSPR on
    234 ** platforms in general. One would assume that the pthreads implementation
    235 ** included lots of the same types, at least conceptually.
    236 */
    237 
    238 /*
    239  * Local threads only.  No multiple CPU support and hence all the
    240  * following routines are no-op.
    241  */
    242 #ifdef _PR_LOCAL_THREADS_ONLY
    243 
    244 #define        _PR_MD_SUSPEND_THREAD(thread)
    245 #define        _PR_MD_RESUME_THREAD(thread)
    246 #define        _PR_MD_SUSPEND_CPU(cpu)
    247 #define        _PR_MD_RESUME_CPU(cpu)
    248 #define        _PR_MD_BEGIN_SUSPEND_ALL()
    249 #define        _PR_MD_END_SUSPEND_ALL()
    250 #define        _PR_MD_BEGIN_RESUME_ALL()
    251 #define        _PR_MD_END_RESUME_ALL()
    252 #define _PR_MD_INIT_ATTACHED_THREAD(thread) PR_FAILURE
    253 
    254 #endif
    255 
    256 typedef struct _PRCPUQueue _PRCPUQueue;
    257 typedef struct _PRCPU _PRCPU;
    258 typedef struct _MDCPU _MDCPU;
    259 
    260 struct _PRCPUQueue {
    261     _MDLock  runQLock;          /* lock for the run + wait queues */
    262     _MDLock  sleepQLock;        /* lock for the run + wait queues */
    263     _MDLock  miscQLock;         /* lock for the run + wait queues */
    264 
    265     PRCList runQ[PR_PRIORITY_LAST + 1]; /* run queue for this CPU */
    266     PRUint32  runQReadyMask;
    267     PRCList sleepQ;
    268     PRIntervalTime sleepQmax;
    269     PRCList pauseQ;
    270     PRCList suspendQ;
    271     PRCList waitingToJoinQ;
    272 
    273     PRUintn   numCPUs;          /* number of CPUs using this Q */
    274 };
    275 
    276 struct _PRCPU {
    277     PRCList links;              /* link list of CPUs */
    278     PRUint32 id;                /* id for this CPU */
    279 
    280     union {
    281         PRInt32 bits;
    282         PRUint8 missed[4];
    283     } u;
    284     PRIntn where;               /* index into u.missed */
    285     PRPackedBool paused;        /* cpu is paused */
    286     PRPackedBool exit;          /* cpu should exit */
    287 
    288     PRThread *thread;           /* native thread for this CPUThread */
    289     PRThread *idle_thread;      /* user-level idle thread for this CPUThread */
    290 
    291     PRIntervalTime last_clock;  /* the last time we went into
    292                                  * _PR_ClockInterrupt() on this CPU
    293                                  */
    294 
    295     _PRCPUQueue *queue;
    296 
    297     _MDCPU md;
    298 };
    299 
    300 typedef struct _PRInterruptTable {
    301     const char *name;
    302     PRUintn missed_bit;
    303     void (*handler)(void);
    304 } _PRInterruptTable;
    305 
    306 #define _PR_CPU_PTR(_qp) \
    307     ((_PRCPU*) ((char*) (_qp) - offsetof(_PRCPU,links)))
    308 
    309 #if !defined(IRIX) && !defined(WIN32) && !defined(XP_OS2) \
    310         && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY))
    311 #define _MD_GET_ATTACHED_THREAD()        (_PR_MD_CURRENT_THREAD())
    312 #endif
    313 
    314 #ifdef _PR_LOCAL_THREADS_ONLY
    315 
    316 NSPR_API(struct _PRCPU *)              _pr_currentCPU;
    317 NSPR_API(PRThread *)                   _pr_currentThread;
    318 NSPR_API(PRThread *)                   _pr_lastThread;
    319 NSPR_API(PRInt32)                      _pr_intsOff;
    320 
    321 #define _MD_CURRENT_CPU()               (_pr_currentCPU)
    322 #define _MD_SET_CURRENT_CPU(_cpu)       (_pr_currentCPU = (_cpu))
    323 #define _MD_CURRENT_THREAD()            (_pr_currentThread)
    324 #define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread))
    325 #define _MD_LAST_THREAD()               (_pr_lastThread)
    326 #define _MD_SET_LAST_THREAD(t)          (_pr_lastThread = t)
    327 
    328 #ifndef XP_MAC
    329 #define _MD_GET_INTSOFF()               (_pr_intsOff)
    330 #define _MD_SET_INTSOFF(_val)           (_pr_intsOff = _val)
    331 #endif
    332 
    333 
    334 /* The unbalanced curly braces in these two macros are intentional */
    335 #define _PR_LOCK_HEAP() { PRIntn _is; if (_pr_currentCPU) _PR_INTSOFF(_is);
    336 #define _PR_UNLOCK_HEAP() if (_pr_currentCPU) _PR_INTSON(_is); }
    337 
    338 #endif /* _PR_LOCAL_THREADS_ONLY */
    339 
    340 extern PRInt32                  _native_threads_only;
    341 
    342 #if defined(_PR_GLOBAL_THREADS_ONLY)
    343 
    344 #define _MD_GET_INTSOFF() 0
    345 #define _MD_SET_INTSOFF(_val)
    346 #define _PR_INTSOFF(_is)
    347 #define _PR_FAST_INTSON(_is)
    348 #define _PR_INTSON(_is)
    349 #define _PR_THREAD_LOCK(_thread)
    350 #define _PR_THREAD_UNLOCK(_thread)
    351 #define _PR_RUNQ_LOCK(cpu)
    352 #define _PR_RUNQ_UNLOCK(cpu)
    353 #define _PR_SLEEPQ_LOCK(thread)
    354 #define _PR_SLEEPQ_UNLOCK(thread)
    355 #define _PR_MISCQ_LOCK(thread)
    356 #define _PR_MISCQ_UNLOCK(thread)
    357 #define _PR_CPU_LIST_LOCK()
    358 #define _PR_CPU_LIST_UNLOCK()
    359 
    360 #define _PR_ADD_RUNQ(_thread, _cpu, _pri)
    361 #define _PR_DEL_RUNQ(_thread)
    362 #define _PR_ADD_SLEEPQ(_thread, _timeout)
    363 #define _PR_DEL_SLEEPQ(_thread, _propogate)
    364 #define _PR_ADD_JOINQ(_thread, _cpu)
    365 #define _PR_DEL_JOINQ(_thread)
    366 #define _PR_ADD_SUSPENDQ(_thread, _cpu)
    367 #define _PR_DEL_SUSPENDQ(_thread)
    368 
    369 #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU)
    370 
    371 #define _PR_IS_NATIVE_THREAD(thread) 1
    372 #define _PR_IS_NATIVE_THREAD_SUPPORTED() 1
    373 
    374 #else
    375 
    376 #ifdef XP_MAC
    377 
    378 #define _PR_INTSOFF(_is)        _MD_INTSOFF(_is)
    379 
    380 #else /* XP_MAC */
    381 
    382 #define _PR_INTSOFF(_is) \
    383     PR_BEGIN_MACRO \
    384         (_is) = _PR_MD_GET_INTSOFF(); \
    385         _PR_MD_SET_INTSOFF(1); \
    386     PR_END_MACRO
    387 
    388 #endif /* XP_MAC */
    389 
    390 #define _PR_FAST_INTSON(_is) \
    391     PR_BEGIN_MACRO \
    392         _PR_MD_SET_INTSOFF(_is); \
    393     PR_END_MACRO
    394 
    395 #define _PR_INTSON(_is) \
    396     PR_BEGIN_MACRO \
    397         if ((_is == 0) && (_PR_MD_CURRENT_CPU())->u.bits) \
    398                 _PR_IntsOn((_PR_MD_CURRENT_CPU())); \
    399         _PR_MD_SET_INTSOFF(_is); \
    400     PR_END_MACRO
    401 
    402 #ifdef _PR_LOCAL_THREADS_ONLY
    403 
    404 #define _PR_IS_NATIVE_THREAD(thread) 0
    405 #define _PR_THREAD_LOCK(_thread)
    406 #define _PR_THREAD_UNLOCK(_thread)
    407 #define _PR_RUNQ_LOCK(cpu)
    408 #define _PR_RUNQ_UNLOCK(cpu)
    409 #define _PR_SLEEPQ_LOCK(thread)
    410 #define _PR_SLEEPQ_UNLOCK(thread)
    411 #define _PR_MISCQ_LOCK(thread)
    412 #define _PR_MISCQ_UNLOCK(thread)
    413 #define _PR_CPU_LIST_LOCK()
    414 #define _PR_CPU_LIST_UNLOCK()
    415 
    416 #define _PR_ADD_RUNQ(_thread, _cpu, _pri) \
    417     PR_BEGIN_MACRO \
    418     PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \
    419     _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \
    420     PR_END_MACRO
    421 
    422 #define _PR_DEL_RUNQ(_thread) \
    423     PR_BEGIN_MACRO \
    424     _PRCPU *_cpu = _thread->cpu; \
    425     PRInt32 _pri = _thread->priority; \
    426     PR_REMOVE_LINK(&(_thread)->links); \
    427     if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \
    428         _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \
    429     PR_END_MACRO
    430 
    431 #define _PR_ADD_SLEEPQ(_thread, _timeout) \
    432     _PR_AddSleepQ(_thread, _timeout);
    433 
    434 #define _PR_DEL_SLEEPQ(_thread, _propogate) \
    435     _PR_DelSleepQ(_thread, _propogate);
    436 
    437 #define _PR_ADD_JOINQ(_thread, _cpu) \
    438     PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu));
    439 
    440 #define _PR_DEL_JOINQ(_thread) \
    441     PR_REMOVE_LINK(&(_thread)->links);
    442 
    443 #define _PR_ADD_SUSPENDQ(_thread, _cpu) \
    444     PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu));
    445 
    446 #define _PR_DEL_SUSPENDQ(_thread) \
    447     PR_REMOVE_LINK(&(_thread)->links);
    448 
    449 #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU)
    450 
    451 #define _PR_IS_NATIVE_THREAD_SUPPORTED() 0
    452 
    453 #else        /* _PR_LOCAL_THREADS_ONLY */
    454 
    455 /* These are for the "combined" thread model */
    456 
    457 #define _PR_THREAD_LOCK(_thread) \
    458     _PR_MD_LOCK(&(_thread)->threadLock);
    459 
    460 #define _PR_THREAD_UNLOCK(_thread) \
    461     _PR_MD_UNLOCK(&(_thread)->threadLock);
    462 
    463 #define _PR_RUNQ_LOCK(_cpu) \
    464     PR_BEGIN_MACRO \
    465     _PR_MD_LOCK(&(_cpu)->queue->runQLock );\
    466     PR_END_MACRO
    467 
    468 #define _PR_RUNQ_UNLOCK(_cpu) \
    469     PR_BEGIN_MACRO \
    470     _PR_MD_UNLOCK(&(_cpu)->queue->runQLock );\
    471     PR_END_MACRO
    472 
    473 #define _PR_SLEEPQ_LOCK(_cpu) \
    474     _PR_MD_LOCK(&(_cpu)->queue->sleepQLock );
    475 
    476 #define _PR_SLEEPQ_UNLOCK(_cpu) \
    477     _PR_MD_UNLOCK(&(_cpu)->queue->sleepQLock );
    478 
    479 #define _PR_MISCQ_LOCK(_cpu) \
    480     _PR_MD_LOCK(&(_cpu)->queue->miscQLock );
    481 
    482 #define _PR_MISCQ_UNLOCK(_cpu) \
    483     _PR_MD_UNLOCK(&(_cpu)->queue->miscQLock );
    484 
    485 #define _PR_CPU_LIST_LOCK()                 _PR_MD_LOCK(&_pr_cpuLock)
    486 #define _PR_CPU_LIST_UNLOCK()               _PR_MD_UNLOCK(&_pr_cpuLock)
    487 
    488 #define QUEUE_RUN           0x1
    489 #define QUEUE_SLEEP         0x2
    490 #define QUEUE_JOIN          0x4
    491 #define QUEUE_SUSPEND       0x8
    492 #define QUEUE_LOCK          0x10
    493 
    494 #define _PR_ADD_RUNQ(_thread, _cpu, _pri) \
    495     PR_BEGIN_MACRO \
    496     PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \
    497     _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \
    498     PR_ASSERT((_thread)->queueCount == 0); \
    499     (_thread)->queueCount = QUEUE_RUN; \
    500     PR_END_MACRO
    501 
    502 #define _PR_DEL_RUNQ(_thread) \
    503     PR_BEGIN_MACRO \
    504     _PRCPU *_cpu = _thread->cpu; \
    505     PRInt32 _pri = _thread->priority; \
    506     PR_REMOVE_LINK(&(_thread)->links); \
    507     if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \
    508         _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \
    509     PR_ASSERT((_thread)->queueCount == QUEUE_RUN);\
    510     (_thread)->queueCount = 0; \
    511     PR_END_MACRO
    512 
    513 #define _PR_ADD_SLEEPQ(_thread, _timeout) \
    514     PR_ASSERT((_thread)->queueCount == 0); \
    515     (_thread)->queueCount = QUEUE_SLEEP; \
    516     _PR_AddSleepQ(_thread, _timeout);
    517 
    518 #define _PR_DEL_SLEEPQ(_thread, _propogate) \
    519     PR_ASSERT((_thread)->queueCount == QUEUE_SLEEP);\
    520     (_thread)->queueCount = 0; \
    521     _PR_DelSleepQ(_thread, _propogate);
    522 
    523 #define _PR_ADD_JOINQ(_thread, _cpu) \
    524     PR_ASSERT((_thread)->queueCount == 0); \
    525     (_thread)->queueCount = QUEUE_JOIN; \
    526     PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu));
    527 
    528 #define _PR_DEL_JOINQ(_thread) \
    529     PR_ASSERT((_thread)->queueCount == QUEUE_JOIN);\
    530     (_thread)->queueCount = 0; \
    531     PR_REMOVE_LINK(&(_thread)->links);
    532 
    533 #define _PR_ADD_SUSPENDQ(_thread, _cpu) \
    534     PR_ASSERT((_thread)->queueCount == 0); \
    535     (_thread)->queueCount = QUEUE_SUSPEND; \
    536     PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu));
    537 
    538 #define _PR_DEL_SUSPENDQ(_thread) \
    539     PR_ASSERT((_thread)->queueCount == QUEUE_SUSPEND);\
    540     (_thread)->queueCount = 0; \
    541     PR_REMOVE_LINK(&(_thread)->links);
    542 
    543 #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) \
    544     (_thread)->cpu = (_newCPU);
    545 
    546 #define _PR_IS_NATIVE_THREAD(thread) (thread->flags & _PR_GLOBAL_SCOPE)
    547 #define _PR_IS_NATIVE_THREAD_SUPPORTED() 1
    548 
    549 #endif /* _PR_LOCAL_THREADS_ONLY */
    550 
    551 #endif /* _PR_GLOBAL_THREADS_ONLY */
    552 
    553 #define _PR_SET_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 1
    554 #define _PR_CLEAR_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 0
    555 
    556 extern _PRInterruptTable _pr_interruptTable[];
    557 
    558 /* Bits for _pr_interruptState.u.missed[0,1] */
    559 #define _PR_MISSED_CLOCK    0x1
    560 #define _PR_MISSED_IO        0x2
    561 #define _PR_MISSED_CHILD    0x4
    562 
    563 extern void _PR_IntsOn(_PRCPU *cpu);
    564 
    565 NSPR_API(void) _PR_WakeupCPU(void);
    566 NSPR_API(void) _PR_PauseCPU(void);
    567 
    568 /************************************************************************/
    569 
    570 #define _PR_LOCK_LOCK(_lock) \
    571     _PR_MD_LOCK(&(_lock)->ilock);
    572 #define _PR_LOCK_UNLOCK(_lock) \
    573     _PR_MD_UNLOCK(&(_lock)->ilock);
    574 
    575 extern void _PR_UnblockLockWaiter(PRLock *lock);
    576 
    577 #define _PR_LOCK_PTR(_qp) \
    578     ((PRLock*) ((char*) (_qp) - offsetof(PRLock,links)))
    579 
    580 /************************************************************************/
    581 
    582 #define _PR_CVAR_LOCK(_cvar) \
    583     _PR_MD_LOCK(&(_cvar)->ilock);
    584 #define _PR_CVAR_UNLOCK(_cvar) \
    585     _PR_MD_UNLOCK(&(_cvar)->ilock);
    586 
    587 extern PRStatus _PR_WaitCondVar(
    588     PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout);
    589 extern PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen);
    590 
    591 NSPR_API(void) _PR_Notify(PRMonitor *mon, PRBool all, PRBool sticky);
    592 
    593 /* PRThread.flags */
    594 #define _PR_SYSTEM          0x01
    595 #define _PR_INTERRUPT       0x02
    596 #define _PR_ATTACHED        0x04        /* created via PR_AttachThread */
    597 #define _PR_PRIMORDIAL      0x08        /* the thread that called PR_Init */
    598 #define _PR_ON_SLEEPQ       0x10        /* thread is on the sleepQ */
    599 #define _PR_ON_PAUSEQ       0x20        /* thread is on the pauseQ */
    600 #define _PR_SUSPENDING      0x40        /* thread wants to suspend */
    601 #define _PR_GLOBAL_SCOPE    0x80        /* thread is global scope */
    602 #define _PR_IDLE_THREAD     0x200       /* this is an idle thread        */
    603 #define _PR_GCABLE_THREAD   0x400       /* this is a collectable thread */
    604 #define _PR_BOUND_THREAD    0x800       /* a bound thread */
    605 #define _PR_INTERRUPT_BLOCKED   0x1000  /* interrupts blocked */
    606 
    607 /* PRThread.state */
    608 #define _PR_UNBORN       0
    609 #define _PR_RUNNABLE     1
    610 #define _PR_RUNNING      2
    611 #define _PR_LOCK_WAIT    3
    612 #define _PR_COND_WAIT    4
    613 #define _PR_JOIN_WAIT    5
    614 #define _PR_IO_WAIT      6
    615 #define _PR_SUSPENDED    7
    616 #define _PR_DEAD_STATE   8  /* for debugging */
    617 
    618 /* PRThreadStack.flags */
    619 #define _PR_STACK_VM            0x1    /* using vm instead of malloc */
    620 #define _PR_STACK_MAPPED        0x2    /* vm is mapped */
    621 #define _PR_STACK_PRIMORDIAL    0x4    /* stack for primordial thread */
    622 
    623 /*
    624 ** If the default stcksize from the client is zero, we need to pick a machine
    625 ** dependent value.  This is only for standard user threads.  For custom threads,
    626 ** 0 has a special meaning.
    627 ** Adjust stackSize. Round up to a page boundary.
    628 */
    629 
    630 #ifndef _MD_MINIMUM_STACK_SIZE
    631 #define _MD_MINIMUM_STACK_SIZE  0
    632 #endif
    633 
    634 #if (!defined(HAVE_CUSTOM_USER_THREADS))
    635 #define        _PR_ADJUST_STACKSIZE(stackSize) \
    636         PR_BEGIN_MACRO \
    637     if (stackSize == 0) \
    638                 stackSize = _MD_DEFAULT_STACK_SIZE; \
    639     if (stackSize < _MD_MINIMUM_STACK_SIZE) \
    640                 stackSize = _MD_MINIMUM_STACK_SIZE; \
    641     stackSize = (stackSize + (1 << _pr_pageShift) - 1) >> _pr_pageShift; \
    642     stackSize <<= _pr_pageShift; \
    643         PR_END_MACRO
    644 #else
    645 #define        _PR_ADJUST_STACKSIZE(stackSize)
    646 #endif
    647 
    648 #define _PR_IS_GCABLE_THREAD(thr) ((thr)->flags & _PR_GCABLE_THREAD)
    649 
    650 #define _PR_PENDING_INTERRUPT(thr)                                      \
    651                 (!((thr)->flags & _PR_INTERRUPT_BLOCKED) && ((thr)->flags & _PR_INTERRUPT))
    652 #define _PR_THREAD_BLOCK_INTERRUPT(thr)                 \
    653                 (thr->flags |= _PR_INTERRUPT_BLOCKED)
    654 #define _PR_THREAD_UNBLOCK_INTERRUPT(thr)                       \
    655                 (thr->flags &= ~_PR_INTERRUPT_BLOCKED)
    656 
    657 #define _PR_THREAD_PTR(_qp) \
    658     ((PRThread*) ((char*) (_qp) - offsetof(PRThread,links)))
    659 
    660 #define _PR_ACTIVE_THREAD_PTR(_qp) \
    661     ((PRThread*) ((char*) (_qp) - offsetof(PRThread,active)))
    662 
    663 #define _PR_THREAD_CONDQ_PTR(_qp) \
    664     ((PRThread*) ((char*) (_qp) - offsetof(PRThread,waitQLinks)))
    665 
    666 #define _PR_THREAD_MD_TO_PTR(_md) \
    667     ((PRThread*) ((char*) (_md) - offsetof(PRThread,md)))
    668 
    669 #define _PR_THREAD_STACK_TO_PTR(_stack) \
    670     ((PRThread*) (_stack->thr))
    671 
    672 extern PRCList _pr_active_local_threadQ;
    673 extern PRCList _pr_active_global_threadQ;
    674 extern PRCList _pr_cpuQ;
    675 extern _MDLock  _pr_cpuLock;
    676 extern PRInt32 _pr_md_idle_cpus;
    677 
    678 #define _PR_ACTIVE_LOCAL_THREADQ()          _pr_active_local_threadQ
    679 #define _PR_ACTIVE_GLOBAL_THREADQ()         _pr_active_global_threadQ
    680 #define _PR_CPUQ()                          _pr_cpuQ
    681 #define _PR_RUNQ(_cpu)                      ((_cpu)->queue->runQ)
    682 #define _PR_RUNQREADYMASK(_cpu)             ((_cpu)->queue->runQReadyMask)
    683 #define _PR_SLEEPQ(_cpu)                    ((_cpu)->queue->sleepQ)
    684 #define _PR_SLEEPQMAX(_cpu)                 ((_cpu)->queue->sleepQmax)
    685 #define _PR_PAUSEQ(_cpu)                    ((_cpu)->queue->pauseQ)
    686 #define _PR_SUSPENDQ(_cpu)                  ((_cpu)->queue->suspendQ)
    687 #define _PR_WAITINGTOJOINQ(_cpu)            ((_cpu)->queue->waitingToJoinQ)
    688 
    689 extern PRUint32 _pr_recycleThreads;   /* Flag for behavior on thread cleanup */
    690 extern PRLock *_pr_deadQLock;
    691 extern PRUint32 _pr_numNativeDead;
    692 extern PRUint32 _pr_numUserDead;
    693 extern PRCList _pr_deadNativeQ;
    694 extern PRCList _pr_deadUserQ;
    695 #define _PR_DEADNATIVEQ     _pr_deadNativeQ
    696 #define _PR_DEADUSERQ       _pr_deadUserQ
    697 #define _PR_DEADQ_LOCK      PR_Lock(_pr_deadQLock);
    698 #define _PR_DEADQ_UNLOCK    PR_Unlock(_pr_deadQLock);
    699 #define _PR_INC_DEADNATIVE  (_pr_numNativeDead++)
    700 #define _PR_DEC_DEADNATIVE  (_pr_numNativeDead--)
    701 #define _PR_NUM_DEADNATIVE  (_pr_numNativeDead)
    702 #define _PR_INC_DEADUSER    (_pr_numUserDead++)
    703 #define _PR_DEC_DEADUSER    (_pr_numUserDead--)
    704 #define _PR_NUM_DEADUSER    (_pr_numUserDead)
    705 
    706 extern PRUint32 _pr_utid;
    707 
    708 extern struct _PRCPU  *_pr_primordialCPU;
    709 
    710 extern PRLock *_pr_activeLock;          /* lock for userActive and systemActive */
    711 extern PRInt32 _pr_userActive;          /* number of active user threads */
    712 extern PRInt32 _pr_systemActive;        /* number of active system threads */
    713 extern PRInt32 _pr_primordialExitCount; /* number of user threads left
    714                                          * before the primordial thread
    715                                          * can exit.  */
    716 extern PRCondVar *_pr_primordialExitCVar; /* the condition variable for
    717                                            * notifying the primordial thread
    718                                            * when all other user threads
    719                                            * have terminated.  */
    720 
    721 extern PRUintn _pr_maxPTDs;
    722 
    723 extern PRLock *_pr_terminationCVLock;
    724 
    725 /*************************************************************************
    726 * Internal routines either called by PR itself or from machine-dependent *
    727 * code.                                                                  *
    728 *************************************************************************/
    729 
    730 extern void _PR_ClockInterrupt(void);
    731 
    732 extern void _PR_Schedule(void);
    733 extern void _PR_SetThreadPriority(
    734     PRThread* thread, PRThreadPriority priority);
    735 
    736 /***********************************************************************
    737 ** FUNCTION:    _PR_NewSegment()
    738 ** DESCRIPTION:
    739 **   Allocate a memory segment. The "size" value is rounded up to the
    740 **   native system page size and a page aligned portion of memory is
    741 **   returned.  This memory is not part of the malloc heap. If "vaddr" is
    742 **   not NULL then PR tries to allocate the segment at the desired virtual
    743 **   address.
    744 ** INPUTS:      size:  size of the desired memory segment
    745 **          vaddr:  address at which the newly aquired segment is to be
    746 **                  mapped into memory.
    747 ** OUTPUTS:     a memory segment is allocated, a PRSegment is allocated
    748 ** RETURN:      pointer to PRSegment
    749 ***********************************************************************/
    750 extern PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr);
    751 
    752 /***********************************************************************
    753 ** FUNCTION:    _PR_DestroySegment()
    754 ** DESCRIPTION:
    755 **   The memory segment and the PRSegment are freed
    756 ** INPUTS:      seg:  pointer to PRSegment to be freed
    757 ** OUTPUTS:     the the PRSegment and its associated memory segment are freed
    758 ** RETURN:      void
    759 ***********************************************************************/
    760 extern void _PR_DestroySegment(PRSegment *seg);
    761 
    762 extern PRThreadStack * _PR_NewStack(PRUint32 stackSize);
    763 extern void _PR_FreeStack(PRThreadStack *stack);
    764 extern PRBool _PR_NotifyThread (PRThread *thread, PRThread *me);
    765 extern void _PR_NotifyLockedThread (PRThread *thread);
    766 
    767 NSPR_API(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout);
    768 NSPR_API(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time);
    769 
    770 extern void _PR_AddThreadToRunQ(PRThread *me, PRThread *thread);
    771 
    772 NSPR_API(PRThread*) _PR_CreateThread(PRThreadType type,
    773                                      void (*start)(void *arg),
    774                                      void *arg,
    775                                      PRThreadPriority priority,
    776                                      PRThreadScope scope,
    777                                      PRThreadState state,
    778                                      PRUint32 stackSize,
    779                      PRUint32 flags);
    780 
    781 extern void _PR_NativeDestroyThread(PRThread *thread);
    782 extern void _PR_UserDestroyThread(PRThread *thread);
    783 
    784 extern PRThread* _PRI_AttachThread(
    785     PRThreadType type, PRThreadPriority priority,
    786     PRThreadStack *stack, PRUint32 flags);
    787 
    788 extern void _PRI_DetachThread(void);
    789 
    790 
    791 #define _PR_IO_PENDING(_thread) ((_thread)->io_pending)
    792 
    793 NSPR_API(void) _PR_MD_INIT_CPUS();
    794 #define    _PR_MD_INIT_CPUS _MD_INIT_CPUS
    795 
    796 NSPR_API(void) _PR_MD_WAKEUP_CPUS();
    797 #define    _PR_MD_WAKEUP_CPUS _MD_WAKEUP_CPUS
    798 
    799 /* Interrupts related */
    800 
    801 NSPR_API(void) _PR_MD_START_INTERRUPTS(void);
    802 #define    _PR_MD_START_INTERRUPTS _MD_START_INTERRUPTS
    803 
    804 NSPR_API(void) _PR_MD_STOP_INTERRUPTS(void);
    805 #define    _PR_MD_STOP_INTERRUPTS _MD_STOP_INTERRUPTS
    806 
    807 NSPR_API(void) _PR_MD_ENABLE_CLOCK_INTERRUPTS(void);
    808 #define    _PR_MD_ENABLE_CLOCK_INTERRUPTS _MD_ENABLE_CLOCK_INTERRUPTS
    809 
    810 NSPR_API(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void);
    811 #define    _PR_MD_DISABLE_CLOCK_INTERRUPTS _MD_DISABLE_CLOCK_INTERRUPTS
    812 
    813 NSPR_API(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void);
    814 #define    _PR_MD_BLOCK_CLOCK_INTERRUPTS _MD_BLOCK_CLOCK_INTERRUPTS
    815 
    816 NSPR_API(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void);
    817 #define    _PR_MD_UNBLOCK_CLOCK_INTERRUPTS _MD_UNBLOCK_CLOCK_INTERRUPTS
    818 
    819 /* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and
    820  * awaken a thread which is waiting on a lock or cvar.
    821  */
    822 extern PRStatus _PR_MD_WAIT(PRThread *, PRIntervalTime timeout);
    823 #define    _PR_MD_WAIT _MD_WAIT
    824 
    825 extern PRStatus _PR_MD_WAKEUP_WAITER(PRThread *);
    826 #define    _PR_MD_WAKEUP_WAITER _MD_WAKEUP_WAITER
    827 
    828 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
    829 NSPR_API(void) _PR_MD_CLOCK_INTERRUPT(void);
    830 #define    _PR_MD_CLOCK_INTERRUPT _MD_CLOCK_INTERRUPT
    831 #endif
    832 
    833 /* Stack debugging */
    834 NSPR_API(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone);
    835 #define    _PR_MD_INIT_STACK _MD_INIT_STACK
    836 
    837 NSPR_API(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts);
    838 #define    _PR_MD_CLEAR_STACK _MD_CLEAR_STACK
    839 
    840 /* CPU related */
    841 NSPR_API(PRInt32) _PR_MD_GET_INTSOFF(void);
    842 #define    _PR_MD_GET_INTSOFF _MD_GET_INTSOFF
    843 
    844 NSPR_API(void) _PR_MD_SET_INTSOFF(PRInt32 _val);
    845 #define    _PR_MD_SET_INTSOFF _MD_SET_INTSOFF
    846 
    847 NSPR_API(_PRCPU*) _PR_MD_CURRENT_CPU(void);
    848 #define    _PR_MD_CURRENT_CPU _MD_CURRENT_CPU
    849 
    850 NSPR_API(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu);
    851 #define    _PR_MD_SET_CURRENT_CPU _MD_SET_CURRENT_CPU
    852 
    853 NSPR_API(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu);
    854 #define    _PR_MD_INIT_RUNNING_CPU _MD_INIT_RUNNING_CPU
    855 
    856 /*
    857  * Returns the number of threads awoken or 0 if a timeout occurred;
    858  */
    859 extern PRInt32 _PR_MD_PAUSE_CPU(PRIntervalTime timeout);
    860 #define    _PR_MD_PAUSE_CPU _MD_PAUSE_CPU
    861 
    862 extern void _PR_MD_CLEANUP_BEFORE_EXIT(void);
    863 #define _PR_MD_CLEANUP_BEFORE_EXIT _MD_CLEANUP_BEFORE_EXIT
    864 
    865 extern void _PR_MD_EXIT(PRIntn status);
    866 #define    _PR_MD_EXIT _MD_EXIT
    867 
    868 /* Locks related */
    869 
    870 NSPR_API(void) _PR_MD_INIT_LOCKS(void);
    871 #define    _PR_MD_INIT_LOCKS _MD_INIT_LOCKS
    872 
    873 NSPR_API(PRStatus) _PR_MD_NEW_LOCK(_MDLock *md);
    874 #define    _PR_MD_NEW_LOCK _MD_NEW_LOCK
    875 
    876 NSPR_API(void) _PR_MD_FREE_LOCK(_MDLock *md);
    877 #define    _PR_MD_FREE_LOCK _MD_FREE_LOCK
    878 
    879 NSPR_API(void) _PR_MD_LOCK(_MDLock *md);
    880 #define    _PR_MD_LOCK _MD_LOCK
    881 
    882 /* Return 0 on success, a nonzero value on failure. */
    883 NSPR_API(PRIntn) _PR_MD_TEST_AND_LOCK(_MDLock *md);
    884 #define    _PR_MD_TEST_AND_LOCK _MD_TEST_AND_LOCK
    885 
    886 NSPR_API(void) _PR_MD_UNLOCK(_MDLock *md);
    887 #define    _PR_MD_UNLOCK _MD_UNLOCK
    888 
    889 NSPR_API(void) _PR_MD_IOQ_LOCK(void);
    890 #define    _PR_MD_IOQ_LOCK _MD_IOQ_LOCK
    891 
    892 NSPR_API(void) _PR_MD_IOQ_UNLOCK(void);
    893 #define    _PR_MD_IOQ_UNLOCK _MD_IOQ_UNLOCK
    894 
    895 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
    896 /* Semaphore related -- only for native threads */
    897 #ifdef HAVE_CVAR_BUILT_ON_SEM
    898 NSPR_API(void) _PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value);
    899 #define _PR_MD_NEW_SEM _MD_NEW_SEM
    900 
    901 NSPR_API(void) _PR_MD_DESTROY_SEM(_MDSemaphore *md);
    902 #define _PR_MD_DESTROY_SEM _MD_DESTROY_SEM
    903 
    904 NSPR_API(PRStatus) _PR_MD_TIMED_WAIT_SEM(
    905     _MDSemaphore *md, PRIntervalTime timeout);
    906 #define _PR_MD_TIMED_WAIT_SEM _MD_TIMED_WAIT_SEM
    907 
    908 NSPR_API(PRStatus) _PR_MD_WAIT_SEM(_MDSemaphore *md);
    909 #define _PR_MD_WAIT_SEM _MD_WAIT_SEM
    910 
    911 NSPR_API(void) _PR_MD_POST_SEM(_MDSemaphore *md);
    912 #define _PR_MD_POST_SEM _MD_POST_SEM
    913 #endif /* HAVE_CVAR_BUILT_ON_SEM */
    914 
    915 #endif
    916 
    917 /* Condition Variables related -- only for native threads */
    918 
    919 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
    920 NSPR_API(PRInt32) _PR_MD_NEW_CV(_MDCVar *md);
    921 #define    _PR_MD_NEW_CV _MD_NEW_CV
    922 
    923 NSPR_API(void) _PR_MD_FREE_CV(_MDCVar *md);
    924 #define    _PR_MD_FREE_CV _MD_FREE_CV
    925 
    926 NSPR_API(void) _PR_MD_WAIT_CV(
    927     _MDCVar *mdCVar,_MDLock *mdLock,PRIntervalTime timeout);
    928 #define    _PR_MD_WAIT_CV _MD_WAIT_CV
    929 
    930 NSPR_API(void) _PR_MD_NOTIFY_CV(_MDCVar *md, _MDLock *lock);
    931 #define    _PR_MD_NOTIFY_CV _MD_NOTIFY_CV
    932 
    933 NSPR_API(void) _PR_MD_NOTIFYALL_CV(_MDCVar *md, _MDLock *lock);
    934 #define    _PR_MD_NOTIFYALL_CV _MD_NOTIFYALL_CV
    935 #endif /* _PR_LOCAL_THREADS_ONLY */
    936 
    937 /* Threads related */
    938 NSPR_API(PRThread*) _PR_MD_CURRENT_THREAD(void);
    939 #define    _PR_MD_CURRENT_THREAD _MD_CURRENT_THREAD
    940 
    941 NSPR_API(PRThread*) _PR_MD_GET_ATTACHED_THREAD(void);
    942 #define    _PR_MD_GET_ATTACHED_THREAD _MD_GET_ATTACHED_THREAD
    943 
    944 NSPR_API(PRThread*) _PR_MD_LAST_THREAD(void);
    945 #define    _PR_MD_LAST_THREAD _MD_LAST_THREAD
    946 
    947 NSPR_API(void) _PR_MD_SET_CURRENT_THREAD(PRThread *thread);
    948 #define    _PR_MD_SET_CURRENT_THREAD _MD_SET_CURRENT_THREAD
    949 
    950 NSPR_API(void) _PR_MD_SET_LAST_THREAD(PRThread *thread);
    951 #define    _PR_MD_SET_LAST_THREAD _MD_SET_LAST_THREAD
    952 
    953 extern PRStatus _PR_MD_INIT_THREAD(PRThread *thread);
    954 #define    _PR_MD_INIT_THREAD _MD_INIT_THREAD
    955 
    956 extern void _PR_MD_EXIT_THREAD(PRThread *thread);
    957 #define    _PR_MD_EXIT_THREAD _MD_EXIT_THREAD
    958 
    959 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
    960 
    961 NSPR_API(PRStatus) _PR_MD_INIT_ATTACHED_THREAD(PRThread *thread);
    962 #define    _PR_MD_INIT_ATTACHED_THREAD _MD_INIT_ATTACHED_THREAD
    963 
    964 extern void _PR_MD_SUSPEND_THREAD(PRThread *thread);
    965 #define    _PR_MD_SUSPEND_THREAD _MD_SUSPEND_THREAD
    966 
    967 extern void _PR_MD_RESUME_THREAD(PRThread *thread);
    968 #define    _PR_MD_RESUME_THREAD _MD_RESUME_THREAD
    969 
    970 extern void _PR_MD_SUSPEND_CPU(_PRCPU  *cpu);
    971 #define    _PR_MD_SUSPEND_CPU _MD_SUSPEND_CPU
    972 
    973 extern void _PR_MD_RESUME_CPU(_PRCPU  *cpu);
    974 #define    _PR_MD_RESUME_CPU _MD_RESUME_CPU
    975 
    976 extern void _PR_MD_BEGIN_SUSPEND_ALL(void);
    977 #define    _PR_MD_BEGIN_SUSPEND_ALL _MD_BEGIN_SUSPEND_ALL
    978 
    979 extern void _PR_MD_END_SUSPEND_ALL(void);
    980 #define    _PR_MD_END_SUSPEND_ALL _MD_END_SUSPEND_ALL
    981 
    982 extern void _PR_MD_BEGIN_RESUME_ALL(void);
    983 #define    _PR_MD_BEGIN_RESUME_ALL _MD_BEGIN_RESUME_ALL
    984 
    985 extern void _PR_MD_END_RESUME_ALL(void);
    986 #define    _PR_MD_END_RESUME_ALL _MD_END_RESUME_ALL
    987 
    988 #if defined(IRIX)
    989 NSPR_API(void) _PR_IRIX_CHILD_PROCESS(void);
    990 #endif        /* IRIX */
    991 
    992 #endif        /* !_PR_LOCAL_THREADS_ONLY */
    993 
    994 extern void _PR_MD_CLEAN_THREAD(PRThread *thread);
    995 #define    _PR_MD_CLEAN_THREAD _MD_CLEAN_THREAD
    996 
    997 #ifdef HAVE_CUSTOM_USER_THREADS
    998 extern void _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *);
    999 #define    _PR_MD_CREATE_PRIMORDIAL_USER_THREAD _MD_CREATE_PRIMORDIAL_USER_THREAD
    1000 
    1001 extern PRThread* _PR_MD_CREATE_USER_THREAD(
    1002                         PRUint32 stacksize,
    1003                         void (*start)(void *),
    1004                         void *arg);
    1005 #define    _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD
    1006 #endif
    1007 
    1008 extern PRStatus _PR_MD_CREATE_THREAD(
    1009                         PRThread *thread,
    1010                         void (*start) (void *),
    1011                         PRThreadPriority priority,
    1012                         PRThreadScope scope,
    1013                         PRThreadState state,
    1014                         PRUint32 stackSize);
    1015 #define    _PR_MD_CREATE_THREAD _MD_CREATE_THREAD
    1016 
    1017 extern void _PR_MD_JOIN_THREAD(_MDThread *md);
    1018 #define    _PR_MD_JOIN_THREAD _MD_JOIN_THREAD
    1019 
    1020 extern void _PR_MD_END_THREAD(void);
    1021 #define    _PR_MD_END_THREAD _MD_END_THREAD
    1022 
    1023 extern void _PR_MD_YIELD(void);
    1024 #define    _PR_MD_YIELD _MD_YIELD
    1025 
    1026 extern void _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri);
    1027 #define    _PR_MD_SET_PRIORITY _MD_SET_PRIORITY
    1028 
    1029 NSPR_API(void) _PR_MD_SUSPENDALL(void);
    1030 #define    _PR_MD_SUSPENDALL _MD_SUSPENDALL
    1031 
    1032 NSPR_API(void) _PR_MD_RESUMEALL(void);
    1033 #define    _PR_MD_RESUMEALL _MD_RESUMEALL
    1034 
    1035 extern void _PR_MD_INIT_CONTEXT(
    1036     PRThread *thread, char *top, void (*start) (void), PRBool *status);
    1037 #define    _PR_MD_INIT_CONTEXT _MD_INIT_CONTEXT
    1038 
    1039 extern void _PR_MD_SWITCH_CONTEXT(PRThread *thread);
    1040 #define    _PR_MD_SWITCH_CONTEXT _MD_SWITCH_CONTEXT
    1041 
    1042 extern void _PR_MD_RESTORE_CONTEXT(PRThread *thread);
    1043 #define    _PR_MD_RESTORE_CONTEXT _MD_RESTORE_CONTEXT
    1044 
    1045 /* Segment related */
    1046 extern void _PR_MD_INIT_SEGS(void);
    1047 #define    _PR_MD_INIT_SEGS _MD_INIT_SEGS
    1048 
    1049 extern PRStatus _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr);
    1050 #define    _PR_MD_ALLOC_SEGMENT _MD_ALLOC_SEGMENT
    1051 
    1052 extern void _PR_MD_FREE_SEGMENT(PRSegment *seg);
    1053 #define    _PR_MD_FREE_SEGMENT _MD_FREE_SEGMENT
    1054 
    1055 /* Directory enumeration related */
    1056 extern PRStatus _PR_MD_OPEN_DIR(_MDDir *md,const char *name);
    1057 #define    _PR_MD_OPEN_DIR _MD_OPEN_DIR
    1058 
    1059 extern char * _PR_MD_READ_DIR(_MDDir *md, PRIntn flags);
    1060 #define    _PR_MD_READ_DIR _MD_READ_DIR
    1061 
    1062 extern PRInt32 _PR_MD_CLOSE_DIR(_MDDir *md);
    1063 #define    _PR_MD_CLOSE_DIR _MD_CLOSE_DIR
    1064 
    1065 /* Named semaphores related */
    1066 extern PRSem * _PR_MD_OPEN_SEMAPHORE(
    1067     const char *osname, PRIntn flags, PRIntn mode, PRUintn value);
    1068 #define    _PR_MD_OPEN_SEMAPHORE _MD_OPEN_SEMAPHORE
    1069 
    1070 extern PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem);
    1071 #define    _PR_MD_WAIT_SEMAPHORE _MD_WAIT_SEMAPHORE
    1072 
    1073 extern PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem);
    1074 #define    _PR_MD_POST_SEMAPHORE _MD_POST_SEMAPHORE
    1075 
    1076 extern PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem);
    1077 #define    _PR_MD_CLOSE_SEMAPHORE _MD_CLOSE_SEMAPHORE
    1078 
    1079 extern PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname);
    1080 #define    _PR_MD_DELETE_SEMAPHORE _MD_DELETE_SEMAPHORE
    1081 
    1082 /* I/O related */
    1083 extern void _PR_MD_INIT_FILEDESC(PRFileDesc *fd);
    1084 #define    _PR_MD_INIT_FILEDESC _MD_INIT_FILEDESC
    1085 
    1086 #ifdef XP_MAC
    1087 extern void _PR_MD_FREE_FILEDESC(PRFileDesc *fd);
    1088 #define    _PR_MD_FREE_FILEDESC _MD_FREE_FILEDESC
    1089 #endif
    1090 
    1091 extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd);
    1092 #define    _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK
    1093 
    1094 /* File I/O related */
    1095 extern PRInt32 _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode);
    1096 #define    _PR_MD_OPEN _MD_OPEN
    1097 
    1098 extern PRInt32 _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode);
    1099 #define    _PR_MD_OPEN_FILE _MD_OPEN_FILE
    1100 
    1101 extern PRInt32 _PR_MD_CLOSE_FILE(PRInt32 osfd);
    1102 #define    _PR_MD_CLOSE_FILE _MD_CLOSE_FILE
    1103 
    1104 extern PRInt32 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 amount);
    1105 #define    _PR_MD_READ _MD_READ
    1106 
    1107 extern PRInt32 _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 amount);
    1108 #define    _PR_MD_WRITE _MD_WRITE
    1109 
    1110 extern PRInt32 _PR_MD_WRITEV(
    1111     PRFileDesc *fd, const struct PRIOVec *iov,
    1112     PRInt32 iov_size, PRIntervalTime timeout);
    1113 #define    _PR_MD_WRITEV _MD_WRITEV
    1114 
    1115 extern PRInt32 _PR_MD_FSYNC(PRFileDesc *fd);
    1116 #define    _PR_MD_FSYNC _MD_FSYNC
    1117 
    1118 extern PRInt32 _PR_MD_DELETE(const char *name);
    1119 #define        _PR_MD_DELETE _MD_DELETE
    1120 
    1121 extern PRInt32 _PR_MD_RENAME(const char *from, const char *to);
    1122 #define _PR_MD_RENAME _MD_RENAME
    1123 
    1124 extern PRInt32 _PR_MD_ACCESS(const char *name, PRAccessHow how);
    1125 #define _PR_MD_ACCESS _MD_ACCESS
    1126 
    1127 extern PRInt32 _PR_MD_STAT(const char *name, struct stat *buf);
    1128 #define _PR_MD_STAT _MD_STAT
    1129 
    1130 extern PRInt32 _PR_MD_MKDIR(const char *name, PRIntn mode);
    1131 #define _PR_MD_MKDIR _MD_MKDIR
    1132 
    1133 extern PRInt32 _PR_MD_MAKE_DIR(const char *name, PRIntn mode);
    1134 #define _PR_MD_MAKE_DIR _MD_MAKE_DIR
    1135 
    1136 extern PRInt32 _PR_MD_RMDIR(const char *name);
    1137 #define _PR_MD_RMDIR _MD_RMDIR
    1138 
    1139 #ifdef MOZ_UNICODE
    1140 /* UTF16 File I/O related */
    1141 extern PRStatus _PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *md, const PRUnichar *name);
    1142 #define    _PR_MD_OPEN_DIR_UTF16 _MD_OPEN_DIR_UTF16
    1143 
    1144 extern PRInt32 _PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, PRIntn mode);
    1145 #define    _PR_MD_OPEN_FILE_UTF16 _MD_OPEN_FILE_UTF16
    1146 
    1147 extern PRUnichar * _PR_MD_READ_DIR_UTF16(_MDDirUTF16 *md, PRIntn flags);
    1148 #define    _PR_MD_READ_DIR_UTF16 _MD_READ_DIR_UTF16
    1149 
    1150 extern PRInt32 _PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *md);
    1151 #define    _PR_MD_CLOSE_DIR_UTF16 _MD_CLOSE_DIR_UTF16
    1152 
    1153 extern PRInt32 _PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info);
    1154 #define _PR_MD_GETFILEINFO64_UTF16 _MD_GETFILEINFO64_UTF16
    1155 #endif /* MOZ_UNICODE */
    1156 
    1157 /* Socket I/O related */
    1158 extern void _PR_MD_INIT_IO(void);
    1159 #define    _PR_MD_INIT_IO _MD_INIT_IO
    1160 
    1161 extern PRInt32 _PR_MD_CLOSE_SOCKET(PRInt32 osfd);
    1162 #define    _PR_MD_CLOSE_SOCKET _MD_CLOSE_SOCKET
    1163 
    1164 extern PRInt32 _PR_MD_CONNECT(
    1165     PRFileDesc *fd, const PRNetAddr *addr,
    1166     PRUint32 addrlen, PRIntervalTime timeout);
    1167 #define    _PR_MD_CONNECT _MD_CONNECT
    1168 
    1169 extern PRInt32 _PR_MD_ACCEPT(
    1170     PRFileDesc *fd, PRNetAddr *addr,
    1171     PRUint32 *addrlen, PRIntervalTime timeout);
    1172 #define    _PR_MD_ACCEPT _MD_ACCEPT
    1173 
    1174 extern PRInt32 _PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen);
    1175 #define    _PR_MD_BIND _MD_BIND
    1176 
    1177 extern PRInt32 _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog);
    1178 #define    _PR_MD_LISTEN _MD_LISTEN
    1179 
    1180 extern PRInt32 _PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how);
    1181 #define    _PR_MD_SHUTDOWN _MD_SHUTDOWN
    1182 
    1183 extern PRInt32 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount,
    1184                                PRIntn flags, PRIntervalTime timeout);
    1185 #define    _PR_MD_RECV _MD_RECV
    1186 
    1187 extern PRInt32 _PR_MD_SEND(
    1188     PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
    1189     PRIntervalTime timeout);
    1190 #define    _PR_MD_SEND _MD_SEND
    1191 
    1192 extern PRInt32 _PR_MD_ACCEPT_READ(PRFileDesc *sd, PRInt32 *newSock,
    1193                                 PRNetAddr **raddr, void *buf, PRInt32 amount,
    1194                                 PRIntervalTime timeout);
    1195 #define _PR_MD_ACCEPT_READ _MD_ACCEPT_READ
    1196 
    1197 #ifdef WIN32
    1198 extern PRInt32 _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *addr,
    1199                                 PRUint32 *addrlen, PRIntervalTime timeout,
    1200                                 PRBool fast,
    1201                                 _PR_AcceptTimeoutCallback callback,
    1202                                 void *callbackArg);
    1203 
    1204 extern PRInt32 _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PRInt32 *newSock,
    1205                                 PRNetAddr **raddr, void *buf, PRInt32 amount,
    1206                                 PRIntervalTime timeout, PRBool fast,
    1207                                 _PR_AcceptTimeoutCallback callback,
    1208                                 void *callbackArg);
    1209 
    1210 extern void _PR_MD_UPDATE_ACCEPT_CONTEXT(PRInt32 s, PRInt32 ls);
    1211 #define _PR_MD_UPDATE_ACCEPT_CONTEXT _MD_UPDATE_ACCEPT_CONTEXT
    1212 #endif /* WIN32 */
    1213 
    1214 extern PRInt32 _PR_MD_SENDFILE(
    1215     PRFileDesc *sock, PRSendFileData *sfd,
    1216         PRInt32 flags, PRIntervalTime timeout);
    1217 #define _PR_MD_SENDFILE _MD_SENDFILE
    1218 
    1219 extern PRStatus _PR_MD_GETSOCKNAME(
    1220     PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
    1221 #define    _PR_MD_GETSOCKNAME _MD_GETSOCKNAME
    1222 
    1223 extern PRStatus _PR_MD_GETPEERNAME(
    1224     PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
    1225 #define    _PR_MD_GETPEERNAME _MD_GETPEERNAME
    1226 
    1227 extern PRStatus _PR_MD_GETSOCKOPT(
    1228     PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen);
    1229 #define    _PR_MD_GETSOCKOPT _MD_GETSOCKOPT
    1230 
    1231 extern PRStatus _PR_MD_SETSOCKOPT(
    1232     PRFileDesc *fd, PRInt32 level, PRInt32 optname,
    1233     const char* optval, PRInt32 optlen);
    1234 #define    _PR_MD_SETSOCKOPT _MD_SETSOCKOPT
    1235 
    1236 extern PRStatus PR_CALLBACK _PR_SocketGetSocketOption(
    1237     PRFileDesc *fd, PRSocketOptionData *data);
    1238 
    1239 extern PRStatus PR_CALLBACK _PR_SocketSetSocketOption(
    1240     PRFileDesc *fd, const PRSocketOptionData *data);
    1241 
    1242 extern PRInt32 _PR_MD_RECVFROM(
    1243     PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
    1244     PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout);
    1245 #define    _PR_MD_RECVFROM _MD_RECVFROM
    1246 
    1247 extern PRInt32 _PR_MD_SENDTO(
    1248     PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
    1249     const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout);
    1250 #define    _PR_MD_SENDTO _MD_SENDTO
    1251 
    1252 extern PRInt32 _PR_MD_SOCKETPAIR(int af, int type, int flags, PRInt32 *osfd);
    1253 #define    _PR_MD_SOCKETPAIR _MD_SOCKETPAIR
    1254 
    1255 extern PRInt32 _PR_MD_SOCKET(int af, int type, int flags);
    1256 #define    _PR_MD_SOCKET _MD_SOCKET
    1257 
    1258 extern PRInt32 _PR_MD_SOCKETAVAILABLE(PRFileDesc *fd);
    1259 #define    _PR_MD_SOCKETAVAILABLE _MD_SOCKETAVAILABLE
    1260 
    1261 extern PRInt32 _PR_MD_PIPEAVAILABLE(PRFileDesc *fd);
    1262 #define    _PR_MD_PIPEAVAILABLE _MD_PIPEAVAILABLE
    1263 
    1264 extern PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds,
    1265                                                                                         PRIntervalTime timeout);
    1266 #define    _PR_MD_PR_POLL _MD_PR_POLL
    1267 
    1268 /*
    1269  * Initialize fd->secret->inheritable for a newly created fd.
    1270  * If 'imported' is false, the osfd (i.e., fd->secret->md.osfd)
    1271  * was created by NSPR and hence has the OS-dependent default
    1272  * inheritable attribute.  If 'imported' is true, the osfd was
    1273  * not created by NSPR and hence a system call is required to
    1274  * query its inheritable attribute.  Since we may never need to
    1275  * know the inheritable attribute of a fd, a platform may choose
    1276  * to initialize fd->secret->inheritable of an imported fd to
    1277  * _PR_TRI_UNKNOWN and only pay the cost of the system call
    1278  * (in _PR_MD_QUERY_FD_INHERITABLE) when necessary.
    1279  */
    1280 extern void _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported);
    1281 #define    _PR_MD_INIT_FD_INHERITABLE _MD_INIT_FD_INHERITABLE
    1282 
    1283 extern PRStatus _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable);
    1284 #define    _PR_MD_SET_FD_INHERITABLE _MD_SET_FD_INHERITABLE
    1285 
    1286 
    1287 #define _PR_PROCESS_TIMEOUT_INTERRUPT_ERRORS(me) \
    1288         if (_PR_PENDING_INTERRUPT(me)) { \
    1289                 me->flags &= ~_PR_INTERRUPT; \
    1290                 PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); \
    1291         } else { \
    1292                 PR_SetError(PR_IO_TIMEOUT_ERROR, 0); \
    1293         }
    1294 
    1295 extern void *_PR_MD_GET_SP(PRThread *thread);
    1296 #define    _PR_MD_GET_SP _MD_GET_SP
    1297 
    1298 #endif /* defined(_PR_PTHREADS) */
    1299207
    1300208/************************************************************************/
     
    1431339
    1432340struct PRLock {
    1433 #if defined(_PR_PTHREADS)
    1434341    pthread_mutex_t mutex;          /* the underlying lock */
    1435342    _PT_Notified notified;          /* array of conditions notified */
    1436343    PRBool locked;                  /* whether the mutex is locked */
    1437344    pthread_t owner;                /* if locked, current lock owner */
    1438 #elif defined(_PR_BTHREADS)
    1439     sem_id      semaphoreID;        /* the underlying lock */
    1440     int32       benaphoreCount;     /* number of people in lock */
    1441     thread_id   owner;              /* current lock owner */
    1442 #else /* not pthreads or Be threads */
    1443     PRCList links;                  /* linkage for PRThread.lockList */
    1444     struct PRThread *owner;         /* current lock owner */
    1445     PRCList waitQ;                  /* list of threads waiting for lock */
    1446     PRThreadPriority priority;      /* priority of lock */
    1447     PRThreadPriority boostPriority; /* boosted priority of lock owner */
    1448     _MDLock ilock;                  /* Internal Lock to protect user-level fields */
    1449 #endif
    1450345};
    1451346
     
    1454349struct PRCondVar {
    1455350    PRLock *lock;               /* associated lock that protects the condition */
    1456 #if defined(_PR_PTHREADS)
    1457351    pthread_cond_t cv;          /* underlying pthreads condition */
    1458352    PRInt32 notify_pending;     /* CV has destroy pending notification */
    1459 #elif defined(_PR_BTHREADS)
    1460     sem_id    sem;              /* the underlying lock */
    1461     sem_id    handshakeSem;     /* the lock for 'notify'-threads waiting for confirmation */
    1462     sem_id    signalSem;        /* the lock for threads waiting for someone to notify */
    1463     volatile int32    nw;       /* the number waiting */
    1464     volatile int32    ns;       /* the number signalling */
    1465     long signalBenCount;        /* the number waiting on the underlying sem */
    1466 #else /* not pthreads or Be threads */
    1467     PRCList condQ;              /* Condition variable wait Q */
    1468     _MDLock ilock;              /* Internal Lock to protect condQ */
    1469     _MDCVar md;
    1470 #endif
    1471353};
    1472354
     
    1475357struct PRMonitor {
    1476358    const char* name;           /* monitor name for debugging */
    1477 #if defined(_PR_PTHREADS)
    1478359    PRLock lock;                /* the lock structure */
    1479360    pthread_t owner;            /* the owner of the lock or invalid */
    1480361    PRCondVar *cvar;            /* condition variable queue */
    1481 #else  /* defined(_PR_PTHREADS) */
    1482     PRCondVar *cvar;            /* associated lock and condition variable queue */
    1483 #endif /* defined(_PR_PTHREADS) */
    1484362    PRUint32 entryCount;        /* # of times re-entered */
    1485363};
     
    1488366
    1489367struct PRSemaphore {
    1490 #if defined(_PR_BTHREADS)
    1491     sem_id  sem;
    1492     int32   benaphoreCount;
    1493 #else
    1494368    PRCondVar *cvar;        /* associated lock and condition variable queue */
    1495369    PRUintn count;            /* the value of the counting semaphore */
    1496370    PRUint32 waiters;            /* threads waiting on the semaphore */
    1497 #if defined(_PR_PTHREADS)
    1498 #else  /* defined(_PR_PTHREADS) */
    1499     _MDSemaphore md;
    1500 #endif /* defined(_PR_PTHREADS) */
    1501 #endif /* defined(_PR_BTHREADS) */
    1502371};
    1503372
     
    1547416    PRSegment *seg;
    1548417        PRThread* thr;          /* back pointer to thread owning this stack */
    1549 
    1550 #if defined(_PR_PTHREADS)
    1551 #else /* defined(_PR_PTHREADS) */
    1552     _MDThreadStack md;
    1553 #endif /* defined(_PR_PTHREADS) */
    1554418};
    1555419
     
    1582446    char *errorString;              /* current error string | NULL */
    1583447
    1584 #if defined(_PR_PTHREADS)
    1585448    pthread_t id;                   /* pthread identifier for the thread */
    1586449    PRBool okToDelete;              /* ok to delete the PRThread struct? */
     
    1599462    int *selectfd_list;             /* Unix fd's that PR_Poll selects on */
    1600463    PRUint32 selectfd_count;        /* number of elements in selectfd_list */
    1601 #endif
    1602 #elif defined(_PR_BTHREADS)
    1603     PRUint32 flags;
    1604     _MDThread md;
    1605     PRBool io_pending;
    1606     PRInt32 io_fd;
    1607     PRBool io_suspended;
    1608 #else /* not pthreads or Be threads */
    1609     _MDLock threadLock;             /* Lock to protect thread state variables.
    1610                                      * Protects the following fields:
    1611                                      *     state
    1612                                      *     priority
    1613                                      *     links
    1614                                      *     wait
    1615                                      *     cpu
    1616                                      */
    1617     PRUint32 queueCount;
    1618     PRUint32 waitCount;
    1619 
    1620     PRCList active;                 /* on list of all active threads        */
    1621     PRCList links;
    1622     PRCList waitQLinks;             /* when thread is PR_Wait'ing */
    1623     PRCList lockList;               /* list of locks currently holding */
    1624     PRIntervalTime sleep;           /* sleep time when thread is sleeping */
    1625     struct _wait {
    1626         struct PRLock *lock;
    1627         struct PRCondVar *cvar;
    1628     } wait;
    1629 
    1630     PRUint32 id;
    1631     PRUint32 flags;
    1632     PRUint32 no_sched;              /* Don't schedule the thread to run.
    1633                                      * This flag has relevance only when
    1634                                      * multiple NSPR CPUs are created.
    1635                                      * When a thread is de-scheduled, there
    1636                                      * is a narrow window of time in which
    1637                                      * the thread is put on the run queue
    1638                                      * but the scheduler is actually using
    1639                                      * the stack of this thread.  It is safe
    1640                                      * to run this thread on a different CPU
    1641                                      * only when its stack is not in use on
    1642                                      * any other CPU.  The no_sched flag is
    1643                                      * set during this interval to prevent
    1644                                      * the thread from being scheduled on a
    1645                                      * different CPU.
    1646                                      */
    1647 
    1648     /* thread termination condition variable for join */
    1649     PRCondVar *term;
    1650 
    1651     _PRCPU *cpu;                    /* cpu to which this thread is bound    */
    1652     PRUint32 threadAllocatedOnStack;/* boolean */
    1653 
    1654     /* When an async IO is in progress and a second async IO cannot be
    1655      * initiated, the io_pending flag is set to true.  Some platforms will
    1656      * not use the io_pending flag.  If the io_pending flag is true, then
    1657      * io_fd is the OS-file descriptor on which IO is pending.
    1658      */
    1659     PRBool io_pending;
    1660     PRInt32 io_fd;
    1661 
    1662     /* If a timeout occurs or if an outstanding IO is interrupted and the
    1663      * OS doesn't support a real cancellation (NT or MAC), then the
    1664      * io_suspended flag will be set to true.  The thread will be resumed
    1665      * but may run into trouble issuing additional IOs until the io_pending
    1666      * flag can be cleared
    1667      */
    1668     PRBool io_suspended;
    1669 
    1670     _MDThread md;
    1671464#endif
    1672465};
     
    1803596    PRUint32 size;
    1804597    PRUintn flags;
    1805 #if defined(_PR_PTHREADS)
    1806 #else  /* defined(_PR_PTHREADS) */
    1807     _MDSegment md;
    1808 #endif /* defined(_PR_PTHREADS) */
    1809598};
    1810599
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/io/prlog.c

    r73071 r101805  
    7272 */
    7373static PRLock *_pr_logLock;
    74 #if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
    7574#define _PR_LOCK_LOG() PR_Lock(_pr_logLock);
    7675#define _PR_UNLOCK_LOG() PR_Unlock(_pr_logLock);
    77 #elif defined(_PR_GLOBAL_THREADS_ONLY)
    78 #define _PR_LOCK_LOG() { _PR_LOCK_LOCK(_pr_logLock)
    79 #define _PR_UNLOCK_LOG() _PR_LOCK_UNLOCK(_pr_logLock); }
    80 #else
    81 
    82 #define _PR_LOCK_LOG() \
    83 { \
    84     PRIntn _is; \
    85     PRThread *_me = _PR_MD_CURRENT_THREAD(); \
    86     if (!_PR_IS_NATIVE_THREAD(_me)) \
    87         _PR_INTSOFF(_is); \
    88     _PR_LOCK_LOCK(_pr_logLock)
    89 
    90 #define _PR_UNLOCK_LOG() \
    91     _PR_LOCK_UNLOCK(_pr_logLock); \
    92     PR_ASSERT(_me == _PR_MD_CURRENT_THREAD()); \
    93     if (!_PR_IS_NATIVE_THREAD(_me)) \
    94         _PR_INTSON(_is); \
    95 }
    96 
    97 #endif
    9876
    9977#if defined(XP_PC)
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/io/prmapopt.c

    r1 r101805  
    7474#include <netinet/tcp.h>  /* TCP_NODELAY, TCP_MAXSEG */
    7575#endif
    76 
    77 #ifndef _PR_PTHREADS
    78 
    79 PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
    80 {
    81     PRStatus rv;
    82     PRInt32 length;
    83     PRInt32 level, name;
    84 
    85     /*
    86      * PR_SockOpt_Nonblocking is a special case that does not
    87      * translate to a getsockopt() call
    88      */
    89     if (PR_SockOpt_Nonblocking == data->option)
    90     {
    91         data->value.non_blocking = fd->secret->nonblocking;
    92         return PR_SUCCESS;
    93     }
    94 
    95     rv = _PR_MapOptionName(data->option, &level, &name);
    96     if (PR_SUCCESS == rv)
    97     {
    98         switch (data->option)
    99         {
    100             case PR_SockOpt_Linger:
    101             {
    102 #if !defined(XP_BEOS) || defined(BONE_VERSION)
    103                 struct linger linger;
    104                 length = sizeof(linger);
    105                 rv = _PR_MD_GETSOCKOPT(
    106                     fd, level, name, (char *) &linger, &length);
    107                 if (PR_SUCCESS == rv)
    108                 {
    109                     PR_ASSERT(sizeof(linger) == length);
    110                     data->value.linger.polarity =
    111                         (linger.l_onoff) ? PR_TRUE : PR_FALSE;
    112                     data->value.linger.linger =
    113                         PR_SecondsToInterval(linger.l_linger);
    114                 }
    115                 break;
    116 #else
    117                 PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
    118                 return PR_FAILURE;
    119 #endif
    120             }
    121             case PR_SockOpt_Reuseaddr:
    122             case PR_SockOpt_Keepalive:
    123             case PR_SockOpt_NoDelay:
    124             case PR_SockOpt_Broadcast:
    125             {
    126 #ifdef WIN32 /* Winsock */
    127                 BOOL value;
    128 #else
    129                 PRIntn value;
    130 #endif
    131                 length = sizeof(value);
    132                 rv = _PR_MD_GETSOCKOPT(
    133                     fd, level, name, (char*)&value, &length);
    134                 if (PR_SUCCESS == rv)
    135                     data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE;
    136                 break;
    137             }
    138             case PR_SockOpt_McastLoopback:
    139             {
    140 #ifdef WIN32 /* Winsock */
    141                 BOOL bool;
    142 #else
    143                 PRUint8 bool;
    144 #endif
    145                 length = sizeof(bool);
    146                 rv = _PR_MD_GETSOCKOPT(
    147                     fd, level, name, (char*)&bool, &length);
    148                 if (PR_SUCCESS == rv)
    149                     data->value.mcast_loopback = (0 == bool) ? PR_FALSE : PR_TRUE;
    150                 break;
    151             }
    152             case PR_SockOpt_RecvBufferSize:
    153             case PR_SockOpt_SendBufferSize:
    154             case PR_SockOpt_MaxSegment:
    155             {
    156                 PRIntn value;
    157                 length = sizeof(value);
    158                 rv = _PR_MD_GETSOCKOPT(
    159                     fd, level, name, (char*)&value, &length);
    160                 if (PR_SUCCESS == rv)
    161                     data->value.recv_buffer_size = value;
    162                 break;
    163             }
    164             case PR_SockOpt_IpTimeToLive:
    165             case PR_SockOpt_IpTypeOfService:
    166             {
    167                 /* These options should really be an int (or PRIntn). */
    168                 length = sizeof(PRUintn);
    169                 rv = _PR_MD_GETSOCKOPT(
    170                     fd, level, name, (char*)&data->value.ip_ttl, &length);
    171                 break;
    172             }
    173             case PR_SockOpt_McastTimeToLive:
    174             {
    175 #ifdef WIN32 /* Winsock */
    176                 int ttl;
    177 #else
    178                 PRUint8 ttl;
    179 #endif
    180                 length = sizeof(ttl);
    181                 rv = _PR_MD_GETSOCKOPT(
    182                     fd, level, name, (char*)&ttl, &length);
    183                 if (PR_SUCCESS == rv)
    184                     data->value.mcast_ttl = ttl;
    185                 break;
    186             }
    187 #ifdef IP_ADD_MEMBERSHIP
    188             case PR_SockOpt_AddMember:
    189             case PR_SockOpt_DropMember:
    190             {
    191                 struct ip_mreq mreq;
    192                 length = sizeof(mreq);
    193                 rv = _PR_MD_GETSOCKOPT(
    194                     fd, level, name, (char*)&mreq, &length);
    195                 if (PR_SUCCESS == rv)
    196                 {
    197                     data->value.add_member.mcaddr.inet.ip =
    198                         mreq.imr_multiaddr.s_addr;
    199                     data->value.add_member.ifaddr.inet.ip =
    200                         mreq.imr_interface.s_addr;
    201                 }
    202                 break;
    203             }
    204 #endif /* IP_ADD_MEMBERSHIP */
    205             case PR_SockOpt_McastInterface:
    206             {
    207                 /* This option is a struct in_addr. */
    208                 length = sizeof(data->value.mcast_if.inet.ip);
    209                 rv = _PR_MD_GETSOCKOPT(
    210                     fd, level, name,
    211                     (char*)&data->value.mcast_if.inet.ip, &length);
    212                 break;
    213             }
    214             default:
    215                 PR_NOT_REACHED("Unknown socket option");
    216                 break;
    217         } 
    218     }
    219     return rv;
    220 }  /* _PR_SocketGetSocketOption */
    221 
    222 PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data)
    223 {
    224     PRStatus rv;
    225     PRInt32 level, name;
    226 
    227     /*
    228      * PR_SockOpt_Nonblocking is a special case that does not
    229      * translate to a setsockopt call.
    230      */
    231     if (PR_SockOpt_Nonblocking == data->option)
    232     {
    233 #ifdef WINNT
    234         PR_ASSERT((fd->secret->md.io_model_committed == PR_FALSE)
    235             || (fd->secret->nonblocking == data->value.non_blocking));
    236         if (fd->secret->md.io_model_committed
    237             && (fd->secret->nonblocking != data->value.non_blocking))
    238         {
    239             /*
    240              * On NT, once we have associated a socket with the io
    241              * completion port, we can't disassociate it.  So we
    242              * can't change the nonblocking option of the socket
    243              * afterwards.
    244              */
    245             PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
    246             return PR_FAILURE;
    247         }
    248 #endif
    249         fd->secret->nonblocking = data->value.non_blocking;
    250         return PR_SUCCESS;
    251     }
    252 
    253     rv = _PR_MapOptionName(data->option, &level, &name);
    254     if (PR_SUCCESS == rv)
    255     {
    256         switch (data->option)
    257         {
    258             case PR_SockOpt_Linger:
    259             {
    260 #if !defined(XP_BEOS) || defined(BONE_VERSION)
    261                 struct linger linger;
    262                 linger.l_onoff = data->value.linger.polarity;
    263                 linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger);
    264                 rv = _PR_MD_SETSOCKOPT(
    265                     fd, level, name, (char*)&linger, sizeof(linger));
    266                 break;
    267 #else
    268                 PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
    269                 return PR_FAILURE;
    270 #endif
    271             }
    272             case PR_SockOpt_Reuseaddr:
    273             case PR_SockOpt_Keepalive:
    274             case PR_SockOpt_NoDelay:
    275             case PR_SockOpt_Broadcast:
    276             {
    277 #ifdef WIN32 /* Winsock */
    278                 BOOL value;
    279 #else
    280                 PRIntn value;
    281 #endif
    282                 value = (data->value.reuse_addr) ? 1 : 0;
    283                 rv = _PR_MD_SETSOCKOPT(
    284                     fd, level, name, (char*)&value, sizeof(value));
    285                 break;
    286             }
    287             case PR_SockOpt_McastLoopback:
    288             {
    289 #ifdef WIN32 /* Winsock */
    290                 BOOL bool;
    291 #else
    292                 PRUint8 bool;
    293 #endif
    294                 bool = data->value.mcast_loopback ? 1 : 0;
    295                 rv = _PR_MD_SETSOCKOPT(
    296                     fd, level, name, (char*)&bool, sizeof(bool));
    297                 break;
    298             }
    299             case PR_SockOpt_RecvBufferSize:
    300             case PR_SockOpt_SendBufferSize:
    301             case PR_SockOpt_MaxSegment:
    302             {
    303                 PRIntn value = data->value.recv_buffer_size;
    304                 rv = _PR_MD_SETSOCKOPT(
    305                     fd, level, name, (char*)&value, sizeof(value));
    306                 break;
    307             }
    308             case PR_SockOpt_IpTimeToLive:
    309             case PR_SockOpt_IpTypeOfService:
    310             {
    311                 /* These options should really be an int (or PRIntn). */
    312                 rv = _PR_MD_SETSOCKOPT(
    313                     fd, level, name, (char*)&data->value.ip_ttl, sizeof(PRUintn));
    314                 break;
    315             }
    316             case PR_SockOpt_McastTimeToLive:
    317             {
    318 #ifdef WIN32 /* Winsock */
    319                 int ttl;
    320 #else
    321                 PRUint8 ttl;
    322 #endif
    323                 ttl = data->value.mcast_ttl;
    324                 rv = _PR_MD_SETSOCKOPT(
    325                     fd, level, name, (char*)&ttl, sizeof(ttl));
    326                 break;
    327             }
    328 #ifdef IP_ADD_MEMBERSHIP
    329             case PR_SockOpt_AddMember:
    330             case PR_SockOpt_DropMember:
    331             {
    332                 struct ip_mreq mreq;
    333                 mreq.imr_multiaddr.s_addr =
    334                     data->value.add_member.mcaddr.inet.ip;
    335                 mreq.imr_interface.s_addr =
    336                     data->value.add_member.ifaddr.inet.ip;
    337                 rv = _PR_MD_SETSOCKOPT(
    338                     fd, level, name, (char*)&mreq, sizeof(mreq));
    339                 break;
    340             }
    341 #endif /* IP_ADD_MEMBERSHIP */
    342             case PR_SockOpt_McastInterface:
    343             {
    344                 /* This option is a struct in_addr. */
    345                 rv = _PR_MD_SETSOCKOPT(
    346                     fd, level, name, (char*)&data->value.mcast_if.inet.ip,
    347                     sizeof(data->value.mcast_if.inet.ip));
    348                 break;
    349             }
    350             default:
    351                 PR_NOT_REACHED("Unknown socket option");
    352                 break;
    353         } 
    354     }
    355     return rv;
    356 }  /* _PR_SocketSetSocketOption */
    357 
    358 #endif /* ! _PR_PTHREADS */
    35976
    36077/*
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/unix/darwin.c

    r1 r101805  
    4444PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
    4545{
    46 #if !defined(_PR_PTHREADS)
    47     if (isCurrent) {
    48         (void) setjmp(CONTEXT(t));
    49     }
    50     *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
    51     return (PRWord *) CONTEXT(t);
    52 #else
    5346        *np = 0;
    5447        return NULL;
    55 #endif
    5648}
    57 
    58 #if !defined(_PR_PTHREADS)
    59 void
    60 _MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
    61 {
    62     return;
    63 }
    64 
    65 PRStatus
    66 _MD_InitializeThread(PRThread *thread)
    67 {
    68         return PR_SUCCESS;
    69 }
    70 
    71 PRStatus
    72 _MD_WAIT(PRThread *thread, PRIntervalTime ticks)
    73 {
    74     PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
    75     _PR_MD_SWITCH_CONTEXT(thread);
    76     return PR_SUCCESS;
    77 }
    78 
    79 PRStatus
    80 _MD_WAKEUP_WAITER(PRThread *thread)
    81 {
    82     if (thread) {
    83         PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
    84     }
    85     return PR_SUCCESS;
    86 }
    87 
    88 /* These functions should not be called for Darwin */
    89 void
    90 _MD_YIELD(void)
    91 {
    92     PR_NOT_REACHED("_MD_YIELD should not be called for Darwin.");
    93 }
    94 
    95 PRStatus
    96 _MD_CREATE_THREAD(
    97     PRThread *thread,
    98     void (*start) (void *),
    99     PRThreadPriority priority,
    100     PRThreadScope scope,
    101     PRThreadState state,
    102     PRUint32 stackSize)
    103 {
    104     PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Darwin.");
    105         return PR_FAILURE;
    106 }
    107 #endif /* ! _PR_PTHREADS */
    10849
    10950/* darwin.c */
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/unix/freebsd.c

    r1 r101805  
    5656PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
    5757{
    58 #ifndef _PR_PTHREADS
    59     if (isCurrent) {
    60         (void) sigsetjmp(CONTEXT(t), 1);
    61     }
    62     *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
    63     return (PRWord *) CONTEXT(t);
    64 #else
    6558        *np = 0;
    6659        return NULL;
    67 #endif
    6860}
    6961
    70 #ifndef _PR_PTHREADS
    71 void
    72 _MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
    73 {
    74     return;
    75 }
    76 
    77 PRStatus
    78 _MD_InitializeThread(PRThread *thread)
    79 {
    80         return PR_SUCCESS;
    81 }
    82 
    83 PRStatus
    84 _MD_WAIT(PRThread *thread, PRIntervalTime ticks)
    85 {
    86     PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
    87     _PR_MD_SWITCH_CONTEXT(thread);
    88     return PR_SUCCESS;
    89 }
    90 
    91 PRStatus
    92 _MD_WAKEUP_WAITER(PRThread *thread)
    93 {
    94     if (thread) {
    95         PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
    96     }
    97     return PR_SUCCESS;
    98 }
    99 
    100 /* These functions should not be called for FreeBSD */
    101 void
    102 _MD_YIELD(void)
    103 {
    104     PR_NOT_REACHED("_MD_YIELD should not be called for FreeBSD.");
    105 }
    106 
    107 PRStatus
    108 _MD_CREATE_THREAD(
    109     PRThread *thread,
    110     void (*start) (void *),
    111     PRThreadPriority priority,
    112     PRThreadScope scope,
    113     PRThreadState state,
    114     PRUint32 stackSize)
    115 {
    116     PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for FreeBSD.");
    117         return PR_FAILURE;
    118 }
    119 #endif /* ! _PR_PTHREADS */
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/unix/linux.c

    r1 r101805  
    4444PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
    4545{
    46 #ifndef _PR_PTHREADS
    47     if (isCurrent) {
    48         (void) setjmp(CONTEXT(t));
    49     }
    50     *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
    51     return (PRWord *) CONTEXT(t);
    52 #else
    5346        *np = 0;
    5447        return NULL;
    55 #endif
    5648}
    57 
    58 #ifdef _PR_PTHREADS
    5949
    6050extern void _MD_unix_terminate_waitpid_daemon(void);
     
    6555}
    6656
    67 #else /* ! _PR_PTHREADS */
    68 
    69 void
    70 _MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
    71 {
    72     return;
    73 }
    74 
    75 PRStatus
    76 _MD_InitializeThread(PRThread *thread)
    77 {
    78         /*
    79          * set the pointers to the stack-pointer and frame-pointer words in the
    80          * context structure; this is for debugging use.
    81          */
    82         thread->md.sp = _MD_GET_SP_PTR(thread);
    83         thread->md.fp = _MD_GET_FP_PTR(thread);
    84         return PR_SUCCESS;
    85 }
    86 
    87 PRStatus
    88 _MD_WAIT(PRThread *thread, PRIntervalTime ticks)
    89 {
    90     PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
    91     _PR_MD_SWITCH_CONTEXT(thread);
    92     return PR_SUCCESS;
    93 }
    94 
    95 PRStatus
    96 _MD_WAKEUP_WAITER(PRThread *thread)
    97 {
    98     if (thread) {
    99         PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
    100     }
    101     return PR_SUCCESS;
    102 }
    103 
    104 /* These functions should not be called for Linux */
    105 void
    106 _MD_YIELD(void)
    107 {
    108     PR_NOT_REACHED("_MD_YIELD should not be called for Linux.");
    109 }
    110 
    111 PRStatus
    112 _MD_CREATE_THREAD(
    113     PRThread *thread,
    114     void (*start) (void *),
    115     PRThreadPriority priority,
    116     PRThreadScope scope,
    117     PRThreadState state,
    118     PRUint32 stackSize)
    119 {
    120     PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Linux.");
    121         return PR_FAILURE;
    122 }
    123 #endif /* ! _PR_PTHREADS */
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/unix/netbsd.c

    r1 r101805  
    5858PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
    5959{
    60 #ifndef _PR_PTHREADS
    61     if (isCurrent) {
    62         (void) sigsetjmp(CONTEXT(t), 1);
    63     }
    64     *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
    65     return (PRWord *) CONTEXT(t);
    66 #else
    6760    *np = 0;
    6861    return NULL;
    69 #endif
    7062}
    7163
    72 #ifndef _PR_PTHREADS
    73 void
    74 _MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
    75 {
    76     return;
    77 }
    78 
    79 PRStatus
    80 _MD_InitializeThread(PRThread *thread)
    81 {
    82     return PR_SUCCESS;
    83 }
    84 
    85 PRStatus
    86 _MD_WAIT(PRThread *thread, PRIntervalTime ticks)
    87 {
    88     PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
    89     _PR_MD_SWITCH_CONTEXT(thread);
    90     return PR_SUCCESS;
    91 }
    92 
    93 PRStatus
    94 _MD_WAKEUP_WAITER(PRThread *thread)
    95 {
    96     if (thread) {
    97         PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
    98     }
    99     return PR_SUCCESS;
    100 }
    101 
    102 /* These functions should not be called for NetBSD */
    103 void
    104 _MD_YIELD(void)
    105 {
    106     PR_NOT_REACHED("_MD_YIELD should not be called for NetBSD.");
    107 }
    108 
    109 PRStatus
    110 _MD_CREATE_THREAD(
    111     PRThread *thread,
    112     void (*start) (void *),
    113     PRThreadPriority priority,
    114     PRThreadScope scope,
    115     PRThreadState state,
    116     PRUint32 stackSize)
    117 {
    118     PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for NetBSD.");
    119     return PR_FAILURE;
    120 }
    121 #endif /* ! _PR_PTHREADS */
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/unix/openbsd.c

    r1 r101805  
    5858PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
    5959{
    60 #ifndef _PR_PTHREADS
    61     if (isCurrent) {
    62         (void) sigsetjmp(CONTEXT(t), 1);
    63     }
    64     *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
    65     return (PRWord *) CONTEXT(t);
    66 #else
    6760    *np = 0;
    6861    return NULL;
    69 #endif
    7062}
    7163
    72 #ifndef _PR_PTHREADS
    73 void
    74 _MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
    75 {
    76     return;
    77 }
    78 
    79 PRStatus
    80 _MD_InitializeThread(PRThread *thread)
    81 {
    82     return PR_SUCCESS;
    83 }
    84 
    85 PRStatus
    86 _MD_WAIT(PRThread *thread, PRIntervalTime ticks)
    87 {
    88     PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
    89     _PR_MD_SWITCH_CONTEXT(thread);
    90     return PR_SUCCESS;
    91 }
    92 
    93 PRStatus
    94 _MD_WAKEUP_WAITER(PRThread *thread)
    95 {
    96     if (thread) {
    97         PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
    98     }
    99     return PR_SUCCESS;
    100 }
    101 
    102 /* These functions should not be called for OpenBSD */
    103 void
    104 _MD_YIELD(void)
    105 {
    106     PR_NOT_REACHED("_MD_YIELD should not be called for OpenBSD.");
    107 }
    108 
    109 PRStatus
    110 _MD_CREATE_THREAD(
    111     PRThread *thread,
    112     void (*start) (void *),
    113     PRThreadPriority priority,
    114     PRThreadScope scope,
    115     PRThreadState state,
    116     PRUint32 stackSize)
    117 {
    118     PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for OpenBSD.");
    119     return PR_FAILURE;
    120 }
    121 #endif /* ! _PR_PTHREADS */
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/unix/solaris.c

    r1 r101805  
    7575}
    7676
    77 #ifdef _PR_PTHREADS
    7877void _MD_EarlyInit(void)
    7978{
     
    8584        return NULL;
    8685}
    87 #endif /* _PR_PTHREADS */
    8886
    8987#if !defined(i386) && !defined(IS_64)
     
    636634}
    637635
    638 #ifdef OLD_CODE
    639 
    640 void _MD_SuspendAll()
    641 {
    642     /* On solaris there are threads, and there are LWPs.
    643      * Calling _PR_DoSingleThread would freeze all of the threads bound to LWPs
    644      * but not necessarily stop all LWPs (for example if someone did
    645      * an attachthread of a thread which was not bound to an LWP).
    646      * So now go through all the LWPs for this process and freeze them.
    647      *
    648      * Note that if any thread which is capable of having the GC run on it must
    649      * had better be a LWP with a single bound thread on it.  Otherwise, this
    650      * might not stop that thread from being run.
    651      */
    652     PRThread *current = _PR_MD_CURRENT_THREAD();
    653     prstatus_t status, lwpstatus;
    654     int result, index, lwp_fd;
    655     lwpid_t me = _lwp_self();
    656     int err;
    657     int lwp_main_proc_fd;
    658 
    659     solaris_preempt_off();
    660 
    661     /* run at highest prio so I cannot be preempted */
    662     thr_getprio(thr_self(), &gcprio);
    663     thr_setprio(thr_self(), 0x7fffffff);
    664 
    665     current->md.sp = (uint_t)&me;       /* set my own stack pointer */
    666 
    667     if ( (lwp_main_proc_fd = solaris_open_main_proc_fd()) < 0) {
    668         PR_ASSERT(0);
    669         solaris_preempt_on();
    670         return;   /* XXXMB ARGH, we're hosed! */
    671     }
    672 
    673     if ( (result = syscall(SYS_ioctl, lwp_main_proc_fd, PIOCSTATUS, &status)) < 0) {
    674         err = errno;
    675         PR_ASSERT(0);
    676         goto failure;   /* XXXMB ARGH, we're hosed! */
    677     }
    678 
    679     num_lwps = status.pr_nlwp;
    680 
    681     if ( (all_lwps = (lwpid_t *)PR_MALLOC((num_lwps+1) * sizeof(lwpid_t)))==NULL) {
    682         PR_ASSERT(0);
    683         goto failure;   /* XXXMB ARGH, we're hosed! */
    684     }
    685            
    686     if ( (result = syscall(SYS_ioctl, lwp_main_proc_fd, PIOCLWPIDS, all_lwps)) < 0) {
    687         PR_ASSERT(0);
    688         PR_DELETE(all_lwps);
    689         goto failure;   /* XXXMB ARGH, we're hosed! */
    690     }
    691 
    692     for (index=0; index< num_lwps; index++) {
    693         if (all_lwps[index] != me)  {
    694             if (_lwp_suspend(all_lwps[index]) < 0) {
    695                 /* could happen if lwp exited */
    696                 all_lwps[index] = me;   /* dummy it up */
    697             }
    698         }
    699     }
    700 
    701     /* Turns out that lwp_suspend is not a blocking call.
    702      * Go through the list and make sure they are all stopped.
    703      */
    704     for (index=0; index< num_lwps; index++) {
    705         if (all_lwps[index] != me)  {
    706             if ( (lwp_fd = solaris_open_lwp(all_lwps[index], lwp_main_proc_fd)) < 0) {
    707                 PR_ASSERT(0);
    708                 PR_DELETE(all_lwps);
    709                 all_lwps = NULL;
    710                 goto failure;   /* XXXMB ARGH, we're hosed! */
    711             }
    712 
    713             if ( (result = syscall(SYS_ioctl, lwp_fd, PIOCSTATUS, &lwpstatus)) < 0) {
    714                 /* Hopefully the thread just died... */
    715                 close(lwp_fd);
    716                 continue;
    717             }
    718             while ( !(lwpstatus.pr_flags & PR_STOPPED) ) {
    719                 if ( (result = syscall(SYS_ioctl, lwp_fd, PIOCSTATUS, &lwpstatus)) < 0) {
    720                     PR_ASSERT(0);  /* ARGH SOMETHING WRONG! */
    721                     break;
    722                 }
    723                 solaris_msec_sleep(1);
    724             }
    725             solaris_record_regs(&lwpstatus);
    726             close(lwp_fd);
    727         }
    728     }
    729 
    730     close(lwp_main_proc_fd);
    731 
    732     return;
    733 failure:
    734     solaris_preempt_on();
    735     thr_setprio(thr_self(), gcprio);
    736     close(lwp_main_proc_fd);
    737     return;
    738 }
    739 
    740 void _MD_ResumeAll()
    741 {
    742     int i;
    743     lwpid_t me = _lwp_self();
    744  
    745     for (i=0; i < num_lwps; i++) {
    746         if (all_lwps[i] == me)
    747             continue;
    748         if ( _lwp_continue(all_lwps[i]) < 0) {
    749             PR_ASSERT(0);  /* ARGH, we are hosed! */
    750         }
    751     }
    752 
    753     /* restore priority and sigmask */
    754     thr_setprio(thr_self(), gcprio);
    755     solaris_preempt_on();
    756     PR_DELETE(all_lwps);
    757     all_lwps = NULL;
    758 }
    759 #endif /* OLD_CODE */
    760 
    761636#ifdef USE_SETJMP
    762637PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
     
    862737
    863738#endif /* _PR_GLOBAL_THREADS_ONLY */
    864 
    865 #ifndef _PR_PTHREADS
    866 #if defined(i386) && defined(SOLARIS2_4)
    867 /*
    868  * Because clock_gettime() on Solaris/x86 2.4 always generates a
    869  * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),
    870  * which is implemented using gettimeofday().
    871  */
    872 
    873 int
    874 _pr_solx86_clock_gettime(clockid_t clock_id, struct timespec *tp)
    875 {
    876     struct timeval tv;
    877 
    878     if (clock_id != CLOCK_REALTIME) {
    879         errno = EINVAL;
    880         return -1;
    881     }
    882 
    883     gettimeofday(&tv, NULL);
    884     tp->tv_sec = tv.tv_sec;
    885     tp->tv_nsec = tv.tv_usec * 1000;
    886     return 0;
    887 }
    888 #endif  /* i386 && SOLARIS2_4 */
    889 #endif  /* _PR_PTHREADS */
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/unix/unix.c

    r101749 r101805  
    9797sigset_t timer_set;
    9898
    99 #if !defined(_PR_PTHREADS)
    100 
    101 static sigset_t empty_set;
    102 
    103 #ifdef SOLARIS
    104 #include <sys/file.h>
    105 #include <sys/filio.h>
    106 #endif
    107 
    108 #ifndef PIPE_BUF
    109 #define PIPE_BUF 512
    110 #endif
    111 
    112 /*
    113  * _nspr_noclock - if set clock interrupts are disabled
    114  */
    115 int _nspr_noclock = 1;
    116 
    117 #ifdef IRIX
    118 extern PRInt32 _nspr_terminate_on_error;
    119 #endif
    120 
    121 /*
    122  * There is an assertion in this code that NSPR's definition of PRIOVec
    123  * is bit compatible with UNIX' definition of a struct iovec. This is
    124  * applicable to the 'writev()' operations where the types are casually
    125  * cast to avoid warnings.
    126  */
    127 
    128 int _pr_md_pipefd[2] = { -1, -1 };
    129 static char _pr_md_pipebuf[PIPE_BUF];
    130 static PRInt32 local_io_wait(PRInt32 osfd, PRInt32 wait_flag,
    131                                                         PRIntervalTime timeout);
    132 
    133 _PRInterruptTable _pr_interruptTable[] = {
    134     {
    135         "clock", _PR_MISSED_CLOCK, _PR_ClockInterrupt,     },
    136     {
    137         0     }
    138 };
    139 
    140 PR_IMPLEMENT(void) _MD_unix_init_running_cpu(_PRCPU *cpu)
    141 {
    142     PR_INIT_CLIST(&(cpu->md.md_unix.ioQ));
    143     cpu->md.md_unix.ioq_max_osfd = -1;
    144     cpu->md.md_unix.ioq_timeout = PR_INTERVAL_NO_TIMEOUT;
    145 }
    146 
    147 PRStatus _MD_open_dir(_MDDir *d, const char *name)
    148 {
    149 int err;
    150 
    151     d->d = opendir(name);
    152     if (!d->d) {
    153         err = _MD_ERRNO();
    154         _PR_MD_MAP_OPENDIR_ERROR(err);
    155         return PR_FAILURE;
    156     }
    157     return PR_SUCCESS;
    158 }
    159 
    160 PRInt32 _MD_close_dir(_MDDir *d)
    161 {
    162 int rv = 0, err;
    163 
    164     if (d->d) {
    165         rv = closedir(d->d);
    166         if (rv == -1) {
    167                 err = _MD_ERRNO();
    168                 _PR_MD_MAP_CLOSEDIR_ERROR(err);
    169         }
    170     }
    171     return rv;
    172 }
    173 
    174 char * _MD_read_dir(_MDDir *d, PRIntn flags)
    175 {
    176 struct dirent *de;
    177 int err;
    178 
    179     for (;;) {
    180         /*
    181           * XXX: readdir() is not MT-safe. There is an MT-safe version
    182           * readdir_r() on some systems.
    183           */
    184         de = readdir(d->d);
    185         if (!de) {
    186             err = _MD_ERRNO();
    187             _PR_MD_MAP_READDIR_ERROR(err);
    188             return 0;
    189         }       
    190         if ((flags & PR_SKIP_DOT) &&
    191             (de->d_name[0] == '.') && (de->d_name[1] == 0))
    192             continue;
    193         if ((flags & PR_SKIP_DOT_DOT) &&
    194             (de->d_name[0] == '.') && (de->d_name[1] == '.') &&
    195             (de->d_name[2] == 0))
    196             continue;
    197         if ((flags & PR_SKIP_HIDDEN) && (de->d_name[0] == '.'))
    198             continue;
    199         break;
    200     }
    201     return de->d_name;
    202 }
    203 
    204 PRInt32 _MD_delete(const char *name)
    205 {
    206 PRInt32 rv, err;
    207 #ifdef UNIXWARE
    208     sigset_t set, oset;
    209 #endif
    210 
    211 #ifdef UNIXWARE
    212     sigfillset(&set);
    213     sigprocmask(SIG_SETMASK, &set, &oset);
    214 #endif
    215     rv = unlink(name);
    216 #ifdef UNIXWARE
    217     sigprocmask(SIG_SETMASK, &oset, NULL);
    218 #endif
    219     if (rv == -1) {
    220             err = _MD_ERRNO();
    221             _PR_MD_MAP_UNLINK_ERROR(err);
    222     }
    223     return(rv);
    224 }
    225 
    226 PRInt32 _MD_rename(const char *from, const char *to)
    227 {
    228     PRInt32 rv = -1, err;
    229 
    230     /*
    231     ** This is trying to enforce the semantics of WINDOZE' rename
    232     ** operation. That means one is not allowed to rename over top
    233     ** of an existing file. Holding a lock across these two function
    234     ** and the open function is known to be a bad idea, but ....
    235     */
    236     if (NULL != _pr_rename_lock)
    237         PR_Lock(_pr_rename_lock);
    238     if (0 == access(to, F_OK))
    239         PR_SetError(PR_FILE_EXISTS_ERROR, 0);
    240     else
    241     {
    242         rv = rename(from, to);
    243         if (rv < 0) {
    244             err = _MD_ERRNO();
    245             _PR_MD_MAP_RENAME_ERROR(err);
    246         }
    247     }
    248     if (NULL != _pr_rename_lock)
    249         PR_Unlock(_pr_rename_lock);
    250     return rv;
    251 }
    252 
    253 PRInt32 _MD_access(const char *name, PRAccessHow how)
    254 {
    255 PRInt32 rv, err;
    256 int amode;
    257 
    258     switch (how) {
    259         case PR_ACCESS_WRITE_OK:
    260             amode = W_OK;
    261             break;
    262         case PR_ACCESS_READ_OK:
    263             amode = R_OK;
    264             break;
    265         case PR_ACCESS_EXISTS:
    266             amode = F_OK;
    267             break;
    268         default:
    269             PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
    270             rv = -1;
    271             goto done;
    272     }
    273     rv = access(name, amode);
    274 
    275     if (rv < 0) {
    276         err = _MD_ERRNO();
    277         _PR_MD_MAP_ACCESS_ERROR(err);
    278     }
    279 
    280 done:
    281     return(rv);
    282 }
    283 
    284 PRInt32 _MD_mkdir(const char *name, PRIntn mode)
    285 {
    286 int rv, err;
    287 
    288     /*
    289     ** This lock is used to enforce rename semantics as described
    290     ** in PR_Rename. Look there for more fun details.
    291     */
    292     if (NULL !=_pr_rename_lock)
    293         PR_Lock(_pr_rename_lock);
    294     rv = mkdir(name, mode);
    295     if (rv < 0) {
    296         err = _MD_ERRNO();
    297         _PR_MD_MAP_MKDIR_ERROR(err);
    298     }
    299     if (NULL !=_pr_rename_lock)
    300         PR_Unlock(_pr_rename_lock);
    301     return rv;
    302 }
    303 
    304 PRInt32 _MD_rmdir(const char *name)
    305 {
    306 int rv, err;
    307 
    308     rv = rmdir(name);
    309     if (rv == -1) {
    310             err = _MD_ERRNO();
    311             _PR_MD_MAP_RMDIR_ERROR(err);
    312     }
    313     return rv;
    314 }
    315 
    316 PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount)
    317 {
    318 PRThread *me = _PR_MD_CURRENT_THREAD();
    319 PRInt32 rv, err;
    320 #ifndef _PR_USE_POLL
    321 fd_set rd;
    322 #else
    323 struct pollfd pfd;
    324 #endif /* _PR_USE_POLL */
    325 PRInt32 osfd = fd->secret->md.osfd;
    326 
    327 #ifndef _PR_USE_POLL
    328     FD_ZERO(&rd);
    329     FD_SET(osfd, &rd);
    330 #else
    331     pfd.fd = osfd;
    332     pfd.events = POLLIN;
    333 #endif /* _PR_USE_POLL */
    334     while ((rv = read(osfd,buf,amount)) == -1) {
    335         err = _MD_ERRNO();
    336         if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
    337             if (fd->secret->nonblocking) {
    338                 break;
    339             }
    340             if (!_PR_IS_NATIVE_THREAD(me)) {
    341                 if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ,
    342                                                                                 PR_INTERVAL_NO_TIMEOUT)) < 0)
    343                                         goto done;                                                             
    344             } else {
    345 #ifndef _PR_USE_POLL
    346                 while ((rv = _MD_SELECT(osfd + 1, &rd, NULL, NULL, NULL))
    347                         == -1 && (err = _MD_ERRNO()) == EINTR) {
    348                     /* retry _MD_SELECT() if it is interrupted */
    349                 }
    350 #else /* _PR_USE_POLL */
    351                 while ((rv = _MD_POLL(&pfd, 1, -1))
    352                         == -1 && (err = _MD_ERRNO()) == EINTR) {
    353                     /* retry _MD_POLL() if it is interrupted */
    354                 }
    355 #endif /* _PR_USE_POLL */
    356                 if (rv == -1) {
    357                     break;
    358                 }
    359             }
    360             if (_PR_PENDING_INTERRUPT(me))
    361                 break;
    362         } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
    363             continue;
    364         } else {
    365             break;
    366         }
    367     }
    368     if (rv < 0) {
    369         if (_PR_PENDING_INTERRUPT(me)) {
    370             me->flags &= ~_PR_INTERRUPT;
    371             PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
    372         } else {
    373             _PR_MD_MAP_READ_ERROR(err);
    374         }
    375     }
    376 done:
    377     return(rv);
    378 }
    379 
    380 PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount)
    381 {
    382 PRThread *me = _PR_MD_CURRENT_THREAD();
    383 PRInt32 rv, err;
    384 #ifndef _PR_USE_POLL
    385 fd_set wd;
    386 #else
    387 struct pollfd pfd;
    388 #endif /* _PR_USE_POLL */
    389 PRInt32 osfd = fd->secret->md.osfd;
    390 
    391 #ifndef _PR_USE_POLL
    392     FD_ZERO(&wd);
    393     FD_SET(osfd, &wd);
    394 #else
    395     pfd.fd = osfd;
    396     pfd.events = POLLOUT;
    397 #endif /* _PR_USE_POLL */
    398     while ((rv = write(osfd,buf,amount)) == -1) {
    399         err = _MD_ERRNO();
    400         if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
    401             if (fd->secret->nonblocking) {
    402                 break;
    403             }
    404             if (!_PR_IS_NATIVE_THREAD(me)) {
    405                 if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE,
    406                                                                                 PR_INTERVAL_NO_TIMEOUT)) < 0)
    407                     goto done;
    408             } else {
    409 #ifndef _PR_USE_POLL
    410                 while ((rv = _MD_SELECT(osfd + 1, NULL, &wd, NULL, NULL))
    411                         == -1 && (err = _MD_ERRNO()) == EINTR) {
    412                     /* retry _MD_SELECT() if it is interrupted */
    413                 }
    414 #else /* _PR_USE_POLL */
    415                 while ((rv = _MD_POLL(&pfd, 1, -1))
    416                         == -1 && (err = _MD_ERRNO()) == EINTR) {
    417                     /* retry _MD_POLL() if it is interrupted */
    418                 }
    419 #endif /* _PR_USE_POLL */
    420                 if (rv == -1) {
    421                     break;
    422                 }
    423             }
    424             if (_PR_PENDING_INTERRUPT(me))
    425                 break;
    426         } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
    427             continue;
    428         } else {
    429             break;
    430         }
    431     }
    432     if (rv < 0) {
    433         if (_PR_PENDING_INTERRUPT(me)) {
    434             me->flags &= ~_PR_INTERRUPT;
    435             PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
    436         } else {
    437             _PR_MD_MAP_WRITE_ERROR(err);
    438         }
    439     }
    440 done:
    441     return(rv);
    442 }
    443 
    444 PRInt32 _MD_fsync(PRFileDesc *fd)
    445 {
    446 PRInt32 rv, err;
    447 
    448     rv = fsync(fd->secret->md.osfd);
    449     if (rv == -1) {
    450         err = _MD_ERRNO();
    451         _PR_MD_MAP_FSYNC_ERROR(err);
    452     }
    453     return(rv);
    454 }
    455 
    456 PRInt32 _MD_close(PRInt32 osfd)
    457 {
    458 PRInt32 rv, err;
    459 
    460     rv = close(osfd);
    461     if (rv == -1) {
    462         err = _MD_ERRNO();
    463         _PR_MD_MAP_CLOSE_ERROR(err);
    464     }
    465     return(rv);
    466 }
    467 
    468 PRInt32 _MD_socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
    469 {
    470     PRInt32 osfd, err;
    471 
    472     osfd = socket(domain, type, proto);
    473 
    474     if (osfd == -1) {
    475         err = _MD_ERRNO();
    476         _PR_MD_MAP_SOCKET_ERROR(err);
    477         return(osfd);
    478     }
    479 
    480     return(osfd);
    481 }
    482 
    483 PRInt32 _MD_socketavailable(PRFileDesc *fd)
    484 {
    485     PRInt32 result;
    486 
    487     if (ioctl(fd->secret->md.osfd, FIONREAD, &result) < 0) {
    488         _PR_MD_MAP_SOCKETAVAILABLE_ERROR(_MD_ERRNO());
    489         return -1;
    490     }
    491     return result;
    492 }
    493 
    494 PRInt64 _MD_socketavailable64(PRFileDesc *fd)
    495 {
    496     PRInt64 result;
    497     LL_I2L(result, _MD_socketavailable(fd));
    498     return result;
    499 }  /* _MD_socketavailable64 */
    500 
    501 #define READ_FD        1
    502 #define WRITE_FD    2
    503 
    504 /*
    505  * socket_io_wait --
    506  *
    507  * wait for socket i/o, periodically checking for interrupt
    508  *
    509  * The first implementation uses select(), for platforms without
    510  * poll().  The second (preferred) implementation uses poll().
    511  */
    512 
    513 #ifndef _PR_USE_POLL
    514 
    515 static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
    516     PRIntervalTime timeout)
    517 {
    518     PRInt32 rv = -1;
    519     struct timeval tv;
    520     PRThread *me = _PR_MD_CURRENT_THREAD();
    521     PRIntervalTime epoch, now, elapsed, remaining;
    522     PRBool wait_for_remaining;
    523     PRInt32 syserror;
    524     fd_set rd_wr;
    525 
    526     switch (timeout) {
    527         case PR_INTERVAL_NO_WAIT:
    528             PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
    529             break;
    530         case PR_INTERVAL_NO_TIMEOUT:
    531             /*
    532              * This is a special case of the 'default' case below.
    533              * Please see the comments there.
    534              */
    535             tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
    536             tv.tv_usec = 0;
    537             FD_ZERO(&rd_wr);
    538             do {
    539                 FD_SET(osfd, &rd_wr);
    540                 if (fd_type == READ_FD)
    541                     rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
    542                 else
    543                     rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
    544                 if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
    545                     _PR_MD_MAP_SELECT_ERROR(syserror);
    546                     break;
    547                 }
    548                 if (_PR_PENDING_INTERRUPT(me)) {
    549                     me->flags &= ~_PR_INTERRUPT;
    550                     PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
    551                     rv = -1;
    552                     break;
    553                 }
    554             } while (rv == 0 || (rv == -1 && syserror == EINTR));
    555             break;
    556         default:
    557             now = epoch = PR_IntervalNow();
    558             remaining = timeout;
    559             FD_ZERO(&rd_wr);
    560             do {
    561                 /*
    562                  * We block in _MD_SELECT for at most
    563                  * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
    564                  * so that there is an upper limit on the delay
    565                  * before the interrupt bit is checked.
    566                  */
    567                 wait_for_remaining = PR_TRUE;
    568                 tv.tv_sec = PR_IntervalToSeconds(remaining);
    569                 if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
    570                     wait_for_remaining = PR_FALSE;
    571                     tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
    572                     tv.tv_usec = 0;
    573                 } else {
    574                     tv.tv_usec = PR_IntervalToMicroseconds(
    575                         remaining -
    576                         PR_SecondsToInterval(tv.tv_sec));
    577                 }
    578                 FD_SET(osfd, &rd_wr);
    579                 if (fd_type == READ_FD)
    580                     rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
    581                 else
    582                     rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
    583                 /*
    584                  * we don't consider EINTR a real error
    585                  */
    586                 if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
    587                     _PR_MD_MAP_SELECT_ERROR(syserror);
    588                     break;
    589                 }
    590                 if (_PR_PENDING_INTERRUPT(me)) {
    591                     me->flags &= ~_PR_INTERRUPT;
    592                     PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
    593                     rv = -1;
    594                     break;
    595                 }
    596                 /*
    597                  * We loop again if _MD_SELECT timed out or got interrupted
    598                  * by a signal, and the timeout deadline has not passed yet.
    599                  */
    600                 if (rv == 0 || (rv == -1 && syserror == EINTR)) {
    601                     /*
    602                      * If _MD_SELECT timed out, we know how much time
    603                      * we spent in blocking, so we can avoid a
    604                      * PR_IntervalNow() call.
    605                      */
    606                     if (rv == 0) {
    607                         if (wait_for_remaining) {
    608                             now += remaining;
    609                         } else {
    610                             now += PR_SecondsToInterval(tv.tv_sec)
    611                                 + PR_MicrosecondsToInterval(tv.tv_usec);
    612                         }
    613                     } else {
    614                         now = PR_IntervalNow();
    615                     }
    616                     elapsed = (PRIntervalTime) (now - epoch);
    617                     if (elapsed >= timeout) {
    618                         PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
    619                         rv = -1;
    620                         break;
    621                     } else {
    622                         remaining = timeout - elapsed;
    623                     }
    624                 }
    625             } while (rv == 0 || (rv == -1 && syserror == EINTR));
    626             break;
    627     }
    628     return(rv);
    629 }
    630 
    631 #else /* _PR_USE_POLL */
    632 
    633 static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
    634     PRIntervalTime timeout)
    635 {
    636     PRInt32 rv = -1;
    637     int msecs;
    638     PRThread *me = _PR_MD_CURRENT_THREAD();
    639     PRIntervalTime epoch, now, elapsed, remaining;
    640     PRBool wait_for_remaining;
    641     PRInt32 syserror;
    642     struct pollfd pfd;
    643 
    644     switch (timeout) {
    645         case PR_INTERVAL_NO_WAIT:
    646             PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
    647             break;
    648         case PR_INTERVAL_NO_TIMEOUT:
    649             /*
    650              * This is a special case of the 'default' case below.
    651              * Please see the comments there.
    652              */
    653             msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
    654             pfd.fd = osfd;
    655             if (fd_type == READ_FD) {
    656                 pfd.events = POLLIN;
    657             } else {
    658                 pfd.events = POLLOUT;
    659             }
    660             do {
    661                 rv = _MD_POLL(&pfd, 1, msecs);
    662                 if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
    663                     _PR_MD_MAP_POLL_ERROR(syserror);
    664                     break;
    665                 }
    666                                 /*
    667                                  * If POLLERR is set, don't process it; retry the operation
    668                                  */
    669                 if ((rv == 1) && (pfd.revents & (POLLHUP | POLLNVAL))) {
    670                                         rv = -1;
    671                     _PR_MD_MAP_POLL_REVENTS_ERROR(pfd.revents);
    672                     break;
    673                 }
    674                 if (_PR_PENDING_INTERRUPT(me)) {
    675                     me->flags &= ~_PR_INTERRUPT;
    676                     PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
    677                     rv = -1;
    678                     break;
    679                 }
    680             } while (rv == 0 || (rv == -1 && syserror == EINTR));
    681             break;
    682         default:
    683             now = epoch = PR_IntervalNow();
    684             remaining = timeout;
    685             pfd.fd = osfd;
    686             if (fd_type == READ_FD) {
    687                 pfd.events = POLLIN;
    688             } else {
    689                 pfd.events = POLLOUT;
    690             }
    691             do {
    692                 /*
    693                  * We block in _MD_POLL for at most
    694                  * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
    695                  * so that there is an upper limit on the delay
    696                  * before the interrupt bit is checked.
    697                  */
    698                 wait_for_remaining = PR_TRUE;
    699                 msecs = PR_IntervalToMilliseconds(remaining);
    700                 if (msecs > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) {
    701                     wait_for_remaining = PR_FALSE;
    702                     msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
    703                 }
    704                 rv = _MD_POLL(&pfd, 1, msecs);
    705                 /*
    706                  * we don't consider EINTR a real error
    707                  */
    708                 if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
    709                     _PR_MD_MAP_POLL_ERROR(syserror);
    710                     break;
    711                 }
    712                 if (_PR_PENDING_INTERRUPT(me)) {
    713                     me->flags &= ~_PR_INTERRUPT;
    714                     PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
    715                     rv = -1;
    716                     break;
    717                 }
    718                                 /*
    719                                  * If POLLERR is set, don't process it; retry the operation
    720                                  */
    721                 if ((rv == 1) && (pfd.revents & (POLLHUP | POLLNVAL))) {
    722                                         rv = -1;
    723                     _PR_MD_MAP_POLL_REVENTS_ERROR(pfd.revents);
    724                     break;
    725                 }
    726                 /*
    727                  * We loop again if _MD_POLL timed out or got interrupted
    728                  * by a signal, and the timeout deadline has not passed yet.
    729                  */
    730                 if (rv == 0 || (rv == -1 && syserror == EINTR)) {
    731                     /*
    732                      * If _MD_POLL timed out, we know how much time
    733                      * we spent in blocking, so we can avoid a
    734                      * PR_IntervalNow() call.
    735                      */
    736                     if (rv == 0) {
    737                         if (wait_for_remaining) {
    738                             now += remaining;
    739                         } else {
    740                             now += PR_MillisecondsToInterval(msecs);
    741                         }
    742                     } else {
    743                         now = PR_IntervalNow();
    744                     }
    745                     elapsed = (PRIntervalTime) (now - epoch);
    746                     if (elapsed >= timeout) {
    747                         PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
    748                         rv = -1;
    749                         break;
    750                     } else {
    751                         remaining = timeout - elapsed;
    752                     }
    753                 }
    754             } while (rv == 0 || (rv == -1 && syserror == EINTR));
    755             break;
    756     }
    757     return(rv);
    758 }
    759 
    760 #endif /* _PR_USE_POLL */
    761 
    762 static PRInt32 local_io_wait(
    763     PRInt32 osfd,
    764     PRInt32 wait_flag,
    765     PRIntervalTime timeout)
    766 {
    767     _PRUnixPollDesc pd;
    768     PRInt32 rv;
    769 
    770     PR_LOG(_pr_io_lm, PR_LOG_MIN,
    771        ("waiting to %s on osfd=%d",
    772         (wait_flag == _PR_UNIX_POLL_READ) ? "read" : "write",
    773         osfd));
    774 
    775     if (timeout == PR_INTERVAL_NO_WAIT) return 0;
    776 
    777     pd.osfd = osfd;
    778     pd.in_flags = wait_flag;
    779     pd.out_flags = 0;
    780 
    781     rv = _PR_WaitForMultipleFDs(&pd, 1, timeout);
    782 
    783     if (rv == 0) {
    784         PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
    785         rv = -1;
    786     }
    787     return rv;
    788 }
    789 
    790 
    791 PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
    792                                 PRInt32 flags, PRIntervalTime timeout)
    793 {
    794     PRInt32 osfd = fd->secret->md.osfd;
    795     PRInt32 rv, err;
    796     PRThread *me = _PR_MD_CURRENT_THREAD();
    797 
    798 /*
    799  * Many OS's (Solaris, Unixware) have a broken recv which won't read
    800  * from socketpairs.  As long as we don't use flags on socketpairs, this
    801  * is a decent fix. - mikep
    802  */
    803 #if defined(UNIXWARE) || defined(SOLARIS) || defined(NCR)
    804     while ((rv = read(osfd,buf,amount)) == -1) {
    805 #else
    806     while ((rv = recv(osfd,buf,amount,flags)) == -1) {
    807 #endif
    808         err = _MD_ERRNO();
    809         if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
    810             if (fd->secret->nonblocking) {
    811                 break;
    812             }
    813             if (!_PR_IS_NATIVE_THREAD(me)) {
    814                                 if ((rv = local_io_wait(osfd,_PR_UNIX_POLL_READ,timeout)) < 0)
    815                                         goto done;
    816             } else {
    817                 if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
    818                     goto done;
    819             }
    820         } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
    821             continue;
    822         } else {
    823             break;
    824         }
    825     }
    826     if (rv < 0) {
    827         _PR_MD_MAP_RECV_ERROR(err);
    828     }
    829 done:
    830     return(rv);
    831 }
    832 
    833 PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,
    834                         PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen,
    835                         PRIntervalTime timeout)
    836 {
    837     PRInt32 osfd = fd->secret->md.osfd;
    838     PRInt32 rv, err;
    839     PRThread *me = _PR_MD_CURRENT_THREAD();
    840 
    841     while ((*addrlen = PR_NETADDR_SIZE(addr)),
    842                 ((rv = recvfrom(osfd, buf, amount, flags,
    843                         (struct sockaddr *) addr, (_PRSockLen_t *)addrlen)) == -1)) {
    844         err = _MD_ERRNO();
    845         if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
    846             if (fd->secret->nonblocking) {
    847                 break;
    848             }
    849             if (!_PR_IS_NATIVE_THREAD(me)) {
    850                 if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ, timeout)) < 0)
    851                     goto done;
    852             } else {
    853                 if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
    854                     goto done;
    855             }
    856         } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
    857             continue;
    858         } else {
    859             break;
    860         }
    861     }
    862     if (rv < 0) {
    863         _PR_MD_MAP_RECVFROM_ERROR(err);
    864     }
    865 done:
    866 #ifdef _PR_HAVE_SOCKADDR_LEN
    867     if (rv != -1) {
    868         /* ignore the sa_len field of struct sockaddr */
    869         if (addr) {
    870             addr->raw.family = ((struct sockaddr *) addr)->sa_family;
    871         }
    872     }
    873 #endif /* _PR_HAVE_SOCKADDR_LEN */
    874     return(rv);
    875 }
    876 
    877 PRInt32 _MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
    878                             PRInt32 flags, PRIntervalTime timeout)
    879 {
    880     PRInt32 osfd = fd->secret->md.osfd;
    881     PRInt32 rv, err;
    882     PRThread *me = _PR_MD_CURRENT_THREAD();
    883 #if defined(SOLARIS)
    884         PRInt32 tmp_amount = amount;
    885 #endif
    886 
    887     /*
    888      * On pre-2.6 Solaris, send() is much slower than write().
    889      * On 2.6 and beyond, with in-kernel sockets, send() and
    890      * write() are fairly equivalent in performance.
    891      */
    892 #if defined(SOLARIS)
    893     PR_ASSERT(0 == flags);
    894     while ((rv = write(osfd,buf,tmp_amount)) == -1) {
    895 #else
    896     while ((rv = send(osfd,buf,amount,flags)) == -1) {
    897 #endif
    898         err = _MD_ERRNO();
    899         if ((err == EAGAIN) || (err == EWOULDBLOCK))    {
    900             if (fd->secret->nonblocking) {
    901                 break;
    902             }
    903             if (!_PR_IS_NATIVE_THREAD(me)) {
    904                 if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0)
    905                     goto done;
    906             } else {
    907                 if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
    908                     goto done;
    909             }
    910         } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
    911             continue;
    912         } else {
    913 #if defined(SOLARIS)
    914                         /*
    915                          * The write system call has been reported to return the ERANGE
    916                          * error on occasion. Try to write in smaller chunks to workaround
    917                          * this bug.
    918                          */
    919                         if (err == ERANGE) {
    920                                 if (tmp_amount > 1) {
    921                                         tmp_amount = tmp_amount/2;      /* half the bytes */
    922                                         continue;
    923                                 }
    924                         }
    925 #endif
    926             break;
    927         }
    928     }
    929         /*
    930          * optimization; if bytes sent is less than "amount" call
    931          * select before returning. This is because it is likely that
    932          * the next send() call will return EWOULDBLOCK.
    933          */
    934     if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
    935             && (timeout != PR_INTERVAL_NO_WAIT)) {
    936         if (_PR_IS_NATIVE_THREAD(me)) {
    937                         if (socket_io_wait(osfd, WRITE_FD, timeout)< 0) {
    938                                 rv = -1;
    939                                 goto done;
    940                         }
    941         } else {
    942                         if (local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout) < 0) {
    943                                 rv = -1;
    944                                 goto done;
    945                         }
    946         }
    947     }
    948     if (rv < 0) {
    949         _PR_MD_MAP_SEND_ERROR(err);
    950     }
    951 done:
    952     return(rv);
    953 }
    954 
    955 PRInt32 _MD_sendto(
    956     PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
    957     const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
    958 {
    959     PRInt32 osfd = fd->secret->md.osfd;
    960     PRInt32 rv, err;
    961     PRThread *me = _PR_MD_CURRENT_THREAD();
    962 #ifdef _PR_HAVE_SOCKADDR_LEN
    963     PRNetAddr addrCopy;
    964 
    965     addrCopy = *addr;
    966     ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
    967     ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
    968 
    969     while ((rv = sendto(osfd, buf, amount, flags,
    970             (struct sockaddr *) &addrCopy, addrlen)) == -1) {
    971 #else
    972     while ((rv = sendto(osfd, buf, amount, flags,
    973             (struct sockaddr *) addr, addrlen)) == -1) {
    974 #endif
    975         err = _MD_ERRNO();
    976         if ((err == EAGAIN) || (err == EWOULDBLOCK))    {
    977             if (fd->secret->nonblocking) {
    978                 break;
    979             }
    980             if (!_PR_IS_NATIVE_THREAD(me)) {
    981                                 if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0)
    982                                         goto done;
    983             } else {
    984                 if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
    985                     goto done;
    986             }
    987         } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
    988             continue;
    989         } else {
    990             break;
    991         }
    992     }
    993     if (rv < 0) {
    994         _PR_MD_MAP_SENDTO_ERROR(err);
    995     }
    996 done:
    997     return(rv);
    998 }
    999 
    1000 PRInt32 _MD_writev(
    1001     PRFileDesc *fd, const PRIOVec *iov,
    1002     PRInt32 iov_size, PRIntervalTime timeout)
    1003 {
    1004     PRInt32 rv, err;
    1005     PRThread *me = _PR_MD_CURRENT_THREAD();
    1006     PRInt32 index, amount = 0;
    1007     PRInt32 osfd = fd->secret->md.osfd;
    1008 
    1009     /*
    1010      * Calculate the total number of bytes to be sent; needed for
    1011      * optimization later.
    1012      * We could avoid this if this number was passed in; but it is
    1013      * probably not a big deal because iov_size is usually small (less than
    1014      * 3)
    1015      */
    1016     if (!fd->secret->nonblocking) {
    1017         for (index=0; index<iov_size; index++) {
    1018             amount += iov[index].iov_len;
    1019         }
    1020     }
    1021 
    1022     while ((rv = writev(osfd, (const struct iovec*)iov, iov_size)) == -1) {
    1023         err = _MD_ERRNO();
    1024         if ((err == EAGAIN) || (err == EWOULDBLOCK))    {
    1025             if (fd->secret->nonblocking) {
    1026                 break;
    1027             }
    1028             if (!_PR_IS_NATIVE_THREAD(me)) {
    1029                                 if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0)
    1030                                         goto done;
    1031             } else {
    1032                 if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0)
    1033                     goto done;
    1034             }
    1035         } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
    1036             continue;
    1037         } else {
    1038             break;
    1039         }
    1040     }
    1041     /*
    1042      * optimization; if bytes sent is less than "amount" call
    1043      * select before returning. This is because it is likely that
    1044      * the next writev() call will return EWOULDBLOCK.
    1045      */
    1046     if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
    1047             && (timeout != PR_INTERVAL_NO_WAIT)) {
    1048         if (_PR_IS_NATIVE_THREAD(me)) {
    1049             if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) {
    1050                                 rv = -1;
    1051                 goto done;
    1052                         }
    1053         } else {
    1054                         if (local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout) < 0) {
    1055                                 rv = -1;
    1056                                 goto done;
    1057                         }
    1058         }
    1059     }
    1060     if (rv < 0) {
    1061         _PR_MD_MAP_WRITEV_ERROR(err);
    1062     }
    1063 done:
    1064     return(rv);
    1065 }
    1066 
    1067 PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr,
    1068                             PRUint32 *addrlen, PRIntervalTime timeout)
    1069 {
    1070     PRInt32 osfd = fd->secret->md.osfd;
    1071     PRInt32 rv, err;
    1072     PRThread *me = _PR_MD_CURRENT_THREAD();
    1073 
    1074     while ((rv = accept(osfd, (struct sockaddr *) addr,
    1075                                         (_PRSockLen_t *)addrlen)) == -1) {
    1076         err = _MD_ERRNO();
    1077         if ((err == EAGAIN) || (err == EWOULDBLOCK) || (err == ECONNABORTED)) {
    1078             if (fd->secret->nonblocking) {
    1079                 break;
    1080             }
    1081             if (!_PR_IS_NATIVE_THREAD(me)) {
    1082                                 if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ, timeout)) < 0)
    1083                                         goto done;
    1084             } else {
    1085                 if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
    1086                     goto done;
    1087             }
    1088         } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
    1089             continue;
    1090         } else {
    1091             break;
    1092         }
    1093     }
    1094     if (rv < 0) {
    1095         _PR_MD_MAP_ACCEPT_ERROR(err);
    1096     }
    1097 done:
    1098 #ifdef _PR_HAVE_SOCKADDR_LEN
    1099     if (rv != -1) {
    1100         /* ignore the sa_len field of struct sockaddr */
    1101         if (addr) {
    1102             addr->raw.family = ((struct sockaddr *) addr)->sa_family;
    1103         }
    1104     }
    1105 #endif /* _PR_HAVE_SOCKADDR_LEN */
    1106     return(rv);
    1107 }
    1108 
    1109 extern int _connect (int s, const struct sockaddr *name, int namelen);
    1110 PRInt32 _MD_connect(
    1111     PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
    1112 {
    1113     PRInt32 rv, err;
    1114     PRThread *me = _PR_MD_CURRENT_THREAD();
    1115     PRInt32 osfd = fd->secret->md.osfd;
    1116 #ifdef IRIX
    1117 extern PRInt32 _MD_irix_connect(
    1118         PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, PRIntervalTime timeout);
    1119 #endif
    1120 #ifdef _PR_HAVE_SOCKADDR_LEN
    1121     PRNetAddr addrCopy;
    1122 
    1123     addrCopy = *addr;
    1124     ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
    1125     ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
    1126 #endif
    1127 
    1128     /*
    1129      * We initiate the connection setup by making a nonblocking connect()
    1130      * call.  If the connect() call fails, there are two cases we handle
    1131      * specially:
    1132      * 1. The connect() call was interrupted by a signal.  In this case
    1133      *    we simply retry connect().
    1134      * 2. The NSPR socket is nonblocking and connect() fails with
    1135      *    EINPROGRESS.  We first wait until the socket becomes writable.
    1136      *    Then we try to find out whether the connection setup succeeded
    1137      *    or failed.
    1138      */
    1139 
    1140 retry:
    1141 #ifdef IRIX
    1142     if ((rv = _MD_irix_connect(osfd, addr, addrlen, timeout)) == -1) {
    1143 #else
    1144 #ifdef _PR_HAVE_SOCKADDR_LEN
    1145     if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) {
    1146 #else
    1147     if ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) {
    1148 #endif
    1149 #endif
    1150         err = _MD_ERRNO();
    1151 
    1152         if (err == EINTR) {
    1153             if (_PR_PENDING_INTERRUPT(me)) {
    1154                 me->flags &= ~_PR_INTERRUPT;
    1155                 PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
    1156                 return -1;
    1157             }
    1158             goto retry;
    1159         }
    1160 
    1161         if (!fd->secret->nonblocking && (err == EINPROGRESS)) {
    1162             if (!_PR_IS_NATIVE_THREAD(me)) {
    1163 
    1164                                 if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0)
    1165                     return -1;
    1166             } else {
    1167                 /*
    1168                  * socket_io_wait() may return -1 or 1.
    1169                  */
    1170 
    1171                 rv = socket_io_wait(osfd, WRITE_FD, timeout);
    1172                 if (rv == -1) {
    1173                     return -1;
    1174                 }
    1175             }
    1176 
    1177             PR_ASSERT(rv == 1);
    1178             if (_PR_PENDING_INTERRUPT(me)) {
    1179                 me->flags &= ~_PR_INTERRUPT;
    1180                 PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
    1181                 return -1;
    1182             }
    1183             err = _MD_unix_get_nonblocking_connect_error(osfd);
    1184             if (err != 0) {
    1185                 _PR_MD_MAP_CONNECT_ERROR(err);
    1186                 return -1;
    1187             }
    1188             return 0;
    1189         }
    1190 
    1191         _PR_MD_MAP_CONNECT_ERROR(err);
    1192     }
    1193 
    1194     return rv;
    1195 }  /* _MD_connect */
    1196 
    1197 PRInt32 _MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
    1198 {
    1199     PRInt32 rv, err;
    1200 #ifdef _PR_HAVE_SOCKADDR_LEN
    1201     PRNetAddr addrCopy;
    1202 
    1203     addrCopy = *addr;
    1204     ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
    1205     ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
    1206     rv = bind(fd->secret->md.osfd, (struct sockaddr *) &addrCopy, (int )addrlen);
    1207 #else
    1208     rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen);
    1209 #endif
    1210     if (rv < 0) {
    1211         err = _MD_ERRNO();
    1212         _PR_MD_MAP_BIND_ERROR(err);
    1213     }
    1214     return(rv);
    1215 }
    1216 
    1217 PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog)
    1218 {
    1219     PRInt32 rv, err;
    1220 
    1221     rv = listen(fd->secret->md.osfd, backlog);
    1222     if (rv < 0) {
    1223         err = _MD_ERRNO();
    1224         _PR_MD_MAP_LISTEN_ERROR(err);
    1225     }
    1226     return(rv);
    1227 }
    1228 
    1229 PRInt32 _MD_shutdown(PRFileDesc *fd, PRIntn how)
    1230 {
    1231     PRInt32 rv, err;
    1232 
    1233     rv = shutdown(fd->secret->md.osfd, how);
    1234     if (rv < 0) {
    1235         err = _MD_ERRNO();
    1236         _PR_MD_MAP_SHUTDOWN_ERROR(err);
    1237     }
    1238     return(rv);
    1239 }
    1240 
    1241 PRInt32 _MD_socketpair(int af, int type, int flags,
    1242                                                         PRInt32 *osfd)
    1243 {
    1244     PRInt32 rv, err;
    1245 
    1246     rv = socketpair(af, type, flags, osfd);
    1247     if (rv < 0) {
    1248         err = _MD_ERRNO();
    1249         _PR_MD_MAP_SOCKETPAIR_ERROR(err);
    1250     }
    1251     return rv;
    1252 }
    1253 
    1254 PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr,
    1255                                                 PRUint32 *addrlen)
    1256 {
    1257     PRInt32 rv, err;
    1258 
    1259     rv = getsockname(fd->secret->md.osfd,
    1260             (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
    1261 #ifdef _PR_HAVE_SOCKADDR_LEN
    1262     if (rv == 0) {
    1263         /* ignore the sa_len field of struct sockaddr */
    1264         if (addr) {
    1265             addr->raw.family = ((struct sockaddr *) addr)->sa_family;
    1266         }
    1267     }
    1268 #endif /* _PR_HAVE_SOCKADDR_LEN */
    1269     if (rv < 0) {
    1270         err = _MD_ERRNO();
    1271         _PR_MD_MAP_GETSOCKNAME_ERROR(err);
    1272     }
    1273     return rv==0?PR_SUCCESS:PR_FAILURE;
    1274 }
    1275 
    1276 PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr,
    1277                                         PRUint32 *addrlen)
    1278 {
    1279     PRInt32 rv, err;
    1280 
    1281     rv = getpeername(fd->secret->md.osfd,
    1282             (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
    1283 #ifdef _PR_HAVE_SOCKADDR_LEN
    1284     if (rv == 0) {
    1285         /* ignore the sa_len field of struct sockaddr */
    1286         if (addr) {
    1287             addr->raw.family = ((struct sockaddr *) addr)->sa_family;
    1288         }
    1289     }
    1290 #endif /* _PR_HAVE_SOCKADDR_LEN */
    1291     if (rv < 0) {
    1292         err = _MD_ERRNO();
    1293         _PR_MD_MAP_GETPEERNAME_ERROR(err);
    1294     }
    1295     return rv==0?PR_SUCCESS:PR_FAILURE;
    1296 }
    1297 
    1298 PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level,
    1299                         PRInt32 optname, char* optval, PRInt32* optlen)
    1300 {
    1301     PRInt32 rv, err;
    1302 
    1303     rv = getsockopt(fd->secret->md.osfd, level, optname, optval, (_PRSockLen_t *)optlen);
    1304     if (rv < 0) {
    1305         err = _MD_ERRNO();
    1306         _PR_MD_MAP_GETSOCKOPT_ERROR(err);
    1307     }
    1308     return rv==0?PR_SUCCESS:PR_FAILURE;
    1309 }
    1310 
    1311 PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level,   
    1312                     PRInt32 optname, const char* optval, PRInt32 optlen)
    1313 {
    1314     PRInt32 rv, err;
    1315 
    1316     rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen);
    1317     if (rv < 0) {
    1318         err = _MD_ERRNO();
    1319         _PR_MD_MAP_SETSOCKOPT_ERROR(err);
    1320     }
    1321     return rv==0?PR_SUCCESS:PR_FAILURE;
    1322 }
    1323 
    1324 PRStatus _MD_set_fd_inheritable(PRFileDesc *fd, PRBool inheritable)
    1325 {
    1326     int rv;
    1327 
    1328     rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC);
    1329     if (-1 == rv) {
    1330         PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
    1331         return PR_FAILURE;
    1332     }
    1333     return PR_SUCCESS;
    1334 }
    1335 
    1336 void _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported)
    1337 {
    1338     if (imported) {
    1339         fd->secret->inheritable = _PR_TRI_UNKNOWN;
    1340     } else {
    1341         /* By default, a Unix fd is not closed on exec. */
    1342 #ifdef DEBUG
    1343         {
    1344             int flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
    1345             PR_ASSERT(0 == flags);
    1346         }
    1347 #endif
    1348         fd->secret->inheritable = _PR_TRI_TRUE;
    1349     }
    1350 }
    1351 
    1352 /************************************************************************/
    1353 #if !defined(_PR_USE_POLL)
    1354 
    1355 /*
    1356 ** Scan through io queue and find any bad fd's that triggered the error
    1357 ** from _MD_SELECT
    1358 */
    1359 static void FindBadFDs(void)
    1360 {
    1361     PRCList *q;
    1362     PRThread *me = _MD_CURRENT_THREAD();
    1363 
    1364     PR_ASSERT(!_PR_IS_NATIVE_THREAD(me));
    1365     q = (_PR_IOQ(me->cpu)).next;
    1366     _PR_IOQ_MAX_OSFD(me->cpu) = -1;
    1367     _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT;
    1368     while (q != &_PR_IOQ(me->cpu)) {
    1369         PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
    1370         PRBool notify = PR_FALSE;
    1371         _PRUnixPollDesc *pds = pq->pds;
    1372         _PRUnixPollDesc *epds = pds + pq->npds;
    1373         PRInt32 pq_max_osfd = -1;
    1374 
    1375         q = q->next;
    1376         for (; pds < epds; pds++) {
    1377             PRInt32 osfd = pds->osfd;
    1378             pds->out_flags = 0;
    1379             PR_ASSERT(osfd >= 0 || pds->in_flags == 0);
    1380             if (pds->in_flags == 0) {
    1381                 continue;  /* skip this fd */
    1382             }
    1383             if (fcntl(osfd, F_GETFL, 0) == -1) {
    1384                 /* Found a bad descriptor, remove it from the fd_sets. */
    1385                 PR_LOG(_pr_io_lm, PR_LOG_MAX,
    1386                     ("file descriptor %d is bad", osfd));
    1387                 pds->out_flags = _PR_UNIX_POLL_NVAL;
    1388                 notify = PR_TRUE;
    1389             }
    1390             if (osfd > pq_max_osfd) {
    1391                 pq_max_osfd = osfd;
    1392             }
    1393         }
    1394 
    1395         if (notify) {
    1396             PRIntn pri;
    1397             PR_REMOVE_LINK(&pq->links);
    1398             pq->on_ioq = PR_FALSE;
    1399 
    1400             /*
    1401          * Decrement the count of descriptors for each desciptor/event
    1402          * because this I/O request is being removed from the
    1403          * ioq
    1404          */
    1405             pds = pq->pds;
    1406             for (; pds < epds; pds++) {
    1407                 PRInt32 osfd = pds->osfd;
    1408                 PRInt16 in_flags = pds->in_flags;
    1409                 PR_ASSERT(osfd >= 0 || in_flags == 0);
    1410                 if (in_flags & _PR_UNIX_POLL_READ) {
    1411                     if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
    1412                         FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
    1413                 }
    1414                 if (in_flags & _PR_UNIX_POLL_WRITE) {
    1415                     if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0)
    1416                         FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
    1417                 }
    1418                 if (in_flags & _PR_UNIX_POLL_EXCEPT) {
    1419                     if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
    1420                         FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
    1421                 }
    1422             }
    1423 
    1424             _PR_THREAD_LOCK(pq->thr);
    1425             if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
    1426                 _PRCPU *cpu = pq->thr->cpu;
    1427                 _PR_SLEEPQ_LOCK(pq->thr->cpu);
    1428                 _PR_DEL_SLEEPQ(pq->thr, PR_TRUE);
    1429                 _PR_SLEEPQ_UNLOCK(pq->thr->cpu);
    1430 
    1431                                 if (pq->thr->flags & _PR_SUSPENDING) {
    1432                                     /*
    1433                                      * set thread state to SUSPENDED;
    1434                                      * a Resume operation on the thread
    1435                                      * will move it to the runQ
    1436                                      */
    1437                                     pq->thr->state = _PR_SUSPENDED;
    1438                                     _PR_MISCQ_LOCK(pq->thr->cpu);
    1439                                     _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu);
    1440                                     _PR_MISCQ_UNLOCK(pq->thr->cpu);
    1441                                 } else {
    1442                                     pri = pq->thr->priority;
    1443                                     pq->thr->state = _PR_RUNNABLE;
    1444 
    1445                                     _PR_RUNQ_LOCK(cpu);
    1446                                     _PR_ADD_RUNQ(pq->thr, cpu, pri);
    1447                                     _PR_RUNQ_UNLOCK(cpu);
    1448                                 }
    1449             }
    1450             _PR_THREAD_UNLOCK(pq->thr);
    1451         } else {
    1452             if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu))
    1453                 _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout;
    1454             if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd)
    1455                 _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd;
    1456         }
    1457     }
    1458     if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
    1459         if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0])
    1460             _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
    1461     }
    1462 }
    1463 #endif  /* !defined(_PR_USE_POLL) */
    1464 
    1465 /************************************************************************/
    1466 
    1467 /*
    1468 ** Called by the scheduler when there is nothing to do. This means that
    1469 ** all threads are blocked on some monitor somewhere.
    1470 **
    1471 ** Note: this code doesn't release the scheduler lock.
    1472 */
    1473 /*
    1474 ** Pause the current CPU. longjmp to the cpu's pause stack
    1475 **
    1476 ** This must be called with the scheduler locked
    1477 */
    1478 void _MD_PauseCPU(PRIntervalTime ticks)
    1479 {
    1480     PRThread *me = _MD_CURRENT_THREAD();
    1481 #ifdef _PR_USE_POLL
    1482     int timeout;
    1483     struct pollfd *pollfds;    /* an array of pollfd structures */
    1484     struct pollfd *pollfdPtr;    /* a pointer that steps through the array */
    1485     unsigned long npollfds;     /* number of pollfd structures in array */
    1486     unsigned long pollfds_size;
    1487     int nfd;                    /* to hold the return value of poll() */
    1488 #else
    1489     struct timeval timeout, *tvp;
    1490     fd_set r, w, e;
    1491     fd_set *rp, *wp, *ep;
    1492     PRInt32 max_osfd, nfd;
    1493 #endif  /* _PR_USE_POLL */
    1494     PRInt32 rv;
    1495     PRCList *q;
    1496     PRUint32 min_timeout;
    1497     sigset_t oldset;
    1498 #ifdef IRIX
    1499 extern sigset_t ints_off;
    1500 #endif
    1501 
    1502     PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
    1503 
    1504     _PR_MD_IOQ_LOCK();
    1505 
    1506 #ifdef _PR_USE_POLL
    1507     /* Build up the pollfd structure array to wait on */
    1508 
    1509     /* Find out how many pollfd structures are needed */
    1510     npollfds = _PR_IOQ_OSFD_CNT(me->cpu);
    1511     PR_ASSERT(npollfds >= 0);
    1512 
    1513     /*
    1514      * We use a pipe to wake up a native thread.  An fd is needed
    1515      * for the pipe and we poll it for reading.
    1516      */
    1517     if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
    1518         npollfds++;
    1519 #ifdef  IRIX
    1520                 /*
    1521                  * On Irix, a second pipe is used to cause the primordial cpu to
    1522                  * wakeup and exit, when the process is exiting because of a call
    1523                  * to exit/PR_ProcessExit.
    1524                  */
    1525                 if (me->cpu->id == 0) {
    1526                 npollfds++;
    1527                 }
    1528 #endif
    1529         }
    1530 
    1531     /*
    1532      * if the cpu's pollfd array is not big enough, release it and allocate a new one
    1533      */
    1534     if (npollfds > _PR_IOQ_POLLFDS_SIZE(me->cpu)) {
    1535         if (_PR_IOQ_POLLFDS(me->cpu) != NULL)
    1536             PR_DELETE(_PR_IOQ_POLLFDS(me->cpu));
    1537         pollfds_size =  PR_MAX(_PR_IOQ_MIN_POLLFDS_SIZE(me->cpu), npollfds);
    1538         pollfds = (struct pollfd *) PR_MALLOC(pollfds_size * sizeof(struct pollfd));
    1539         _PR_IOQ_POLLFDS(me->cpu) = pollfds;
    1540         _PR_IOQ_POLLFDS_SIZE(me->cpu) = pollfds_size;
    1541     } else {
    1542         pollfds = _PR_IOQ_POLLFDS(me->cpu);
    1543     }
    1544     pollfdPtr = pollfds;
    1545 
    1546     /*
    1547      * If we need to poll the pipe for waking up a native thread,
    1548      * the pipe's fd is the first element in the pollfds array.
    1549      */
    1550     if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
    1551         pollfdPtr->fd = _pr_md_pipefd[0];
    1552         pollfdPtr->events = POLLIN;
    1553         pollfdPtr++;
    1554 #ifdef  IRIX
    1555                 /*
    1556                  * On Irix, the second element is the exit pipe
    1557                  */
    1558                 if (me->cpu->id == 0) {
    1559                         pollfdPtr->fd = _pr_irix_primoridal_cpu_fd[0];
    1560                         pollfdPtr->events = POLLIN;
    1561                         pollfdPtr++;
    1562                 }
    1563 #endif
    1564     }
    1565 
    1566     min_timeout = PR_INTERVAL_NO_TIMEOUT;
    1567     for (q = _PR_IOQ(me->cpu).next; q != &_PR_IOQ(me->cpu); q = q->next) {
    1568         PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
    1569         _PRUnixPollDesc *pds = pq->pds;
    1570         _PRUnixPollDesc *epds = pds + pq->npds;
    1571 
    1572         if (pq->timeout < min_timeout) {
    1573             min_timeout = pq->timeout;
    1574         }
    1575         for (; pds < epds; pds++, pollfdPtr++) {
    1576             /*
    1577          * Assert that the pollfdPtr pointer does not go
    1578          * beyond the end of the pollfds array
    1579          */
    1580             PR_ASSERT(pollfdPtr < pollfds + npollfds);
    1581             pollfdPtr->fd = pds->osfd;
    1582             /* direct copy of poll flags */
    1583             pollfdPtr->events = pds->in_flags;
    1584         }
    1585     }
    1586     _PR_IOQ_TIMEOUT(me->cpu) = min_timeout;
    1587 #else
    1588     /*
    1589      * assigment of fd_sets
    1590      */
    1591     r = _PR_FD_READ_SET(me->cpu);
    1592     w = _PR_FD_WRITE_SET(me->cpu);
    1593     e = _PR_FD_EXCEPTION_SET(me->cpu);
    1594 
    1595     rp = &r;
    1596     wp = &w;
    1597     ep = &e;
    1598 
    1599     max_osfd = _PR_IOQ_MAX_OSFD(me->cpu) + 1;
    1600     min_timeout = _PR_IOQ_TIMEOUT(me->cpu);
    1601 #endif  /* _PR_USE_POLL */
    1602     /*
    1603     ** Compute the minimum timeout value: make it the smaller of the
    1604     ** timeouts specified by the i/o pollers or the timeout of the first
    1605     ** sleeping thread.
    1606     */
    1607     q = _PR_SLEEPQ(me->cpu).next;
    1608 
    1609     if (q != &_PR_SLEEPQ(me->cpu)) {
    1610         PRThread *t = _PR_THREAD_PTR(q);
    1611 
    1612         if (t->sleep < min_timeout) {
    1613             min_timeout = t->sleep;
    1614         }
    1615     }
    1616     if (min_timeout > ticks) {
    1617         min_timeout = ticks;
    1618     }
    1619 
    1620 #ifdef _PR_USE_POLL
    1621     if (min_timeout == PR_INTERVAL_NO_TIMEOUT)
    1622         timeout = -1;
    1623     else
    1624         timeout = PR_IntervalToMilliseconds(min_timeout);
    1625 #else
    1626     if (min_timeout == PR_INTERVAL_NO_TIMEOUT) {
    1627         tvp = NULL;
    1628     } else {
    1629         timeout.tv_sec = PR_IntervalToSeconds(min_timeout);
    1630         timeout.tv_usec = PR_IntervalToMicroseconds(min_timeout)
    1631             % PR_USEC_PER_SEC;
    1632         tvp = &timeout;
    1633     }
    1634 #endif  /* _PR_USE_POLL */
    1635 
    1636     _PR_MD_IOQ_UNLOCK();
    1637     _MD_CHECK_FOR_EXIT();
    1638     /*
    1639      * check for i/o operations
    1640      */
    1641 #ifndef _PR_NO_CLOCK_TIMER
    1642     /*
    1643      * Disable the clock interrupts while we are in select, if clock interrupts
    1644      * are enabled. Otherwise, when the select/poll calls are interrupted, the
    1645      * timer value starts ticking from zero again when the system call is restarted.
    1646      */
    1647 #ifdef IRIX
    1648     /*
    1649      * SIGCHLD signal is used on Irix to detect he termination of an
    1650      * sproc by SIGSEGV, SIGBUS or SIGABRT signals when
    1651      * _nspr_terminate_on_error is set.
    1652      */
    1653     if ((!_nspr_noclock) || (_nspr_terminate_on_error))
    1654 #else
    1655         if (!_nspr_noclock)
    1656 #endif    /* IRIX */
    1657 #ifdef IRIX
    1658     sigprocmask(SIG_BLOCK, &ints_off, &oldset);
    1659 #else
    1660     PR_ASSERT(sigismember(&timer_set, SIGALRM));
    1661     sigprocmask(SIG_BLOCK, &timer_set, &oldset);
    1662 #endif    /* IRIX */
    1663 #endif  /* !_PR_NO_CLOCK_TIMER */
    1664 
    1665 #ifndef _PR_USE_POLL
    1666     PR_ASSERT(FD_ISSET(_pr_md_pipefd[0],rp));
    1667     nfd = _MD_SELECT(max_osfd, rp, wp, ep, tvp);
    1668 #else
    1669     nfd = _MD_POLL(pollfds, npollfds, timeout);
    1670 #endif  /* !_PR_USE_POLL */
    1671 
    1672 #ifndef _PR_NO_CLOCK_TIMER
    1673 #ifdef IRIX
    1674     if ((!_nspr_noclock) || (_nspr_terminate_on_error))
    1675 #else
    1676         if (!_nspr_noclock)
    1677 #endif    /* IRIX */
    1678     sigprocmask(SIG_SETMASK, &oldset, 0);
    1679 #endif  /* !_PR_NO_CLOCK_TIMER */
    1680 
    1681     _MD_CHECK_FOR_EXIT();
    1682 
    1683 #ifdef IRIX
    1684         _PR_MD_primordial_cpu();
    1685 #endif
    1686 
    1687     _PR_MD_IOQ_LOCK();
    1688     /*
    1689     ** Notify monitors that are associated with the selected descriptors.
    1690     */
    1691 #ifdef _PR_USE_POLL
    1692     if (nfd > 0) {
    1693         pollfdPtr = pollfds;
    1694         if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
    1695             /*
    1696                          * Assert that the pipe is the first element in the
    1697                          * pollfds array.
    1698                          */
    1699             PR_ASSERT(pollfds[0].fd == _pr_md_pipefd[0]);
    1700             if ((pollfds[0].revents & POLLIN) && (nfd == 1)) {
    1701                 /*
    1702                                  * woken up by another thread; read all the data
    1703                                  * in the pipe to empty the pipe
    1704                                  */
    1705                 while ((rv = read(_pr_md_pipefd[0], _pr_md_pipebuf,
    1706                     PIPE_BUF)) == PIPE_BUF){
    1707                 }
    1708                 PR_ASSERT((rv > 0) || ((rv == -1) && (errno == EAGAIN)));
    1709             }
    1710             pollfdPtr++;
    1711 #ifdef  IRIX
    1712                         /*
    1713                          * On Irix, check to see if the primordial cpu needs to exit
    1714                          * to cause the process to terminate
    1715                          */
    1716                         if (me->cpu->id == 0) {
    1717                 PR_ASSERT(pollfds[1].fd == _pr_irix_primoridal_cpu_fd[0]);
    1718                                 if (pollfdPtr->revents & POLLIN) {
    1719                                         if (_pr_irix_process_exit) {
    1720                                                 /*
    1721                                                  * process exit due to a call to PR_ProcessExit
    1722                                                  */
    1723                                                 prctl(PR_SETEXITSIG, SIGKILL);
    1724                                                 _exit(_pr_irix_process_exit_code);
    1725                                         } else {
    1726                                                 while ((rv = read(_pr_irix_primoridal_cpu_fd[0],
    1727                                                         _pr_md_pipebuf, PIPE_BUF)) == PIPE_BUF) {
    1728                                                 }
    1729                                                 PR_ASSERT(rv > 0);
    1730                                         }
    1731                                 }
    1732                                 pollfdPtr++;
    1733                         }
    1734 #endif
    1735         }
    1736         for (q = _PR_IOQ(me->cpu).next; q != &_PR_IOQ(me->cpu); q = q->next) {
    1737             PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
    1738             PRBool notify = PR_FALSE;
    1739             _PRUnixPollDesc *pds = pq->pds;
    1740             _PRUnixPollDesc *epds = pds + pq->npds;
    1741 
    1742             for (; pds < epds; pds++, pollfdPtr++) {
    1743                 /*
    1744                   * Assert that the pollfdPtr pointer does not go beyond
    1745                   * the end of the pollfds array.
    1746                   */
    1747                 PR_ASSERT(pollfdPtr < pollfds + npollfds);
    1748                 /*
    1749                  * Assert that the fd's in the pollfds array (stepped
    1750                  * through by pollfdPtr) are in the same order as
    1751                  * the fd's in _PR_IOQ() (stepped through by q and pds).
    1752                  * This is how the pollfds array was created earlier.
    1753                  */
    1754                 PR_ASSERT(pollfdPtr->fd == pds->osfd);
    1755                 pds->out_flags = pollfdPtr->revents;
    1756                 /* Negative fd's are ignored by poll() */
    1757                 if (pds->osfd >= 0 && pds->out_flags) {
    1758                     notify = PR_TRUE;
    1759                 }
    1760             }
    1761             if (notify) {
    1762                 PRIntn pri;
    1763                 PRThread *thred;
    1764 
    1765                 PR_REMOVE_LINK(&pq->links);
    1766                 pq->on_ioq = PR_FALSE;
    1767 
    1768                 thred = pq->thr;
    1769                 _PR_THREAD_LOCK(thred);
    1770                 if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
    1771                     _PRCPU *cpu = pq->thr->cpu;
    1772                     _PR_SLEEPQ_LOCK(pq->thr->cpu);
    1773                     _PR_DEL_SLEEPQ(pq->thr, PR_TRUE);
    1774                     _PR_SLEEPQ_UNLOCK(pq->thr->cpu);
    1775 
    1776                                         if (pq->thr->flags & _PR_SUSPENDING) {
    1777                                             /*
    1778                                              * set thread state to SUSPENDED;
    1779                                              * a Resume operation on the thread
    1780                                              * will move it to the runQ
    1781                                              */
    1782                                             pq->thr->state = _PR_SUSPENDED;
    1783                                             _PR_MISCQ_LOCK(pq->thr->cpu);
    1784                                             _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu);
    1785                                             _PR_MISCQ_UNLOCK(pq->thr->cpu);
    1786                                         } else {
    1787                                                 pri = pq->thr->priority;
    1788                                                 pq->thr->state = _PR_RUNNABLE;
    1789 
    1790                                                 _PR_RUNQ_LOCK(cpu);
    1791                                                 _PR_ADD_RUNQ(pq->thr, cpu, pri);
    1792                                                 _PR_RUNQ_UNLOCK(cpu);
    1793                                                 if (_pr_md_idle_cpus > 1)
    1794                                                         _PR_MD_WAKEUP_WAITER(thred);
    1795                                         }
    1796                 }
    1797                 _PR_THREAD_UNLOCK(thred);
    1798                 _PR_IOQ_OSFD_CNT(me->cpu) -= pq->npds;
    1799                 PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0);
    1800             }
    1801         }
    1802     } else if (nfd == -1) {
    1803         PR_LOG(_pr_io_lm, PR_LOG_MAX, ("poll() failed with errno %d", errno));
    1804     }
    1805 
    1806 #else
    1807     if (nfd > 0) {
    1808         q = _PR_IOQ(me->cpu).next;
    1809         _PR_IOQ_MAX_OSFD(me->cpu) = -1;
    1810         _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT;
    1811         while (q != &_PR_IOQ(me->cpu)) {
    1812             PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
    1813             PRBool notify = PR_FALSE;
    1814             _PRUnixPollDesc *pds = pq->pds;
    1815             _PRUnixPollDesc *epds = pds + pq->npds;
    1816             PRInt32 pq_max_osfd = -1;
    1817 
    1818             q = q->next;
    1819             for (; pds < epds; pds++) {
    1820                 PRInt32 osfd = pds->osfd;
    1821                 PRInt16 in_flags = pds->in_flags;
    1822                 PRInt16 out_flags = 0;
    1823                 PR_ASSERT(osfd >= 0 || in_flags == 0);
    1824                 if ((in_flags & _PR_UNIX_POLL_READ) && FD_ISSET(osfd, rp)) {
    1825                     out_flags |= _PR_UNIX_POLL_READ;
    1826                 }
    1827                 if ((in_flags & _PR_UNIX_POLL_WRITE) && FD_ISSET(osfd, wp)) {
    1828                     out_flags |= _PR_UNIX_POLL_WRITE;
    1829                 }
    1830                 if ((in_flags & _PR_UNIX_POLL_EXCEPT) && FD_ISSET(osfd, ep)) {
    1831                     out_flags |= _PR_UNIX_POLL_EXCEPT;
    1832                 }
    1833                 pds->out_flags = out_flags;
    1834                 if (out_flags) {
    1835                     notify = PR_TRUE;
    1836                 }
    1837                 if (osfd > pq_max_osfd) {
    1838                     pq_max_osfd = osfd;
    1839                 }
    1840             }
    1841             if (notify == PR_TRUE) {
    1842                 PRIntn pri;
    1843                 PRThread *thred;
    1844 
    1845                 PR_REMOVE_LINK(&pq->links);
    1846                 pq->on_ioq = PR_FALSE;
    1847 
    1848                 /*
    1849                  * Decrement the count of descriptors for each desciptor/event
    1850                  * because this I/O request is being removed from the
    1851                  * ioq
    1852                  */
    1853                 pds = pq->pds;
    1854                 for (; pds < epds; pds++) {
    1855                     PRInt32 osfd = pds->osfd;
    1856                     PRInt16 in_flags = pds->in_flags;
    1857                     PR_ASSERT(osfd >= 0 || in_flags == 0);
    1858                     if (in_flags & _PR_UNIX_POLL_READ) {
    1859                         if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
    1860                             FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
    1861                     }
    1862                     if (in_flags & _PR_UNIX_POLL_WRITE) {
    1863                         if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0)
    1864                             FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
    1865                     }
    1866                     if (in_flags & _PR_UNIX_POLL_EXCEPT) {
    1867                         if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
    1868                             FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
    1869                     }
    1870                 }
    1871 
    1872                 /*
    1873                  * Because this thread can run on a different cpu right
    1874                  * after being added to the run queue, do not dereference
    1875                  * pq
    1876                  */
    1877                  thred = pq->thr;
    1878                 _PR_THREAD_LOCK(thred);
    1879                 if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
    1880                     _PRCPU *cpu = thred->cpu;
    1881                     _PR_SLEEPQ_LOCK(pq->thr->cpu);
    1882                     _PR_DEL_SLEEPQ(pq->thr, PR_TRUE);
    1883                     _PR_SLEEPQ_UNLOCK(pq->thr->cpu);
    1884 
    1885                                         if (pq->thr->flags & _PR_SUSPENDING) {
    1886                                             /*
    1887                                              * set thread state to SUSPENDED;
    1888                                              * a Resume operation on the thread
    1889                                              * will move it to the runQ
    1890                                              */
    1891                                             pq->thr->state = _PR_SUSPENDED;
    1892                                             _PR_MISCQ_LOCK(pq->thr->cpu);
    1893                                             _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu);
    1894                                             _PR_MISCQ_UNLOCK(pq->thr->cpu);
    1895                                         } else {
    1896                                                 pri = pq->thr->priority;
    1897                                                 pq->thr->state = _PR_RUNNABLE;
    1898 
    1899                                                 pq->thr->cpu = cpu;
    1900                                                 _PR_RUNQ_LOCK(cpu);
    1901                                                 _PR_ADD_RUNQ(pq->thr, cpu, pri);
    1902                                                 _PR_RUNQ_UNLOCK(cpu);
    1903                                                 if (_pr_md_idle_cpus > 1)
    1904                                                         _PR_MD_WAKEUP_WAITER(thred);
    1905                                         }
    1906                 }
    1907                 _PR_THREAD_UNLOCK(thred);
    1908             } else {
    1909                 if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu))
    1910                     _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout;
    1911                 if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd)
    1912                     _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd;
    1913             }
    1914         }
    1915         if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
    1916             if ((FD_ISSET(_pr_md_pipefd[0], rp)) && (nfd == 1)) {
    1917                 /*
    1918              * woken up by another thread; read all the data
    1919              * in the pipe to empty the pipe
    1920              */
    1921                 while ((rv =
    1922                     read(_pr_md_pipefd[0], _pr_md_pipebuf, PIPE_BUF))
    1923                     == PIPE_BUF){
    1924                 }
    1925                 PR_ASSERT((rv > 0) ||
    1926                     ((rv == -1) && (errno == EAGAIN)));
    1927             }
    1928             if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0])
    1929                 _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
    1930 #ifdef  IRIX
    1931                         if ((me->cpu->id == 0) &&
    1932                                                 (FD_ISSET(_pr_irix_primoridal_cpu_fd[0], rp))) {
    1933                                 if (_pr_irix_process_exit) {
    1934                                         /*
    1935                                          * process exit due to a call to PR_ProcessExit
    1936                                          */
    1937                                         prctl(PR_SETEXITSIG, SIGKILL);
    1938                                         _exit(_pr_irix_process_exit_code);
    1939                                 } else {
    1940                                                 while ((rv = read(_pr_irix_primoridal_cpu_fd[0],
    1941                                                         _pr_md_pipebuf, PIPE_BUF)) == PIPE_BUF) {
    1942                                                 }
    1943                                                 PR_ASSERT(rv > 0);
    1944                                 }
    1945                         }
    1946                         if (me->cpu->id == 0) {
    1947                                 if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_irix_primoridal_cpu_fd[0])
    1948                                         _PR_IOQ_MAX_OSFD(me->cpu) = _pr_irix_primoridal_cpu_fd[0];
    1949                         }
    1950 #endif
    1951         }
    1952     } else if (nfd < 0) {
    1953         if (errno == EBADF) {
    1954             FindBadFDs();
    1955         } else {
    1956             PR_LOG(_pr_io_lm, PR_LOG_MAX, ("select() failed with errno %d",
    1957                 errno));
    1958         }
    1959     } else {
    1960         PR_ASSERT(nfd == 0);
    1961         /*
    1962          * compute the new value of _PR_IOQ_TIMEOUT
    1963          */
    1964         q = _PR_IOQ(me->cpu).next;
    1965         _PR_IOQ_MAX_OSFD(me->cpu) = -1;
    1966         _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT;
    1967         while (q != &_PR_IOQ(me->cpu)) {
    1968             PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
    1969             _PRUnixPollDesc *pds = pq->pds;
    1970             _PRUnixPollDesc *epds = pds + pq->npds;
    1971             PRInt32 pq_max_osfd = -1;
    1972 
    1973             q = q->next;
    1974             for (; pds < epds; pds++) {
    1975                 if (pds->osfd > pq_max_osfd) {
    1976                     pq_max_osfd = pds->osfd;
    1977                 }
    1978             }
    1979             if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu))
    1980                 _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout;
    1981             if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd)
    1982                 _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd;
    1983         }
    1984         if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
    1985             if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0])
    1986                 _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
    1987         }
    1988     }
    1989 #endif  /* _PR_USE_POLL */
    1990     _PR_MD_IOQ_UNLOCK();
    1991 }
    1992 
    1993 void _MD_Wakeup_CPUs()
    1994 {
    1995     PRInt32 rv, data;
    1996 
    1997     data = 0;
    1998     rv = write(_pr_md_pipefd[1], &data, 1);
    1999 
    2000     while ((rv < 0) && (errno == EAGAIN)) {
    2001         /*
    2002          * pipe full, read all data in pipe to empty it
    2003          */
    2004         while ((rv =
    2005             read(_pr_md_pipefd[0], _pr_md_pipebuf, PIPE_BUF))
    2006             == PIPE_BUF) {
    2007         }
    2008         PR_ASSERT((rv > 0) ||
    2009             ((rv == -1) && (errno == EAGAIN)));
    2010         rv = write(_pr_md_pipefd[1], &data, 1);
    2011     }
    2012 }
    2013 
    2014 
    2015 void _MD_InitCPUS()
    2016 {
    2017     PRInt32 rv, flags;
    2018     PRThread *me = _MD_CURRENT_THREAD();
    2019 
    2020     rv = pipe(_pr_md_pipefd);
    2021     PR_ASSERT(rv == 0);
    2022     _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
    2023 #ifndef _PR_USE_POLL
    2024     FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(me->cpu));
    2025 #endif
    2026 
    2027     flags = fcntl(_pr_md_pipefd[0], F_GETFL, 0);
    2028     fcntl(_pr_md_pipefd[0], F_SETFL, flags | O_NONBLOCK);
    2029     flags = fcntl(_pr_md_pipefd[1], F_GETFL, 0);
    2030     fcntl(_pr_md_pipefd[1], F_SETFL, flags | O_NONBLOCK);
    2031 }
    2032 
    2033 /*
    2034 ** Unix SIGALRM (clock) signal handler
    2035 */
    2036 static void ClockInterruptHandler()
    2037 {
    2038     int olderrno;
    2039     PRUintn pri;
    2040     _PRCPU *cpu = _PR_MD_CURRENT_CPU();
    2041     PRThread *me = _MD_CURRENT_THREAD();
    2042 
    2043 #ifdef SOLARIS
    2044     if (!me || _PR_IS_NATIVE_THREAD(me)) {
    2045         _pr_primordialCPU->u.missed[_pr_primordialCPU->where] |= _PR_MISSED_CLOCK;
    2046         return;
    2047     }
    2048 #endif
    2049 
    2050     if (_PR_MD_GET_INTSOFF() != 0) {
    2051         cpu->u.missed[cpu->where] |= _PR_MISSED_CLOCK;
    2052         return;
    2053     }
    2054     _PR_MD_SET_INTSOFF(1);
    2055 
    2056     olderrno = errno;
    2057     _PR_ClockInterrupt();
    2058     errno = olderrno;
    2059 
    2060     /*
    2061     ** If the interrupt wants a resched or if some other thread at
    2062     ** the same priority needs the cpu, reschedule.
    2063     */
    2064     pri = me->priority;
    2065     if ((cpu->u.missed[3] || (_PR_RUNQREADYMASK(me->cpu) >> pri))) {
    2066 #ifdef _PR_NO_PREEMPT
    2067         cpu->resched = PR_TRUE;
    2068         if (pr_interruptSwitchHook) {
    2069             (*pr_interruptSwitchHook)(pr_interruptSwitchHookArg);
    2070         }
    2071 #else /* _PR_NO_PREEMPT */
    2072         /*
    2073     ** Re-enable unix interrupts (so that we can use
    2074     ** setjmp/longjmp for context switching without having to
    2075     ** worry about the signal state)
    2076     */
    2077         sigprocmask(SIG_SETMASK, &empty_set, 0);
    2078         PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("clock caused context switch"));
    2079 
    2080         if(!(me->flags & _PR_IDLE_THREAD)) {
    2081             _PR_THREAD_LOCK(me);
    2082             me->state = _PR_RUNNABLE;
    2083             me->cpu = cpu;
    2084             _PR_RUNQ_LOCK(cpu);
    2085             _PR_ADD_RUNQ(me, cpu, pri);
    2086             _PR_RUNQ_UNLOCK(cpu);
    2087             _PR_THREAD_UNLOCK(me);
    2088         } else
    2089             me->state = _PR_RUNNABLE;
    2090         _MD_SWITCH_CONTEXT(me);
    2091         PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("clock back from context switch"));
    2092 #endif /* _PR_NO_PREEMPT */
    2093     }
    2094     /*
    2095      * Because this thread could be running on a different cpu after
    2096      * a context switch the current cpu should be accessed and the
    2097      * value of the 'cpu' variable should not be used.
    2098      */
    2099     _PR_MD_SET_INTSOFF(0);
    2100 }
    2101 
    2102 /*
    2103  * On HP-UX 9, we have to use the sigvector() interface to restart
    2104  * interrupted system calls, because sigaction() does not have the
    2105  * SA_RESTART flag.
    2106  */
    2107 
    2108 #ifdef HPUX9
    2109 static void HPUX9_ClockInterruptHandler(
    2110     int sig,
    2111     int code,
    2112     struct sigcontext *scp)
    2113 {
    2114     ClockInterruptHandler();
    2115     scp->sc_syscall_action = SIG_RESTART;
    2116 }
    2117 #endif /* HPUX9 */
    2118 
    2119 /* # of milliseconds per clock tick that we will use */
    2120 #define MSEC_PER_TICK    50
    2121 
    2122 
    2123 void _MD_StartInterrupts()
    2124 {
    2125     char *eval;
    2126 
    2127     if ((eval = getenv("NSPR_NOCLOCK")) != NULL) {
    2128         if (atoi(eval) == 0)
    2129             _nspr_noclock = 0;
    2130         else
    2131             _nspr_noclock = 1;
    2132     }
    2133 
    2134 #ifndef _PR_NO_CLOCK_TIMER
    2135     if (!_nspr_noclock) {
    2136         _MD_EnableClockInterrupts();
    2137     }
    2138 #endif
    2139 }
    2140 
    2141 void _MD_StopInterrupts()
    2142 {
    2143     sigprocmask(SIG_BLOCK, &timer_set, 0);
    2144 }
    2145 
    2146 void _MD_EnableClockInterrupts()
    2147 {
    2148     struct itimerval itval;
    2149     extern PRUintn _pr_numCPU;
    2150 #ifdef HPUX9
    2151     struct sigvec vec;
    2152 
    2153     vec.sv_handler = (void (*)()) HPUX9_ClockInterruptHandler;
    2154     vec.sv_mask = 0;
    2155     vec.sv_flags = 0;
    2156     sigvector(SIGALRM, &vec, 0);
    2157 #else
    2158     struct sigaction vtact;
    2159 
    2160     vtact.sa_handler = (void (*)()) ClockInterruptHandler;
    2161     sigemptyset(&vtact.sa_mask);
    2162     vtact.sa_flags = SA_RESTART;
    2163     sigaction(SIGALRM, &vtact, 0);
    2164 #endif /* HPUX9 */
    2165 
    2166     PR_ASSERT(_pr_numCPU == 1);
    2167         itval.it_interval.tv_sec = 0;
    2168         itval.it_interval.tv_usec = MSEC_PER_TICK * PR_USEC_PER_MSEC;
    2169         itval.it_value = itval.it_interval;
    2170         setitimer(ITIMER_REAL, &itval, 0);
    2171 }
    2172 
    2173 void _MD_DisableClockInterrupts()
    2174 {
    2175     struct itimerval itval;
    2176     extern PRUintn _pr_numCPU;
    2177 
    2178     PR_ASSERT(_pr_numCPU == 1);
    2179         itval.it_interval.tv_sec = 0;
    2180         itval.it_interval.tv_usec = 0;
    2181         itval.it_value = itval.it_interval;
    2182         setitimer(ITIMER_REAL, &itval, 0);
    2183 }
    2184 
    2185 void _MD_BlockClockInterrupts()
    2186 {
    2187     sigprocmask(SIG_BLOCK, &timer_set, 0);
    2188 }
    2189 
    2190 void _MD_UnblockClockInterrupts()
    2191 {
    2192     sigprocmask(SIG_UNBLOCK, &timer_set, 0);
    2193 }
    2194 
    2195 void _MD_MakeNonblock(PRFileDesc *fd)
    2196 {
    2197     PRInt32 osfd = fd->secret->md.osfd;
    2198     int flags;
    2199 
    2200     if (osfd <= 2) {
    2201         /* Don't mess around with stdin, stdout or stderr */
    2202         return;
    2203     }
    2204     flags = fcntl(osfd, F_GETFL, 0);
    2205 
    2206     /*
    2207      * Use O_NONBLOCK (POSIX-style non-blocking I/O) whenever possible.
    2208      * On SunOS 4, we must use FNDELAY (BSD-style non-blocking I/O),
    2209      * otherwise connect() still blocks and can be interrupted by SIGALRM.
    2210      */
    2211 
    2212 #ifdef SUNOS4
    2213     fcntl(osfd, F_SETFL, flags | FNDELAY);
    2214 #else
    2215     fcntl(osfd, F_SETFL, flags | O_NONBLOCK);
    2216 #endif
    2217     }
    2218 
    2219 PRInt32 _MD_open(const char *name, PRIntn flags, PRIntn mode)
    2220 {
    2221     PRInt32 osflags;
    2222     PRInt32 rv, err;
    2223 
    2224     if (flags & PR_RDWR) {
    2225         osflags = O_RDWR;
    2226     } else if (flags & PR_WRONLY) {
    2227         osflags = O_WRONLY;
    2228     } else {
    2229         osflags = O_RDONLY;
    2230     }
    2231 
    2232     if (flags & PR_EXCL)
    2233         osflags |= O_EXCL;
    2234     if (flags & PR_APPEND)
    2235         osflags |= O_APPEND;
    2236     if (flags & PR_TRUNCATE)
    2237         osflags |= O_TRUNC;
    2238     if (flags & PR_SYNC) {
    2239 #if defined(O_SYNC)
    2240         osflags |= O_SYNC;
    2241 #elif defined(O_FSYNC)
    2242         osflags |= O_FSYNC;
    2243 #else
    2244 #error "Neither O_SYNC nor O_FSYNC is defined on this platform"
    2245 #endif
    2246     }
    2247 
    2248     /*
    2249     ** On creations we hold the 'create' lock in order to enforce
    2250     ** the semantics of PR_Rename. (see the latter for more details)
    2251     */
    2252     if (flags & PR_CREATE_FILE)
    2253     {
    2254         osflags |= O_CREAT;
    2255         if (NULL !=_pr_rename_lock)
    2256             PR_Lock(_pr_rename_lock);
    2257     }
    2258 
    2259     rv = _md_iovector._open64(name, osflags, mode);
    2260 
    2261     if (rv < 0) {
    2262         err = _MD_ERRNO();
    2263         _PR_MD_MAP_OPEN_ERROR(err);
    2264     }
    2265 
    2266     if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock))
    2267         PR_Unlock(_pr_rename_lock);
    2268     return rv;
    2269 }
    2270 
    2271 PRIntervalTime intr_timeout_ticks;
    2272 
    2273 #if defined(SOLARIS) || defined(IRIX)
    2274 static void sigsegvhandler() {
    2275     fprintf(stderr,"Received SIGSEGV\n");
    2276     fflush(stderr);
    2277     pause();
    2278 }
    2279 
    2280 static void sigaborthandler() {
    2281     fprintf(stderr,"Received SIGABRT\n");
    2282     fflush(stderr);
    2283     pause();
    2284 }
    2285 
    2286 static void sigbushandler() {
    2287     fprintf(stderr,"Received SIGBUS\n");
    2288     fflush(stderr);
    2289     pause();
    2290 }
    2291 #endif /* SOLARIS, IRIX */
    2292 
    2293 #endif  /* !defined(_PR_PTHREADS) */
    2294 
    229599void _MD_query_fd_inheritable(PRFileDesc *fd)
    2296100{
     
    2820624    sigemptyset(&timer_set);
    2821625
    2822 #if !defined(_PR_PTHREADS)
    2823 
    2824     sigaddset(&timer_set, SIGALRM);
    2825     sigemptyset(&empty_set);
    2826     intr_timeout_ticks =
    2827             PR_SecondsToInterval(_PR_INTERRUPT_CHECK_INTERVAL_SECS);
    2828 
    2829 #if defined(SOLARIS) || defined(IRIX)
    2830 
    2831     if (getenv("NSPR_SIGSEGV_HANDLE")) {
    2832         sigact.sa_handler = sigsegvhandler;
    2833         sigact.sa_flags = 0;
    2834         sigact.sa_mask = timer_set;
    2835         sigaction(SIGSEGV, &sigact, 0);
    2836     }
    2837 
    2838     if (getenv("NSPR_SIGABRT_HANDLE")) {
    2839         sigact.sa_handler = sigaborthandler;
    2840         sigact.sa_flags = 0;
    2841         sigact.sa_mask = timer_set;
    2842         sigaction(SIGABRT, &sigact, 0);
    2843     }
    2844 
    2845     if (getenv("NSPR_SIGBUS_HANDLE")) {
    2846         sigact.sa_handler = sigbushandler;
    2847         sigact.sa_flags = 0;
    2848         sigact.sa_mask = timer_set;
    2849         sigaction(SIGBUS, &sigact, 0);
    2850     }
    2851 
    2852 #endif
    2853 #endif  /* !defined(_PR_PTHREADS) */
    2854 
    2855     /*
    2856      * Under HP-UX DCE threads, sigaction() installs a per-thread
    2857      * handler, so we use sigvector() to install a process-wide
    2858      * handler.
    2859      */
    2860 #if defined(HPUX) && defined(_PR_DCETHREADS)
    2861     {
    2862         struct sigvec vec;
    2863 
    2864         vec.sv_handler = SIG_IGN;
    2865         vec.sv_mask = 0;
    2866         vec.sv_flags = 0;
    2867         rv = sigvector(SIGPIPE, &vec, NULL);
    2868         PR_ASSERT(0 == rv);
    2869     }
    2870 #else
    2871626    sigact.sa_handler = SIG_IGN;
    2872627    sigemptyset(&sigact.sa_mask);
     
    2874629    rv = sigaction(SIGPIPE, &sigact, 0);
    2875630    PR_ASSERT(0 == rv);
    2876 #endif /* HPUX && _PR_DCETHREADS */
    2877631
    2878632    _pr_rename_lock = PR_NewLock();
     
    2887641    _PR_InitIOV();  /* one last hack */
    2888642}
    2889 
    2890 #if !defined(_PR_PTHREADS)
    2891 
    2892 /*
    2893  * Variables used by the GC code, initialized in _MD_InitSegs().
    2894  */
    2895 static PRInt32 _pr_zero_fd = -1;
    2896 static PRLock *_pr_md_lock = NULL;
    2897 
    2898 /*
    2899  * _MD_InitSegs --
    2900  *
    2901  * This is Unix's version of _PR_MD_INIT_SEGS(), which is
    2902  * called by _PR_InitSegs(), which in turn is called by
    2903  * PR_Init().
    2904  */
    2905 void _MD_InitSegs(void)
    2906 {
    2907 #ifdef DEBUG
    2908     /*
    2909     ** Disable using mmap(2) if NSPR_NO_MMAP is set
    2910     */
    2911     if (getenv("NSPR_NO_MMAP")) {
    2912         _pr_zero_fd = -2;
    2913         return;
    2914     }
    2915 #endif
    2916     _pr_zero_fd = open("/dev/zero",O_RDWR , 0);
    2917     /* Prevent the fd from being inherited by child processes */
    2918     fcntl(_pr_zero_fd, F_SETFD, FD_CLOEXEC);
    2919     _pr_md_lock = PR_NewLock();
    2920 }
    2921 
    2922 PRStatus _MD_AllocSegment(PRSegment *seg, PRUint32 size, void *vaddr)
    2923 {
    2924     static char *lastaddr = (char*) _PR_STACK_VMBASE;
    2925     PRStatus retval = PR_SUCCESS;
    2926     int prot;
    2927     void *rv;
    2928 
    2929     PR_ASSERT(seg != 0);
    2930     PR_ASSERT(size != 0);
    2931 
    2932     PR_Lock(_pr_md_lock);
    2933     if (_pr_zero_fd < 0) {
    2934 from_heap:
    2935         seg->vaddr = PR_MALLOC(size);
    2936         if (!seg->vaddr) {
    2937             retval = PR_FAILURE;
    2938         }
    2939         else {
    2940             seg->size = size;
    2941         }
    2942         goto exit;
    2943     }
    2944 
    2945     prot = PROT_READ|PROT_WRITE;
    2946     /*
    2947      * On Alpha Linux, the user-level thread stack needs
    2948      * to be made executable because longjmp/signal seem
    2949      * to put machine instructions on the stack.
    2950      */
    2951 #if defined(LINUX) && defined(__alpha)
    2952     prot |= PROT_EXEC;
    2953 #endif
    2954     rv = mmap((vaddr != 0) ? vaddr : lastaddr, size, prot,
    2955         _MD_MMAP_FLAGS,
    2956         _pr_zero_fd, 0);
    2957     if (rv == (void*)-1) {
    2958         goto from_heap;
    2959     }
    2960     lastaddr += size;
    2961     seg->vaddr = rv;
    2962     seg->size = size;
    2963     seg->flags = _PR_SEG_VM;
    2964 
    2965 exit:
    2966     PR_Unlock(_pr_md_lock);
    2967     return retval;
    2968 }
    2969 
    2970 void _MD_FreeSegment(PRSegment *seg)
    2971 {
    2972     if (seg->flags & _PR_SEG_VM)
    2973         (void) munmap(seg->vaddr, seg->size);
    2974     else
    2975         PR_DELETE(seg->vaddr);
    2976 }
    2977 
    2978 #endif /* _PR_PTHREADS */
    2979643
    2980644/*
     
    3023687}
    3024688
    3025 #if !defined(_PR_PTHREADS)
    3026 /*
    3027  * Wait for I/O on multiple descriptors.
    3028  *
    3029  * Return 0 if timed out, return -1 if interrupted,
    3030  * else return the number of ready descriptors.
    3031  */
    3032 PRInt32 _PR_WaitForMultipleFDs(
    3033     _PRUnixPollDesc *unixpds,
    3034     PRInt32 pdcnt,
    3035     PRIntervalTime timeout)
    3036 {
    3037     PRPollQueue pq;
    3038     PRIntn is;
    3039     PRInt32 rv;
    3040     _PRCPU *io_cpu;
    3041     _PRUnixPollDesc *unixpd, *eunixpd;
    3042     PRThread *me = _PR_MD_CURRENT_THREAD();
    3043 
    3044     PR_ASSERT(!(me->flags & _PR_IDLE_THREAD));
    3045 
    3046     if (_PR_PENDING_INTERRUPT(me)) {
    3047         me->flags &= ~_PR_INTERRUPT;
    3048         PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
    3049         return -1;
    3050     }
    3051 
    3052     pq.pds = unixpds;
    3053     pq.npds = pdcnt;
    3054 
    3055     _PR_INTSOFF(is);
    3056     _PR_MD_IOQ_LOCK();
    3057     _PR_THREAD_LOCK(me);
    3058 
    3059     pq.thr = me;
    3060     io_cpu = me->cpu;
    3061     pq.on_ioq = PR_TRUE;
    3062     pq.timeout = timeout;
    3063     _PR_ADD_TO_IOQ(pq, me->cpu);
    3064 
    3065 #if !defined(_PR_USE_POLL)
    3066     eunixpd = unixpds + pdcnt;
    3067     for (unixpd = unixpds; unixpd < eunixpd; unixpd++) {
    3068         PRInt32 osfd = unixpd->osfd;
    3069         if (unixpd->in_flags & _PR_UNIX_POLL_READ) {
    3070             FD_SET(osfd, &_PR_FD_READ_SET(me->cpu));
    3071             _PR_FD_READ_CNT(me->cpu)[osfd]++;
    3072         }
    3073         if (unixpd->in_flags & _PR_UNIX_POLL_WRITE) {
    3074             FD_SET(osfd, &_PR_FD_WRITE_SET(me->cpu));
    3075             (_PR_FD_WRITE_CNT(me->cpu))[osfd]++;
    3076         }
    3077         if (unixpd->in_flags & _PR_UNIX_POLL_EXCEPT) {
    3078             FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
    3079             (_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++;
    3080         }
    3081         if (osfd > _PR_IOQ_MAX_OSFD(me->cpu)) {
    3082             _PR_IOQ_MAX_OSFD(me->cpu) = osfd;
    3083         }
    3084     }
    3085 #endif  /* !defined(_PR_USE_POLL) */
    3086 
    3087     if (_PR_IOQ_TIMEOUT(me->cpu) > timeout) {
    3088         _PR_IOQ_TIMEOUT(me->cpu) = timeout;
    3089     }
    3090 
    3091     _PR_IOQ_OSFD_CNT(me->cpu) += pdcnt;
    3092        
    3093     _PR_SLEEPQ_LOCK(me->cpu);
    3094     _PR_ADD_SLEEPQ(me, timeout);
    3095     me->state = _PR_IO_WAIT;
    3096     me->io_pending = PR_TRUE;
    3097     me->io_suspended = PR_FALSE;
    3098     _PR_SLEEPQ_UNLOCK(me->cpu);
    3099     _PR_THREAD_UNLOCK(me);
    3100     _PR_MD_IOQ_UNLOCK();
    3101 
    3102     _PR_MD_WAIT(me, timeout);
    3103 
    3104     me->io_pending = PR_FALSE;
    3105     me->io_suspended = PR_FALSE;
    3106 
    3107     /*
    3108      * This thread should run on the same cpu on which it was blocked; when
    3109      * the IO request times out the fd sets and fd counts for the
    3110      * cpu are updated below.
    3111      */
    3112     PR_ASSERT(me->cpu == io_cpu);
    3113 
    3114     /*
    3115     ** If we timed out the pollq might still be on the ioq. Remove it
    3116     ** before continuing.
    3117     */
    3118     if (pq.on_ioq) {
    3119         _PR_MD_IOQ_LOCK();
    3120         /*
    3121          * Need to check pq.on_ioq again
    3122          */
    3123         if (pq.on_ioq) {
    3124             PR_REMOVE_LINK(&pq.links);
    3125 #ifndef _PR_USE_POLL
    3126             eunixpd = unixpds + pdcnt;
    3127             for (unixpd = unixpds; unixpd < eunixpd; unixpd++) {
    3128                 PRInt32 osfd = unixpd->osfd;
    3129                 PRInt16 in_flags = unixpd->in_flags;
    3130 
    3131                 if (in_flags & _PR_UNIX_POLL_READ) {
    3132                     if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
    3133                         FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
    3134                 }
    3135                 if (in_flags & _PR_UNIX_POLL_WRITE) {
    3136                     if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0)
    3137                         FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
    3138                 }
    3139                 if (in_flags & _PR_UNIX_POLL_EXCEPT) {
    3140                     if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
    3141                         FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
    3142                 }
    3143             }
    3144 #endif  /* _PR_USE_POLL */
    3145             PR_ASSERT(pq.npds == pdcnt);
    3146             _PR_IOQ_OSFD_CNT(me->cpu) -= pdcnt;
    3147             PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0);
    3148         }
    3149         _PR_MD_IOQ_UNLOCK();
    3150     }
    3151     /* XXX Should we use _PR_FAST_INTSON or _PR_INTSON? */
    3152     if (1 == pdcnt) {
    3153         _PR_FAST_INTSON(is);
    3154     } else {
    3155         _PR_INTSON(is);
    3156     }
    3157 
    3158     if (_PR_PENDING_INTERRUPT(me)) {
    3159         me->flags &= ~_PR_INTERRUPT;
    3160         PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
    3161         return -1;
    3162     }
    3163 
    3164     rv = 0;
    3165     if (pq.on_ioq == PR_FALSE) {
    3166         /* Count the number of ready descriptors */
    3167         while (--pdcnt >= 0) {
    3168             if (unixpds->out_flags != 0) {
    3169                 rv++;
    3170             }
    3171             unixpds++;
    3172         }
    3173     }
    3174 
    3175     return rv;
    3176 }
    3177 
    3178 /*
    3179  * Unblock threads waiting for I/O
    3180  *    used when interrupting threads
    3181  *
    3182  * NOTE: The thread lock should held when this function is called.
    3183  * On return, the thread lock is released.
    3184  */
    3185 void _PR_Unblock_IO_Wait(PRThread *thr)
    3186 {
    3187     int pri = thr->priority;
    3188     _PRCPU *cpu = thr->cpu;
    3189  
    3190     /*
    3191      * GLOBAL threads wakeup periodically to check for interrupt
    3192      */
    3193     if (_PR_IS_NATIVE_THREAD(thr)) {
    3194         _PR_THREAD_UNLOCK(thr);
    3195         return;
    3196     }
    3197 
    3198     PR_ASSERT(thr->flags & (_PR_ON_SLEEPQ | _PR_ON_PAUSEQ));
    3199     _PR_SLEEPQ_LOCK(cpu);
    3200     _PR_DEL_SLEEPQ(thr, PR_TRUE);
    3201     _PR_SLEEPQ_UNLOCK(cpu);
    3202 
    3203     PR_ASSERT(!(thr->flags & _PR_IDLE_THREAD));
    3204     thr->state = _PR_RUNNABLE;
    3205     _PR_RUNQ_LOCK(cpu);
    3206     _PR_ADD_RUNQ(thr, cpu, pri);
    3207     _PR_RUNQ_UNLOCK(cpu);
    3208     _PR_THREAD_UNLOCK(thr);
    3209     _PR_MD_WAKEUP_WAITER(thr);
    3210 }
    3211 #endif  /* !defined(_PR_PTHREADS) */
    3212 
    3213689/*
    3214690 * When a nonblocking connect has completed, determine whether it
     
    3221697int _MD_unix_get_nonblocking_connect_error(int osfd)
    3222698{
    3223 #if defined(NTO)
    3224     /* Neutrino does not support the SO_ERROR socket option */
    3225     PRInt32      rv;
    3226     PRNetAddr    addr;
    3227     _PRSockLen_t addrlen = sizeof(addr);
    3228 
    3229     /* Test to see if we are using the Tiny TCP/IP Stack or the Full one. */
    3230     struct statvfs superblock;
    3231     rv = fstatvfs(osfd, &superblock);
    3232     if (rv == 0) {
    3233         if (strcmp(superblock.f_basetype, "ttcpip") == 0) {
    3234             /* Using the Tiny Stack! */
    3235             rv = getpeername(osfd, (struct sockaddr *) &addr,
    3236                     (_PRSockLen_t *) &addrlen);
    3237             if (rv == -1) {
    3238                 int errno_copy = errno;    /* make a copy so I don't
    3239                                             * accidentally reset */
    3240 
    3241                 if (errno_copy == ENOTCONN) {
    3242                     struct stat StatInfo;
    3243                     rv = fstat(osfd, &StatInfo);
    3244                     if (rv == 0) {
    3245                         time_t current_time = time(NULL);
    3246 
    3247                         /*
    3248                          * this is a real hack, can't explain why it
    3249                          * works it just does
    3250                          */
    3251                         if (abs(current_time - StatInfo.st_atime) < 5) {
    3252                             return ECONNREFUSED;
    3253                         } else {
    3254                             return ETIMEDOUT;
    3255                         }
    3256                     } else {
    3257                         return ECONNREFUSED;
    3258                     }
    3259                 } else {
    3260                     return errno_copy;
    3261                 }
    3262             } else {
    3263                 /* No Error */
    3264                 return 0;
    3265             }
    3266         } else {
    3267             /* Have the FULL Stack which supports SO_ERROR */
    3268             /* Hasn't been written yet, never been tested! */
    3269             /* [email protected] */
    3270 
    3271             int err;
    3272             _PRSockLen_t optlen = sizeof(err);
    3273 
    3274             if (getsockopt(osfd, SOL_SOCKET, SO_ERROR,
    3275                     (char *) &err, &optlen) == -1) {
    3276                 return errno;
    3277             } else {
    3278                 return err;
    3279             }           
    3280         }
    3281     } else {
    3282         return ECONNREFUSED;
    3283     }   
    3284 #elif defined(NCR) || defined(UNIXWARE) || defined(SNI) || defined(NEC)
    3285     /*
    3286      * getsockopt() fails with EPIPE, so use getmsg() instead.
    3287      */
    3288 
    3289     int rv;
    3290     int flags = 0;
    3291     rv = getmsg(osfd, NULL, NULL, &flags);
    3292     PR_ASSERT(-1 == rv || 0 == rv);
    3293     if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) {
    3294         return errno;
    3295     }
    3296     return 0;  /* no error */
    3297 #else
    3298699    int err;
    3299700    _PRSockLen_t optlen = sizeof(err);
     
    3303704        return err;
    3304705    }
    3305 #endif
    3306706}
    3307707
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/misc/prinit.c

    r101795 r101805  
    173173    _PR_InitLocks();
    174174    _PR_InitAtomic();
    175     _PR_InitSegs();
    176175        _PR_InitTPD();
    177176    _PR_InitEnv();
     
    199198{
    200199        _PR_InitStuff();
    201 
    202     /* Enable interrupts */
    203 #if !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY)
    204     _PR_MD_START_INTERRUPTS();
    205 #endif
    206 
    207200}
    208201
    209202PR_IMPLEMENT(void) PR_DisableClockInterrupts(void)
    210203{
    211 #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
    212         if (!_pr_initialized) {
    213                 _PR_InitStuff();
    214         } else {
    215         _PR_MD_DISABLE_CLOCK_INTERRUPTS();
    216         }
    217 #endif
    218204}
    219205
    220206PR_IMPLEMENT(void) PR_EnableClockInterrupts(void)
    221207{
    222 #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
    223         if (!_pr_initialized) {
    224                 _PR_InitStuff();
    225         }
    226     _PR_MD_ENABLE_CLOCK_INTERRUPTS();
    227 #endif
    228208}
    229209
    230210PR_IMPLEMENT(void) PR_BlockClockInterrupts(void)
    231211{
    232 #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
    233         _PR_MD_BLOCK_CLOCK_INTERRUPTS();
    234 #endif
    235212}
    236213
    237214PR_IMPLEMENT(void) PR_UnblockClockInterrupts(void)
    238215{
    239 #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
    240         _PR_MD_UNBLOCK_CLOCK_INTERRUPTS();
    241 #endif
    242216}
    243217
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/pthreads/ptio.c

    r101793 r101805  
    4040** Descritpion:  Implemenation of I/O methods for pthreads
    4141*/
    42 
    43 #if defined(_PR_PTHREADS)
    4442
    4543#if defined(_PR_POLL_WITH_SELECT)
     
    41804178    return rv;
    41814179}
    4182 #endif /* defined(_PR_PTHREADS) */
    41834180
    41844181#ifdef MOZ_UNICODE
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/pthreads/ptsynch.c

    r101769 r101805  
    4242*/
    4343
    44 #if defined(_PR_PTHREADS)
    45 
    4644#include "primpl.h"
    4745
     
    11261124}  /* PRP_NakedBroadcast */
    11271125
    1128 #endif  /* defined(_PR_PTHREADS) */
    1129 
    11301126/* ptsynch.c */
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/pthreads/ptthread.c

    r101793 r101805  
    4141** Exports:            ptthread.h
    4242*/
    43 
    44 #if defined(_PR_PTHREADS) || defined(_PR_DCETHREADS)
    4543
    4644#include "prlog.h"
     
    15601558#endif /* !defined(_PR_DCETHREADS) */
    15611559
    1562 #endif  /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */
    1563 
    15641560/* ptthread.c */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette