Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/nsprpub/pr/src/md/windows/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 8 kB image not shown  

Quelle  w32poll.c   Sprache: C

 
/* -*- 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);
        /* ignore a socket without PR_NSPR_IO_LAYER available */

        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;
}

Messung V0.5
C=95 H=96 G=95

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.