michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #if defined(_PR_PTHREADS) michael@0: michael@0: #error "This file should not be compiled" michael@0: michael@0: #else /* defined(_PR_PTHREADS) */ michael@0: michael@0: #include "primpl.h" michael@0: michael@0: #include michael@0: michael@0: #include michael@0: #ifdef _PR_USE_POLL michael@0: #include michael@0: #endif michael@0: michael@0: #if defined(_PR_USE_POLL) michael@0: static PRInt32 NativeThreadPoll( michael@0: PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) michael@0: { michael@0: /* michael@0: * This function is mostly duplicated from ptio.s's PR_Poll(). michael@0: */ michael@0: PRInt32 ready = 0; michael@0: /* michael@0: * For restarting poll() if it is interrupted by a signal. michael@0: * We use these variables to figure out how much time has michael@0: * elapsed and how much of the timeout still remains. michael@0: */ michael@0: PRIntn index, msecs; michael@0: struct pollfd *syspoll = NULL; michael@0: PRIntervalTime start, elapsed, remaining; michael@0: michael@0: syspoll = (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd)); michael@0: if (NULL == syspoll) michael@0: { michael@0: PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); michael@0: return -1; michael@0: } michael@0: for (index = 0; index < npds; ++index) michael@0: { michael@0: PRFileDesc *bottom; michael@0: PRInt16 in_flags_read = 0, in_flags_write = 0; michael@0: PRInt16 out_flags_read = 0, out_flags_write = 0; michael@0: michael@0: if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) michael@0: { michael@0: if (pds[index].in_flags & PR_POLL_READ) michael@0: { michael@0: in_flags_read = (pds[index].fd->methods->poll)( michael@0: pds[index].fd, michael@0: pds[index].in_flags & ~PR_POLL_WRITE, michael@0: &out_flags_read); michael@0: } michael@0: if (pds[index].in_flags & PR_POLL_WRITE) michael@0: { michael@0: in_flags_write = (pds[index].fd->methods->poll)( michael@0: pds[index].fd, michael@0: pds[index].in_flags & ~PR_POLL_READ, michael@0: &out_flags_write); michael@0: } michael@0: if ((0 != (in_flags_read & out_flags_read)) michael@0: || (0 != (in_flags_write & out_flags_write))) michael@0: { michael@0: /* this one is ready right now */ michael@0: if (0 == ready) michael@0: { michael@0: /* michael@0: * We will return without calling the system michael@0: * poll function. So zero the out_flags michael@0: * fields of all the poll descriptors before michael@0: * this one. michael@0: */ michael@0: int i; michael@0: for (i = 0; i < index; i++) michael@0: { michael@0: pds[i].out_flags = 0; michael@0: } michael@0: } michael@0: ready += 1; michael@0: pds[index].out_flags = out_flags_read | out_flags_write; michael@0: } michael@0: else michael@0: { michael@0: pds[index].out_flags = 0; /* pre-condition */ michael@0: /* now locate the NSPR layer at the bottom of the stack */ michael@0: bottom = PR_GetIdentitiesLayer(pds[index].fd, PR_NSPR_IO_LAYER); michael@0: PR_ASSERT(NULL != bottom); /* what to do about that? */ michael@0: if ((NULL != bottom) michael@0: && (_PR_FILEDESC_OPEN == bottom->secret->state)) michael@0: { michael@0: if (0 == ready) michael@0: { michael@0: syspoll[index].fd = bottom->secret->md.osfd; michael@0: syspoll[index].events = 0; /* pre-condition */ michael@0: if (in_flags_read & PR_POLL_READ) michael@0: { michael@0: pds[index].out_flags |= michael@0: _PR_POLL_READ_SYS_READ; michael@0: syspoll[index].events |= POLLIN; michael@0: } michael@0: if (in_flags_read & PR_POLL_WRITE) michael@0: { michael@0: pds[index].out_flags |= michael@0: _PR_POLL_READ_SYS_WRITE; michael@0: syspoll[index].events |= POLLOUT; michael@0: } michael@0: if (in_flags_write & PR_POLL_READ) michael@0: { michael@0: pds[index].out_flags |= michael@0: _PR_POLL_WRITE_SYS_READ; michael@0: syspoll[index].events |= POLLIN; michael@0: } michael@0: if (in_flags_write & PR_POLL_WRITE) michael@0: { michael@0: pds[index].out_flags |= michael@0: _PR_POLL_WRITE_SYS_WRITE; michael@0: syspoll[index].events |= POLLOUT; michael@0: } michael@0: if (pds[index].in_flags & PR_POLL_EXCEPT) michael@0: syspoll[index].events |= POLLPRI; michael@0: } michael@0: } michael@0: else michael@0: { michael@0: if (0 == ready) michael@0: { michael@0: int i; michael@0: for (i = 0; i < index; i++) michael@0: { michael@0: pds[i].out_flags = 0; michael@0: } michael@0: } michael@0: ready += 1; /* this will cause an abrupt return */ michael@0: pds[index].out_flags = PR_POLL_NVAL; /* bogii */ michael@0: } michael@0: } michael@0: } michael@0: else michael@0: { michael@0: /* make poll() ignore this entry */ michael@0: syspoll[index].fd = -1; michael@0: syspoll[index].events = 0; michael@0: pds[index].out_flags = 0; michael@0: } michael@0: } michael@0: michael@0: if (0 == ready) michael@0: { michael@0: switch (timeout) michael@0: { michael@0: case PR_INTERVAL_NO_WAIT: msecs = 0; break; michael@0: case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break; michael@0: default: michael@0: msecs = PR_IntervalToMilliseconds(timeout); michael@0: start = PR_IntervalNow(); michael@0: } michael@0: michael@0: retry: michael@0: ready = _MD_POLL(syspoll, npds, msecs); michael@0: if (-1 == ready) michael@0: { michael@0: PRIntn oserror = errno; michael@0: michael@0: if (EINTR == oserror) michael@0: { michael@0: if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry; michael@0: else if (timeout == PR_INTERVAL_NO_WAIT) ready = 0; michael@0: else michael@0: { michael@0: elapsed = (PRIntervalTime)(PR_IntervalNow() - start); michael@0: if (elapsed > timeout) ready = 0; /* timed out */ michael@0: else michael@0: { michael@0: remaining = timeout - elapsed; michael@0: msecs = PR_IntervalToMilliseconds(remaining); michael@0: goto retry; michael@0: } michael@0: } michael@0: } michael@0: else _PR_MD_MAP_POLL_ERROR(oserror); michael@0: } michael@0: else if (ready > 0) michael@0: { michael@0: for (index = 0; index < npds; ++index) michael@0: { michael@0: PRInt16 out_flags = 0; michael@0: if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) michael@0: { michael@0: if (0 != syspoll[index].revents) michael@0: { michael@0: /* michael@0: ** Set up the out_flags so that it contains the michael@0: ** bits that the highest layer thinks are nice michael@0: ** to have. Then the client of that layer will michael@0: ** call the appropriate I/O function and maybe michael@0: ** the protocol will make progress. michael@0: */ michael@0: if (syspoll[index].revents & POLLIN) michael@0: { michael@0: if (pds[index].out_flags michael@0: & _PR_POLL_READ_SYS_READ) michael@0: { michael@0: out_flags |= PR_POLL_READ; michael@0: } michael@0: if (pds[index].out_flags michael@0: & _PR_POLL_WRITE_SYS_READ) michael@0: { michael@0: out_flags |= PR_POLL_WRITE; michael@0: } michael@0: } michael@0: if (syspoll[index].revents & POLLOUT) michael@0: { michael@0: if (pds[index].out_flags michael@0: & _PR_POLL_READ_SYS_WRITE) michael@0: { michael@0: out_flags |= PR_POLL_READ; michael@0: } michael@0: if (pds[index].out_flags michael@0: & _PR_POLL_WRITE_SYS_WRITE) michael@0: { michael@0: out_flags |= PR_POLL_WRITE; michael@0: } michael@0: } michael@0: if (syspoll[index].revents & POLLPRI) michael@0: out_flags |= PR_POLL_EXCEPT; michael@0: if (syspoll[index].revents & POLLERR) michael@0: out_flags |= PR_POLL_ERR; michael@0: if (syspoll[index].revents & POLLNVAL) michael@0: out_flags |= PR_POLL_NVAL; michael@0: if (syspoll[index].revents & POLLHUP) michael@0: out_flags |= PR_POLL_HUP; michael@0: } michael@0: } michael@0: pds[index].out_flags = out_flags; michael@0: } michael@0: } michael@0: } michael@0: michael@0: PR_DELETE(syspoll); michael@0: return ready; michael@0: michael@0: } /* NativeThreadPoll */ michael@0: #endif /* defined(_PR_USE_POLL) */ michael@0: michael@0: #if !defined(_PR_USE_POLL) michael@0: static PRInt32 NativeThreadSelect( michael@0: PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) michael@0: { michael@0: /* michael@0: * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL(). michael@0: */ michael@0: fd_set rd, wt, ex; michael@0: PRFileDesc *bottom; michael@0: PRPollDesc *pd, *epd; michael@0: PRInt32 maxfd = -1, ready, err; michael@0: PRIntervalTime remaining, elapsed, start; michael@0: michael@0: struct timeval tv, *tvp = NULL; michael@0: michael@0: FD_ZERO(&rd); michael@0: FD_ZERO(&wt); michael@0: FD_ZERO(&ex); michael@0: michael@0: ready = 0; michael@0: for (pd = pds, epd = pd + npds; pd < epd; pd++) michael@0: { michael@0: PRInt16 in_flags_read = 0, in_flags_write = 0; michael@0: PRInt16 out_flags_read = 0, out_flags_write = 0; michael@0: michael@0: if ((NULL != pd->fd) && (0 != pd->in_flags)) michael@0: { michael@0: if (pd->in_flags & PR_POLL_READ) michael@0: { michael@0: in_flags_read = (pd->fd->methods->poll)( michael@0: pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); michael@0: } michael@0: if (pd->in_flags & PR_POLL_WRITE) michael@0: { michael@0: in_flags_write = (pd->fd->methods->poll)( michael@0: pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); michael@0: } michael@0: if ((0 != (in_flags_read & out_flags_read)) michael@0: || (0 != (in_flags_write & out_flags_write))) michael@0: { michael@0: /* this one's ready right now */ michael@0: if (0 == ready) michael@0: { michael@0: /* michael@0: * We will have to return without calling the michael@0: * system poll/select function. So zero the michael@0: * out_flags fields of all the poll descriptors michael@0: * before this one. michael@0: */ michael@0: PRPollDesc *prev; michael@0: for (prev = pds; prev < pd; prev++) michael@0: { michael@0: prev->out_flags = 0; michael@0: } michael@0: } michael@0: ready += 1; michael@0: pd->out_flags = out_flags_read | out_flags_write; michael@0: } michael@0: else michael@0: { michael@0: pd->out_flags = 0; /* pre-condition */ michael@0: michael@0: /* make sure this is an NSPR supported stack */ michael@0: bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); michael@0: PR_ASSERT(NULL != bottom); /* what to do about that? */ michael@0: if ((NULL != bottom) michael@0: && (_PR_FILEDESC_OPEN == bottom->secret->state)) michael@0: { michael@0: if (0 == ready) michael@0: { michael@0: PRInt32 osfd = bottom->secret->md.osfd; michael@0: if (osfd > maxfd) maxfd = osfd; michael@0: if (in_flags_read & PR_POLL_READ) michael@0: { michael@0: pd->out_flags |= _PR_POLL_READ_SYS_READ; michael@0: FD_SET(osfd, &rd); michael@0: } michael@0: if (in_flags_read & PR_POLL_WRITE) michael@0: { michael@0: pd->out_flags |= _PR_POLL_READ_SYS_WRITE; michael@0: FD_SET(osfd, &wt); michael@0: } michael@0: if (in_flags_write & PR_POLL_READ) michael@0: { michael@0: pd->out_flags |= _PR_POLL_WRITE_SYS_READ; michael@0: FD_SET(osfd, &rd); michael@0: } michael@0: if (in_flags_write & PR_POLL_WRITE) michael@0: { michael@0: pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; michael@0: FD_SET(osfd, &wt); michael@0: } michael@0: if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex); michael@0: } michael@0: } michael@0: else michael@0: { michael@0: if (0 == ready) michael@0: { michael@0: PRPollDesc *prev; michael@0: for (prev = pds; prev < pd; prev++) michael@0: { michael@0: prev->out_flags = 0; michael@0: } michael@0: } michael@0: ready += 1; /* this will cause an abrupt return */ michael@0: pd->out_flags = PR_POLL_NVAL; /* bogii */ michael@0: } michael@0: } michael@0: } michael@0: else michael@0: { michael@0: pd->out_flags = 0; michael@0: } michael@0: } michael@0: michael@0: if (0 != ready) return ready; /* no need to block */ michael@0: michael@0: remaining = timeout; michael@0: start = PR_IntervalNow(); michael@0: michael@0: retry: michael@0: if (timeout != PR_INTERVAL_NO_TIMEOUT) michael@0: { michael@0: PRInt32 ticksPerSecond = PR_TicksPerSecond(); michael@0: tv.tv_sec = remaining / ticksPerSecond; michael@0: tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond ); michael@0: tvp = &tv; michael@0: } michael@0: michael@0: ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp); michael@0: michael@0: if (ready == -1 && errno == EINTR) michael@0: { michael@0: if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry; michael@0: else michael@0: { michael@0: elapsed = (PRIntervalTime) (PR_IntervalNow() - start); michael@0: if (elapsed > timeout) ready = 0; /* timed out */ michael@0: else michael@0: { michael@0: remaining = timeout - elapsed; michael@0: goto retry; michael@0: } michael@0: } michael@0: } michael@0: michael@0: /* michael@0: ** Now to unravel the select sets back into the client's poll michael@0: ** descriptor list. Is this possibly an area for pissing away michael@0: ** a few cycles or what? michael@0: */ michael@0: if (ready > 0) michael@0: { michael@0: ready = 0; michael@0: for (pd = pds, epd = pd + npds; pd < epd; pd++) michael@0: { michael@0: PRInt16 out_flags = 0; michael@0: if ((NULL != pd->fd) && (0 != pd->in_flags)) michael@0: { michael@0: PRInt32 osfd; michael@0: bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); michael@0: PR_ASSERT(NULL != bottom); michael@0: michael@0: osfd = bottom->secret->md.osfd; michael@0: michael@0: if (FD_ISSET(osfd, &rd)) michael@0: { michael@0: if (pd->out_flags & _PR_POLL_READ_SYS_READ) michael@0: out_flags |= PR_POLL_READ; michael@0: if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) michael@0: out_flags |= PR_POLL_WRITE; michael@0: } michael@0: if (FD_ISSET(osfd, &wt)) michael@0: { michael@0: if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) michael@0: out_flags |= PR_POLL_READ; michael@0: if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) michael@0: out_flags |= PR_POLL_WRITE; michael@0: } michael@0: if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT; michael@0: } michael@0: pd->out_flags = out_flags; michael@0: if (out_flags) ready++; michael@0: } michael@0: PR_ASSERT(ready > 0); michael@0: } michael@0: else if (ready < 0) michael@0: { michael@0: err = _MD_ERRNO(); michael@0: if (err == EBADF) michael@0: { michael@0: /* Find the bad fds */ michael@0: ready = 0; michael@0: for (pd = pds, epd = pd + npds; pd < epd; pd++) michael@0: { michael@0: pd->out_flags = 0; michael@0: if ((NULL != pd->fd) && (0 != pd->in_flags)) michael@0: { michael@0: bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); michael@0: if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1) michael@0: { michael@0: pd->out_flags = PR_POLL_NVAL; michael@0: ready++; michael@0: } michael@0: } michael@0: } michael@0: PR_ASSERT(ready > 0); michael@0: } michael@0: else _PR_MD_MAP_SELECT_ERROR(err); michael@0: } michael@0: michael@0: return ready; michael@0: } /* NativeThreadSelect */ michael@0: #endif /* !defined(_PR_USE_POLL) */ michael@0: michael@0: static PRInt32 LocalThreads( michael@0: PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) michael@0: { michael@0: PRPollDesc *pd, *epd; michael@0: PRInt32 ready, pdcnt; michael@0: _PRUnixPollDesc *unixpds, *unixpd; michael@0: michael@0: /* michael@0: * XXX michael@0: * PRPollDesc has a PRFileDesc field, fd, while the IOQ michael@0: * is a list of PRPollQueue structures, each of which contains michael@0: * a _PRUnixPollDesc. A _PRUnixPollDesc struct contains michael@0: * the OS file descriptor, osfd, and not a PRFileDesc. michael@0: * So, we have allocate memory for _PRUnixPollDesc structures, michael@0: * copy the flags information from the pds list and have pq michael@0: * point to this list of _PRUnixPollDesc structures. michael@0: * michael@0: * It would be better if the memory allocation can be avoided. michael@0: */ michael@0: michael@0: unixpd = unixpds = (_PRUnixPollDesc*) michael@0: PR_MALLOC(npds * sizeof(_PRUnixPollDesc)); michael@0: if (NULL == unixpds) michael@0: { michael@0: PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); michael@0: return -1; michael@0: } michael@0: michael@0: ready = 0; michael@0: for (pdcnt = 0, pd = pds, epd = pd + npds; pd < epd; pd++) michael@0: { michael@0: PRFileDesc *bottom; michael@0: PRInt16 in_flags_read = 0, in_flags_write = 0; michael@0: PRInt16 out_flags_read = 0, out_flags_write = 0; michael@0: michael@0: if ((NULL != pd->fd) && (0 != pd->in_flags)) michael@0: { michael@0: if (pd->in_flags & PR_POLL_READ) michael@0: { michael@0: in_flags_read = (pd->fd->methods->poll)( michael@0: pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); michael@0: } michael@0: if (pd->in_flags & PR_POLL_WRITE) michael@0: { michael@0: in_flags_write = (pd->fd->methods->poll)( michael@0: pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); michael@0: } michael@0: if ((0 != (in_flags_read & out_flags_read)) michael@0: || (0 != (in_flags_write & out_flags_write))) michael@0: { michael@0: /* this one's ready right now */ michael@0: if (0 == ready) michael@0: { michael@0: /* michael@0: * We will have to return without calling the michael@0: * system poll/select function. So zero the michael@0: * out_flags fields of all the poll descriptors michael@0: * before this one. michael@0: */ michael@0: PRPollDesc *prev; michael@0: for (prev = pds; prev < pd; prev++) michael@0: { michael@0: prev->out_flags = 0; michael@0: } michael@0: } michael@0: ready += 1; michael@0: pd->out_flags = out_flags_read | out_flags_write; michael@0: } michael@0: else michael@0: { michael@0: pd->out_flags = 0; /* pre-condition */ michael@0: bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); michael@0: PR_ASSERT(NULL != bottom); /* what to do about that? */ michael@0: if ((NULL != bottom) michael@0: && (_PR_FILEDESC_OPEN == bottom->secret->state)) michael@0: { michael@0: if (0 == ready) michael@0: { michael@0: unixpd->osfd = bottom->secret->md.osfd; michael@0: unixpd->in_flags = 0; michael@0: if (in_flags_read & PR_POLL_READ) michael@0: { michael@0: unixpd->in_flags |= _PR_UNIX_POLL_READ; michael@0: pd->out_flags |= _PR_POLL_READ_SYS_READ; michael@0: } michael@0: if (in_flags_read & PR_POLL_WRITE) michael@0: { michael@0: unixpd->in_flags |= _PR_UNIX_POLL_WRITE; michael@0: pd->out_flags |= _PR_POLL_READ_SYS_WRITE; michael@0: } michael@0: if (in_flags_write & PR_POLL_READ) michael@0: { michael@0: unixpd->in_flags |= _PR_UNIX_POLL_READ; michael@0: pd->out_flags |= _PR_POLL_WRITE_SYS_READ; michael@0: } michael@0: if (in_flags_write & PR_POLL_WRITE) michael@0: { michael@0: unixpd->in_flags |= _PR_UNIX_POLL_WRITE; michael@0: pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; michael@0: } michael@0: if ((in_flags_read | in_flags_write) & PR_POLL_EXCEPT) michael@0: { michael@0: unixpd->in_flags |= _PR_UNIX_POLL_EXCEPT; michael@0: } michael@0: unixpd++; pdcnt++; michael@0: } michael@0: } michael@0: else michael@0: { michael@0: if (0 == ready) michael@0: { michael@0: PRPollDesc *prev; michael@0: for (prev = pds; prev < pd; prev++) michael@0: { michael@0: prev->out_flags = 0; michael@0: } michael@0: } michael@0: ready += 1; /* this will cause an abrupt return */ michael@0: pd->out_flags = PR_POLL_NVAL; /* bogii */ michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: if (0 != ready) michael@0: { michael@0: /* no need to block */ michael@0: PR_DELETE(unixpds); michael@0: return ready; michael@0: } michael@0: michael@0: ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout); michael@0: michael@0: /* michael@0: * Copy the out_flags from the _PRUnixPollDesc structures to the michael@0: * user's PRPollDesc structures and free the allocated memory michael@0: */ michael@0: unixpd = unixpds; michael@0: for (pd = pds, epd = pd + npds; pd < epd; pd++) michael@0: { michael@0: PRInt16 out_flags = 0; michael@0: if ((NULL != pd->fd) && (0 != pd->in_flags)) michael@0: { michael@0: /* michael@0: * take errors from the poll operation, michael@0: * the R/W bits from the request michael@0: */ michael@0: if (0 != unixpd->out_flags) michael@0: { michael@0: if (unixpd->out_flags & _PR_UNIX_POLL_READ) michael@0: { michael@0: if (pd->out_flags & _PR_POLL_READ_SYS_READ) michael@0: out_flags |= PR_POLL_READ; michael@0: if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) michael@0: out_flags |= PR_POLL_WRITE; michael@0: } michael@0: if (unixpd->out_flags & _PR_UNIX_POLL_WRITE) michael@0: { michael@0: if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) michael@0: out_flags |= PR_POLL_READ; michael@0: if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) michael@0: out_flags |= PR_POLL_WRITE; michael@0: } michael@0: if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT) michael@0: out_flags |= PR_POLL_EXCEPT; michael@0: if (unixpd->out_flags & _PR_UNIX_POLL_ERR) michael@0: out_flags |= PR_POLL_ERR; michael@0: if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) michael@0: out_flags |= PR_POLL_NVAL; michael@0: if (unixpd->out_flags & _PR_UNIX_POLL_HUP) michael@0: out_flags |= PR_POLL_HUP; michael@0: } michael@0: unixpd++; michael@0: } michael@0: pd->out_flags = out_flags; michael@0: } michael@0: michael@0: PR_DELETE(unixpds); michael@0: michael@0: return ready; michael@0: } /* LocalThreads */ michael@0: michael@0: #if defined(_PR_USE_POLL) michael@0: #define NativeThreads NativeThreadPoll michael@0: #else michael@0: #define NativeThreads NativeThreadSelect michael@0: #endif michael@0: michael@0: PRInt32 _MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) michael@0: { michael@0: PRInt32 rv = 0; michael@0: PRThread *me = _PR_MD_CURRENT_THREAD(); michael@0: michael@0: if (_PR_PENDING_INTERRUPT(me)) michael@0: { michael@0: me->flags &= ~_PR_INTERRUPT; michael@0: PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); michael@0: return -1; michael@0: } michael@0: if (0 == npds) PR_Sleep(timeout); michael@0: else if (_PR_IS_NATIVE_THREAD(me)) michael@0: rv = NativeThreads(pds, npds, timeout); michael@0: else rv = LocalThreads(pds, npds, timeout); michael@0: michael@0: return rv; michael@0: } /* _MD_pr_poll */ michael@0: michael@0: #endif /* defined(_PR_PTHREADS) */ michael@0: michael@0: /* uxpoll.c */ michael@0: