| Index: mozilla/nsprpub/pr/src/md/windows/w32poll.c
|
| ===================================================================
|
| --- mozilla/nsprpub/pr/src/md/windows/w32poll.c (revision 191424)
|
| +++ mozilla/nsprpub/pr/src/md/windows/w32poll.c (working copy)
|
| @@ -1,325 +0,0 @@
|
| -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
| -/* This Source Code Form is subject to the terms of the Mozilla Public
|
| - * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| -
|
| -/*
|
| - * This file implements _PR_MD_PR_POLL for Win32.
|
| - */
|
| -
|
| -/* The default value of FD_SETSIZE is 64. */
|
| -#define FD_SETSIZE 1024
|
| -
|
| -#include "primpl.h"
|
| -
|
| -#if !defined(_PR_GLOBAL_THREADS_ONLY)
|
| -
|
| -struct select_data_s {
|
| - PRInt32 status;
|
| - PRInt32 error;
|
| - fd_set *rd, *wt, *ex;
|
| - const struct timeval *tv;
|
| -};
|
| -
|
| -static void
|
| -_PR_MD_select_thread(void *cdata)
|
| -{
|
| - struct select_data_s *cd = (struct select_data_s *)cdata;
|
| -
|
| - cd->status = select(0, cd->rd, cd->wt, cd->ex, cd->tv);
|
| -
|
| - if (cd->status == SOCKET_ERROR) {
|
| - cd->error = WSAGetLastError();
|
| - }
|
| -}
|
| -
|
| -int _PR_NTFiberSafeSelect(
|
| - int nfds,
|
| - fd_set *readfds,
|
| - fd_set *writefds,
|
| - fd_set *exceptfds,
|
| - const struct timeval *timeout)
|
| -{
|
| - PRThread *me = _PR_MD_CURRENT_THREAD();
|
| - int ready;
|
| -
|
| - if (_PR_IS_NATIVE_THREAD(me)) {
|
| - ready = _MD_SELECT(nfds, readfds, writefds, exceptfds, timeout);
|
| - }
|
| - else
|
| - {
|
| - /*
|
| - ** Creating a new thread on each call!!
|
| - ** I guess web server doesn't use non-block I/O.
|
| - */
|
| - PRThread *selectThread;
|
| - struct select_data_s data;
|
| - data.status = 0;
|
| - data.error = 0;
|
| - data.rd = readfds;
|
| - data.wt = writefds;
|
| - data.ex = exceptfds;
|
| - data.tv = timeout;
|
| -
|
| - selectThread = PR_CreateThread(
|
| - PR_USER_THREAD, _PR_MD_select_thread, &data,
|
| - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
|
| - if (selectThread == NULL) return -1;
|
| -
|
| - PR_JoinThread(selectThread);
|
| - ready = data.status;
|
| - if (ready == SOCKET_ERROR) WSASetLastError(data.error);
|
| - }
|
| - return ready;
|
| -}
|
| -
|
| -#endif /* !defined(_PR_GLOBAL_THREADS_ONLY) */
|
| -
|
| -PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
|
| -{
|
| - int ready, err;
|
| - fd_set rd, wt, ex;
|
| - fd_set *rdp, *wtp, *exp;
|
| - int nrd, nwt, nex;
|
| - PRFileDesc *bottom;
|
| - PRPollDesc *pd, *epd;
|
| - PRThread *me = _PR_MD_CURRENT_THREAD();
|
| -
|
| - struct timeval tv, *tvp = NULL;
|
| -
|
| - if (_PR_PENDING_INTERRUPT(me))
|
| - {
|
| - me->flags &= ~_PR_INTERRUPT;
|
| - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
|
| - return -1;
|
| - }
|
| -
|
| - /*
|
| - ** Is it an empty set? If so, just sleep for the timeout and return
|
| - */
|
| - if (0 == npds)
|
| - {
|
| - PR_Sleep(timeout);
|
| - return 0;
|
| - }
|
| -
|
| - nrd = nwt = nex = 0;
|
| - FD_ZERO(&rd);
|
| - FD_ZERO(&wt);
|
| - FD_ZERO(&ex);
|
| -
|
| - ready = 0;
|
| - for (pd = pds, epd = pd + npds; pd < epd; pd++)
|
| - {
|
| - SOCKET osfd;
|
| - PRInt16 in_flags_read = 0, in_flags_write = 0;
|
| - PRInt16 out_flags_read = 0, out_flags_write = 0;
|
| -
|
| - if ((NULL != pd->fd) && (0 != pd->in_flags))
|
| - {
|
| - if (pd->in_flags & PR_POLL_READ)
|
| - {
|
| - in_flags_read = (pd->fd->methods->poll)(
|
| - pd->fd, (PRInt16)(pd->in_flags & ~PR_POLL_WRITE),
|
| - &out_flags_read);
|
| - }
|
| - if (pd->in_flags & PR_POLL_WRITE)
|
| - {
|
| - in_flags_write = (pd->fd->methods->poll)(
|
| - pd->fd, (PRInt16)(pd->in_flags & ~PR_POLL_READ),
|
| - &out_flags_write);
|
| - }
|
| - if ((0 != (in_flags_read & out_flags_read))
|
| - || (0 != (in_flags_write & out_flags_write)))
|
| - {
|
| - /* this one's ready right now (buffered input) */
|
| - if (0 == ready)
|
| - {
|
| - /*
|
| - * We will have to return without calling the
|
| - * system poll/select function. So zero the
|
| - * out_flags fields of all the poll descriptors
|
| - * before this one.
|
| - */
|
| - PRPollDesc *prev;
|
| - for (prev = pds; prev < pd; prev++)
|
| - {
|
| - prev->out_flags = 0;
|
| - }
|
| - }
|
| - ready += 1;
|
| - pd->out_flags = out_flags_read | out_flags_write;
|
| - }
|
| - else
|
| - {
|
| - pd->out_flags = 0; /* pre-condition */
|
| - /* make sure this is an NSPR supported stack */
|
| - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
|
| - PR_ASSERT(NULL != bottom); /* what to do about that? */
|
| - if ((NULL != bottom)
|
| - && (_PR_FILEDESC_OPEN == bottom->secret->state))
|
| - {
|
| - if (0 == ready)
|
| - {
|
| - osfd = (SOCKET) bottom->secret->md.osfd;
|
| - if (in_flags_read & PR_POLL_READ)
|
| - {
|
| - pd->out_flags |= _PR_POLL_READ_SYS_READ;
|
| - FD_SET(osfd, &rd);
|
| - nrd++;
|
| - }
|
| - if (in_flags_read & PR_POLL_WRITE)
|
| - {
|
| - pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
|
| - FD_SET(osfd, &wt);
|
| - nwt++;
|
| - }
|
| - if (in_flags_write & PR_POLL_READ)
|
| - {
|
| - pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
|
| - FD_SET(osfd, &rd);
|
| - nrd++;
|
| - }
|
| - if (in_flags_write & PR_POLL_WRITE)
|
| - {
|
| - pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
|
| - FD_SET(osfd, &wt);
|
| - nwt++;
|
| - }
|
| - if (pd->in_flags & PR_POLL_EXCEPT) {
|
| - FD_SET(osfd, &ex);
|
| - nex++;
|
| - }
|
| - }
|
| - }
|
| - else
|
| - {
|
| - if (0 == ready)
|
| - {
|
| - PRPollDesc *prev;
|
| - for (prev = pds; prev < pd; prev++)
|
| - {
|
| - prev->out_flags = 0;
|
| - }
|
| - }
|
| - ready += 1; /* this will cause an abrupt return */
|
| - pd->out_flags = PR_POLL_NVAL; /* bogii */
|
| - }
|
| - }
|
| - }
|
| - else
|
| - {
|
| - pd->out_flags = 0;
|
| - }
|
| - }
|
| -
|
| - if (0 != ready) return ready; /* no need to block */
|
| -
|
| - /*
|
| - * FD_SET does nothing if the fd_set's internal fd_array is full. If
|
| - * nrd, nwt, or nex is greater than FD_SETSIZE, we know FD_SET must
|
| - * have failed to insert an osfd into the corresponding fd_set, and
|
| - * therefore we should fail.
|
| - */
|
| - if ((nrd > FD_SETSIZE) || (nwt > FD_SETSIZE) || (nex > FD_SETSIZE)) {
|
| - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
| - return -1;
|
| - }
|
| -
|
| - rdp = (0 == nrd) ? NULL : &rd;
|
| - wtp = (0 == nwt) ? NULL : &wt;
|
| - exp = (0 == nex) ? NULL : &ex;
|
| -
|
| - if ((NULL == rdp) && (NULL == wtp) && (NULL == exp)) {
|
| - PR_Sleep(timeout);
|
| - return 0;
|
| - }
|
| -
|
| - if (timeout != PR_INTERVAL_NO_TIMEOUT)
|
| - {
|
| - PRInt32 ticksPerSecond = PR_TicksPerSecond();
|
| - tv.tv_sec = timeout / ticksPerSecond;
|
| - tv.tv_usec = PR_IntervalToMicroseconds( timeout % ticksPerSecond );
|
| - tvp = &tv;
|
| - }
|
| -
|
| -#if defined(_PR_GLOBAL_THREADS_ONLY)
|
| - ready = _MD_SELECT(0, rdp, wtp, exp, tvp);
|
| -#else
|
| - ready = _PR_NTFiberSafeSelect(0, rdp, wtp, exp, tvp);
|
| -#endif
|
| -
|
| - /*
|
| - ** Now to unravel the select sets back into the client's poll
|
| - ** descriptor list. Is this possibly an area for pissing away
|
| - ** a few cycles or what?
|
| - */
|
| - if (ready > 0)
|
| - {
|
| - ready = 0;
|
| - for (pd = pds, epd = pd + npds; pd < epd; pd++)
|
| - {
|
| - PRInt16 out_flags = 0;
|
| - if ((NULL != pd->fd) && (0 != pd->in_flags))
|
| - {
|
| - SOCKET osfd;
|
| - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
|
| - PR_ASSERT(NULL != bottom);
|
| -
|
| - osfd = (SOCKET) bottom->secret->md.osfd;
|
| -
|
| - if (FD_ISSET(osfd, &rd))
|
| - {
|
| - if (pd->out_flags & _PR_POLL_READ_SYS_READ)
|
| - out_flags |= PR_POLL_READ;
|
| - if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
|
| - out_flags |= PR_POLL_WRITE;
|
| - }
|
| - if (FD_ISSET(osfd, &wt))
|
| - {
|
| - if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
|
| - out_flags |= PR_POLL_READ;
|
| - if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
|
| - out_flags |= PR_POLL_WRITE;
|
| - }
|
| - if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;
|
| - }
|
| - pd->out_flags = out_flags;
|
| - if (out_flags) ready++;
|
| - }
|
| - PR_ASSERT(ready > 0);
|
| - }
|
| - else if (ready == SOCKET_ERROR)
|
| - {
|
| - err = WSAGetLastError();
|
| - if (err == WSAENOTSOCK)
|
| - {
|
| - /* Find the bad fds */
|
| - int optval;
|
| - int optlen = sizeof(optval);
|
| - ready = 0;
|
| - for (pd = pds, epd = pd + npds; pd < epd; pd++)
|
| - {
|
| - pd->out_flags = 0;
|
| - if ((NULL != pd->fd) && (0 != pd->in_flags))
|
| - {
|
| - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
|
| - if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET,
|
| - SO_TYPE, (char *) &optval, &optlen) == -1)
|
| - {
|
| - PR_ASSERT(WSAGetLastError() == WSAENOTSOCK);
|
| - if (WSAGetLastError() == WSAENOTSOCK)
|
| - {
|
| - pd->out_flags = PR_POLL_NVAL;
|
| - ready++;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - PR_ASSERT(ready > 0);
|
| - }
|
| - else _PR_MD_MAP_SELECT_ERROR(err);
|
| - }
|
| -
|
| - return ready;
|
| -}
|
|
|