home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / pr / src / md / os2 / os2poll.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  4.7 KB  |  166 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  * 
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  * 
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /*
  20.  * This file implements _PR_MD_PR_POLL for OS/2.
  21.  */
  22.  
  23. #include "primpl.h"
  24.  
  25. PRInt32
  26. _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds,
  27.                         PRIntervalTime timeout)
  28. {
  29.     PRPollDesc *pd, *epd;
  30.     PRInt32 n, err, pdcnt;
  31.     PRThread *me = _PR_MD_CURRENT_THREAD();
  32.  
  33.        fd_set rd, wt, ex;
  34.        struct timeval tv, *tvp = NULL;
  35.        int maxfd = -1;
  36.  
  37.     /*
  38.         * For restarting _MD_SELECT() if it is interrupted by a signal.
  39.         * We use these variables to figure out how much time has elapsed
  40.         * and how much of the timeout still remains.
  41.         */
  42.        PRIntervalTime start, elapsed, remaining;
  43.  
  44.        FD_ZERO(&rd);
  45.        FD_ZERO(&wt);
  46.        FD_ZERO(&ex);
  47.  
  48.     for (pd = pds, epd = pd + npds; pd < epd; pd++) {
  49.          PRInt32 osfd;
  50.          PRInt16 in_flags = pd->in_flags;
  51.          PRFileDesc *bottom = pd->fd;
  52.  
  53.          if ((NULL == bottom) || (in_flags == 0)) {
  54.              continue;
  55.          }
  56.          while (bottom->lower != NULL) {
  57.              bottom = bottom->lower;
  58.          }
  59.          osfd = bottom->secret->md.osfd;
  60.  
  61.        if (osfd > maxfd) {
  62.            maxfd = osfd;
  63.        }
  64.        if (in_flags & PR_POLL_READ)  {
  65.            FD_SET(osfd, &rd);
  66.        }
  67.        if (in_flags & PR_POLL_WRITE) {
  68.            FD_SET(osfd, &wt);
  69.        }
  70.        if (in_flags & PR_POLL_EXCEPT) {
  71.            FD_SET(osfd, &ex);
  72.        }
  73.    }
  74.    if (timeout != PR_INTERVAL_NO_TIMEOUT) {
  75.        tv.tv_sec = PR_IntervalToSeconds(timeout);
  76.        tv.tv_usec = PR_IntervalToMicroseconds(timeout) % PR_USEC_PER_SEC;
  77.        tvp = &tv;
  78.        start = PR_IntervalNow();
  79.    }
  80.  
  81. retry:
  82.    n = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp);
  83.    if (n == -1 && errno == EINTR) {
  84.          if (timeout == PR_INTERVAL_NO_TIMEOUT) {
  85.               goto retry;
  86.          } else {
  87.              elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
  88.              if (elapsed > timeout) {
  89.                  n = 0;  /* timed out */
  90.             } else {
  91.                 remaining = timeout - elapsed;
  92.                 tv.tv_sec = PR_IntervalToSeconds(remaining);
  93.                 tv.tv_usec = PR_IntervalToMicroseconds(
  94.                     remaining - PR_SecondsToInterval(tv.tv_sec));
  95.                 goto retry;
  96.          }
  97.          }
  98.    }
  99.  
  100.    if (n > 0) {
  101.        n = 0;
  102.        for (pd = pds, epd = pd + npds; pd < epd; pd++) {
  103.            PRInt32 osfd;
  104.            PRInt16 in_flags = pd->in_flags;
  105.            PRInt16 out_flags = 0;
  106.            PRFileDesc *bottom = pd->fd;
  107.  
  108.              if ((NULL == bottom) || (in_flags == 0)) {
  109.                pd->out_flags = 0;
  110.                continue;
  111.            }
  112.            while (bottom->lower != NULL) {
  113.                bottom = bottom->lower;
  114.            }
  115.            osfd = bottom->secret->md.osfd;
  116.  
  117.            if ((in_flags & PR_POLL_READ) && FD_ISSET(osfd, &rd))  {
  118.                out_flags |= PR_POLL_READ;
  119.            }
  120.            if ((in_flags & PR_POLL_WRITE) && FD_ISSET(osfd, &wt)) {
  121.                out_flags |= PR_POLL_WRITE;
  122.            }
  123.            if ((in_flags & PR_POLL_EXCEPT) && FD_ISSET(osfd, &ex)) {
  124.                out_flags |= PR_POLL_EXCEPT;
  125.            }
  126.            pd->out_flags = out_flags;
  127.            if (out_flags) {
  128.                n++;
  129.            }
  130.        }
  131.        PR_ASSERT(n > 0);
  132.    } else if (n < 0) {
  133.        err = _MD_ERRNO();
  134.        if (err == EBADF) {
  135.            /* Find the bad fds */
  136.            n = 0;
  137.            for (pd = pds, epd = pd + npds; pd < epd; pd++) {
  138.             int optval;
  139.             int optlen = sizeof(optval);
  140.                PRFileDesc *bottom = pd->fd;
  141.             pd->out_flags = 0;
  142.                if ((NULL == bottom) || (pd->in_flags == 0)) {
  143.                    continue;
  144.                }
  145.                while (bottom->lower != NULL) {
  146.                    bottom = bottom->lower;
  147.                }
  148.             if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET,
  149.                     SO_TYPE, (char *) &optval, &optlen) == -1) {
  150.                 PR_ASSERT(_MD_ERRNO() == ENOTSOCK);
  151.                 if (_MD_ERRNO() == ENOTSOCK) {
  152.                     pd->out_flags = PR_POLL_NVAL;
  153.                     n++;
  154.                 }
  155.             }
  156.            }
  157.            PR_ASSERT(n > 0);
  158.        } else {
  159.            PR_ASSERT(err != EINTR);  /* should have been handled above */
  160.            _PR_MD_MAP_SELECT_ERROR(err);
  161.       }
  162.    }
  163.    return n;
  164.  }
  165.  
  166.