nsprpub/pr/src/md/unix/uxpoll.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #if defined(_PR_PTHREADS)
     8 #error "This file should not be compiled"
    10 #else  /* defined(_PR_PTHREADS) */
    12 #include "primpl.h"
    14 #include <sys/time.h>
    16 #include <fcntl.h>
    17 #ifdef _PR_USE_POLL
    18 #include <poll.h>
    19 #endif
    21 #if defined(_PR_USE_POLL)
    22 static PRInt32 NativeThreadPoll(
    23     PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
    24 {
    25     /*
    26      * This function is mostly duplicated from ptio.s's PR_Poll().
    27      */
    28     PRInt32 ready = 0;
    29     /*
    30      * For restarting poll() if it is interrupted by a signal.
    31      * We use these variables to figure out how much time has
    32      * elapsed and how much of the timeout still remains.
    33      */
    34     PRIntn index, msecs;
    35     struct pollfd *syspoll = NULL;
    36     PRIntervalTime start, elapsed, remaining;
    38     syspoll = (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd));
    39     if (NULL == syspoll)
    40     {
    41         PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
    42         return -1;
    43     }
    44     for (index = 0; index < npds; ++index)
    45     {
    46         PRFileDesc *bottom;
    47         PRInt16 in_flags_read = 0, in_flags_write = 0;
    48         PRInt16 out_flags_read = 0, out_flags_write = 0;
    50         if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
    51         {
    52             if (pds[index].in_flags & PR_POLL_READ)
    53             {
    54                 in_flags_read = (pds[index].fd->methods->poll)(
    55                     pds[index].fd,
    56                     pds[index].in_flags & ~PR_POLL_WRITE,
    57                     &out_flags_read);
    58             }
    59             if (pds[index].in_flags & PR_POLL_WRITE)
    60             {
    61                 in_flags_write = (pds[index].fd->methods->poll)(
    62                     pds[index].fd,
    63                     pds[index].in_flags & ~PR_POLL_READ,
    64                     &out_flags_write);
    65             }
    66             if ((0 != (in_flags_read & out_flags_read))
    67             || (0 != (in_flags_write & out_flags_write)))
    68             {
    69                 /* this one is ready right now */
    70                 if (0 == ready)
    71                 {
    72                     /*
    73                      * We will return without calling the system
    74                      * poll function.  So zero the out_flags
    75                      * fields of all the poll descriptors before
    76                      * this one.
    77                      */
    78                     int i;
    79                     for (i = 0; i < index; i++)
    80                     {
    81                         pds[i].out_flags = 0;
    82                     }
    83                 }
    84                 ready += 1;
    85                 pds[index].out_flags = out_flags_read | out_flags_write;
    86             }
    87             else
    88             {
    89                 pds[index].out_flags = 0;  /* pre-condition */
    90                 /* now locate the NSPR layer at the bottom of the stack */
    91                 bottom = PR_GetIdentitiesLayer(pds[index].fd, PR_NSPR_IO_LAYER);
    92                 PR_ASSERT(NULL != bottom);  /* what to do about that? */
    93                 if ((NULL != bottom)
    94                 && (_PR_FILEDESC_OPEN == bottom->secret->state))
    95                 {
    96                     if (0 == ready)
    97                     {
    98                         syspoll[index].fd = bottom->secret->md.osfd;
    99                         syspoll[index].events = 0;  /* pre-condition */
   100                         if (in_flags_read & PR_POLL_READ)
   101                         {
   102                             pds[index].out_flags |=
   103                                 _PR_POLL_READ_SYS_READ;
   104                             syspoll[index].events |= POLLIN;
   105                         }
   106                         if (in_flags_read & PR_POLL_WRITE)
   107                         {
   108                             pds[index].out_flags |=
   109                                 _PR_POLL_READ_SYS_WRITE;
   110                             syspoll[index].events |= POLLOUT;
   111                         }
   112                         if (in_flags_write & PR_POLL_READ)
   113                         {
   114                             pds[index].out_flags |=
   115                                 _PR_POLL_WRITE_SYS_READ;
   116                             syspoll[index].events |= POLLIN;
   117                         }
   118                         if (in_flags_write & PR_POLL_WRITE)
   119                         {
   120                             pds[index].out_flags |=
   121                                 _PR_POLL_WRITE_SYS_WRITE;
   122                             syspoll[index].events |= POLLOUT;
   123                         }
   124                         if (pds[index].in_flags & PR_POLL_EXCEPT)
   125                             syspoll[index].events |= POLLPRI;
   126                     }
   127                 }
   128                 else
   129                 {
   130                     if (0 == ready)
   131                     {
   132                         int i;
   133                         for (i = 0; i < index; i++)
   134                         {
   135                             pds[i].out_flags = 0;
   136                         }
   137                     }
   138                     ready += 1;  /* this will cause an abrupt return */
   139                     pds[index].out_flags = PR_POLL_NVAL;  /* bogii */
   140                 }
   141             }
   142         }
   143         else
   144         {
   145             /* make poll() ignore this entry */
   146             syspoll[index].fd = -1;
   147             syspoll[index].events = 0;
   148             pds[index].out_flags = 0;
   149         }
   150     }
   152     if (0 == ready)
   153     {
   154         switch (timeout)
   155         {
   156             case PR_INTERVAL_NO_WAIT: msecs = 0; break;
   157             case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break;
   158             default:
   159                 msecs = PR_IntervalToMilliseconds(timeout);
   160                 start = PR_IntervalNow();
   161         }
   163 retry:
   164         ready = _MD_POLL(syspoll, npds, msecs);
   165         if (-1 == ready)
   166         {
   167             PRIntn oserror = errno;
   169             if (EINTR == oserror)
   170             {
   171                 if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
   172                 else if (timeout == PR_INTERVAL_NO_WAIT) ready = 0;
   173                 else
   174                 {
   175                     elapsed = (PRIntervalTime)(PR_IntervalNow() - start);
   176                     if (elapsed > timeout) ready = 0;  /* timed out */
   177                     else
   178                     {
   179                         remaining = timeout - elapsed;
   180                         msecs = PR_IntervalToMilliseconds(remaining);
   181                         goto retry;
   182                     }
   183                 }
   184             }
   185             else _PR_MD_MAP_POLL_ERROR(oserror);
   186         }
   187         else if (ready > 0)
   188         {
   189             for (index = 0; index < npds; ++index)
   190             {
   191                 PRInt16 out_flags = 0;
   192                 if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
   193                 {
   194                     if (0 != syspoll[index].revents)
   195                     {
   196                         /*
   197                         ** Set up the out_flags so that it contains the
   198                         ** bits that the highest layer thinks are nice
   199                         ** to have. Then the client of that layer will
   200                         ** call the appropriate I/O function and maybe
   201                         ** the protocol will make progress.
   202                         */
   203                         if (syspoll[index].revents & POLLIN)
   204                         {
   205                             if (pds[index].out_flags
   206                             & _PR_POLL_READ_SYS_READ)
   207                             {
   208                                 out_flags |= PR_POLL_READ;
   209                             }
   210                             if (pds[index].out_flags
   211                             & _PR_POLL_WRITE_SYS_READ)
   212                             {
   213                                 out_flags |= PR_POLL_WRITE;
   214                             }
   215                         }
   216                         if (syspoll[index].revents & POLLOUT)
   217                         {
   218                             if (pds[index].out_flags
   219                             & _PR_POLL_READ_SYS_WRITE)
   220                             {
   221                                 out_flags |= PR_POLL_READ;
   222                             }
   223                             if (pds[index].out_flags
   224                             & _PR_POLL_WRITE_SYS_WRITE)
   225                             {
   226                                 out_flags |= PR_POLL_WRITE;
   227                             }
   228                         }
   229                         if (syspoll[index].revents & POLLPRI)
   230                             out_flags |= PR_POLL_EXCEPT;
   231                         if (syspoll[index].revents & POLLERR)
   232                             out_flags |= PR_POLL_ERR;
   233                         if (syspoll[index].revents & POLLNVAL)
   234                             out_flags |= PR_POLL_NVAL;
   235                         if (syspoll[index].revents & POLLHUP)
   236                             out_flags |= PR_POLL_HUP;
   237                     }
   238                 }
   239                 pds[index].out_flags = out_flags;
   240             }
   241         }
   242     }
   244     PR_DELETE(syspoll);
   245     return ready;
   247 }  /* NativeThreadPoll */
   248 #endif  /* defined(_PR_USE_POLL) */
   250 #if !defined(_PR_USE_POLL)
   251 static PRInt32 NativeThreadSelect(
   252     PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
   253 {
   254     /*
   255      * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL().
   256      */
   257     fd_set rd, wt, ex;
   258     PRFileDesc *bottom;
   259     PRPollDesc *pd, *epd;
   260     PRInt32 maxfd = -1, ready, err;
   261     PRIntervalTime remaining, elapsed, start;
   263     struct timeval tv, *tvp = NULL;
   265     FD_ZERO(&rd);
   266     FD_ZERO(&wt);
   267     FD_ZERO(&ex);
   269     ready = 0;
   270     for (pd = pds, epd = pd + npds; pd < epd; pd++)
   271     {
   272         PRInt16 in_flags_read = 0, in_flags_write = 0;
   273         PRInt16 out_flags_read = 0, out_flags_write = 0;
   275         if ((NULL != pd->fd) && (0 != pd->in_flags))
   276         {
   277             if (pd->in_flags & PR_POLL_READ)
   278             {
   279                 in_flags_read = (pd->fd->methods->poll)(
   280                     pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
   281             }
   282             if (pd->in_flags & PR_POLL_WRITE)
   283             {
   284                 in_flags_write = (pd->fd->methods->poll)(
   285                     pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
   286             }
   287             if ((0 != (in_flags_read & out_flags_read))
   288             || (0 != (in_flags_write & out_flags_write)))
   289             {
   290                 /* this one's ready right now */
   291                 if (0 == ready)
   292                 {
   293                     /*
   294                      * We will have to return without calling the
   295                      * system poll/select function.  So zero the
   296                      * out_flags fields of all the poll descriptors
   297                      * before this one.
   298                      */
   299                     PRPollDesc *prev;
   300                     for (prev = pds; prev < pd; prev++)
   301                     {
   302                         prev->out_flags = 0;
   303                     }
   304                 }
   305                 ready += 1;
   306                 pd->out_flags = out_flags_read | out_flags_write;
   307             }
   308             else
   309             {
   310                 pd->out_flags = 0;  /* pre-condition */
   312                 /* make sure this is an NSPR supported stack */
   313                 bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
   314                 PR_ASSERT(NULL != bottom);  /* what to do about that? */
   315                 if ((NULL != bottom)
   316                 && (_PR_FILEDESC_OPEN == bottom->secret->state))
   317                 {
   318                     if (0 == ready)
   319                     {
   320                         PRInt32 osfd = bottom->secret->md.osfd;
   321                         if (osfd > maxfd) maxfd = osfd;
   322                         if (in_flags_read & PR_POLL_READ)
   323                         {
   324                             pd->out_flags |= _PR_POLL_READ_SYS_READ;
   325                             FD_SET(osfd, &rd);
   326                         }
   327                         if (in_flags_read & PR_POLL_WRITE)
   328                         {
   329                             pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
   330                             FD_SET(osfd, &wt);
   331                         }
   332                         if (in_flags_write & PR_POLL_READ)
   333                         {
   334                             pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
   335                             FD_SET(osfd, &rd);
   336                         }
   337                         if (in_flags_write & PR_POLL_WRITE)
   338                         {
   339                             pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
   340                             FD_SET(osfd, &wt);
   341                         }
   342                         if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex);
   343                     }
   344                 }
   345                 else
   346                 {
   347                     if (0 == ready)
   348                     {
   349                         PRPollDesc *prev;
   350                         for (prev = pds; prev < pd; prev++)
   351                         {
   352                             prev->out_flags = 0;
   353                         }
   354                     }
   355                     ready += 1;  /* this will cause an abrupt return */
   356                     pd->out_flags = PR_POLL_NVAL;  /* bogii */
   357                 }
   358             }
   359         }
   360         else
   361         {
   362             pd->out_flags = 0;
   363         }
   364     }
   366     if (0 != ready) return ready;  /* no need to block */
   368     remaining = timeout;
   369     start = PR_IntervalNow();
   371 retry:
   372     if (timeout != PR_INTERVAL_NO_TIMEOUT)
   373     {
   374         PRInt32 ticksPerSecond = PR_TicksPerSecond();
   375         tv.tv_sec = remaining / ticksPerSecond;
   376         tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond );
   377         tvp = &tv;
   378     }
   380     ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp);
   382     if (ready == -1 && errno == EINTR)
   383     {
   384         if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
   385         else
   386         {
   387             elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
   388             if (elapsed > timeout) ready = 0;  /* timed out */
   389             else
   390             {
   391                 remaining = timeout - elapsed;
   392                 goto retry;
   393             }
   394         }
   395     }
   397     /*
   398     ** Now to unravel the select sets back into the client's poll
   399     ** descriptor list. Is this possibly an area for pissing away
   400     ** a few cycles or what?
   401     */
   402     if (ready > 0)
   403     {
   404         ready = 0;
   405         for (pd = pds, epd = pd + npds; pd < epd; pd++)
   406         {
   407             PRInt16 out_flags = 0;
   408             if ((NULL != pd->fd) && (0 != pd->in_flags))
   409             {
   410                 PRInt32 osfd;
   411                 bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
   412                 PR_ASSERT(NULL != bottom);
   414                 osfd = bottom->secret->md.osfd;
   416                 if (FD_ISSET(osfd, &rd))
   417                 {
   418                     if (pd->out_flags & _PR_POLL_READ_SYS_READ)
   419                         out_flags |= PR_POLL_READ;
   420                     if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
   421                         out_flags |= PR_POLL_WRITE;
   422                 } 
   423                 if (FD_ISSET(osfd, &wt))
   424                 {
   425                     if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
   426                         out_flags |= PR_POLL_READ;
   427                     if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
   428                         out_flags |= PR_POLL_WRITE;
   429                 } 
   430                 if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;
   431             }
   432             pd->out_flags = out_flags;
   433             if (out_flags) ready++;
   434         }
   435         PR_ASSERT(ready > 0);
   436     }
   437     else if (ready < 0)
   438     {
   439         err = _MD_ERRNO();
   440         if (err == EBADF)
   441         {
   442             /* Find the bad fds */
   443             ready = 0;
   444             for (pd = pds, epd = pd + npds; pd < epd; pd++)
   445             {
   446                 pd->out_flags = 0;
   447                 if ((NULL != pd->fd) && (0 != pd->in_flags))
   448                 {
   449                     bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
   450                     if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1)
   451                     {
   452                         pd->out_flags = PR_POLL_NVAL;
   453                         ready++;
   454                     }
   455                 }
   456             }
   457             PR_ASSERT(ready > 0);
   458         }
   459         else _PR_MD_MAP_SELECT_ERROR(err);
   460     }
   462     return ready;
   463 }  /* NativeThreadSelect */
   464 #endif  /* !defined(_PR_USE_POLL) */
   466 static PRInt32 LocalThreads(
   467     PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
   468 {
   469     PRPollDesc *pd, *epd;
   470     PRInt32 ready, pdcnt;
   471     _PRUnixPollDesc *unixpds, *unixpd;
   473     /*
   474      * XXX
   475      *        PRPollDesc has a PRFileDesc field, fd, while the IOQ
   476      *        is a list of PRPollQueue structures, each of which contains
   477      *        a _PRUnixPollDesc. A _PRUnixPollDesc struct contains
   478      *        the OS file descriptor, osfd, and not a PRFileDesc.
   479      *        So, we have allocate memory for _PRUnixPollDesc structures,
   480      *        copy the flags information from the pds list and have pq
   481      *        point to this list of _PRUnixPollDesc structures.
   482      *
   483      *        It would be better if the memory allocation can be avoided.
   484      */
   486     unixpd = unixpds = (_PRUnixPollDesc*)
   487         PR_MALLOC(npds * sizeof(_PRUnixPollDesc));
   488     if (NULL == unixpds)
   489     {
   490         PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
   491         return -1;
   492     }
   494     ready = 0;
   495     for (pdcnt = 0, pd = pds, epd = pd + npds; pd < epd; pd++)
   496     {
   497         PRFileDesc *bottom;
   498         PRInt16 in_flags_read = 0, in_flags_write = 0;
   499         PRInt16 out_flags_read = 0, out_flags_write = 0;
   501         if ((NULL != pd->fd) && (0 != pd->in_flags))
   502         {
   503             if (pd->in_flags & PR_POLL_READ)
   504             {
   505                 in_flags_read = (pd->fd->methods->poll)(
   506                     pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
   507             }
   508             if (pd->in_flags & PR_POLL_WRITE)
   509             {
   510                 in_flags_write = (pd->fd->methods->poll)(
   511                     pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
   512             }
   513             if ((0 != (in_flags_read & out_flags_read))
   514             || (0 != (in_flags_write & out_flags_write)))
   515             {
   516                 /* this one's ready right now */
   517                 if (0 == ready)
   518                 {
   519                     /*
   520                      * We will have to return without calling the
   521                      * system poll/select function.  So zero the
   522                      * out_flags fields of all the poll descriptors
   523                      * before this one.
   524                      */
   525                     PRPollDesc *prev;
   526                     for (prev = pds; prev < pd; prev++)
   527                     {
   528                         prev->out_flags = 0;
   529                     }
   530                 }
   531                 ready += 1;
   532                 pd->out_flags = out_flags_read | out_flags_write;
   533             }
   534             else
   535             {
   536                 pd->out_flags = 0;  /* pre-condition */
   537                 bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
   538                 PR_ASSERT(NULL != bottom);  /* what to do about that? */
   539                 if ((NULL != bottom)
   540                 && (_PR_FILEDESC_OPEN == bottom->secret->state))
   541                 {
   542                     if (0 == ready)
   543                     {
   544                         unixpd->osfd = bottom->secret->md.osfd;
   545                         unixpd->in_flags = 0;
   546                         if (in_flags_read & PR_POLL_READ)
   547                         {
   548                             unixpd->in_flags |= _PR_UNIX_POLL_READ;
   549                             pd->out_flags |= _PR_POLL_READ_SYS_READ;
   550                         }
   551                         if (in_flags_read & PR_POLL_WRITE)
   552                         {
   553                             unixpd->in_flags |= _PR_UNIX_POLL_WRITE;
   554                             pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
   555                         }
   556                         if (in_flags_write & PR_POLL_READ)
   557                         {
   558                             unixpd->in_flags |= _PR_UNIX_POLL_READ;
   559                             pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
   560                         }
   561                         if (in_flags_write & PR_POLL_WRITE)
   562                         {
   563                             unixpd->in_flags |= _PR_UNIX_POLL_WRITE;
   564                             pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
   565                         }
   566                         if ((in_flags_read | in_flags_write) & PR_POLL_EXCEPT)
   567                         {
   568                             unixpd->in_flags |= _PR_UNIX_POLL_EXCEPT;
   569                         }
   570                         unixpd++; pdcnt++;
   571                     }
   572                 }
   573                 else
   574                 {
   575                     if (0 == ready)
   576                     {
   577                         PRPollDesc *prev;
   578                         for (prev = pds; prev < pd; prev++)
   579                         {
   580                             prev->out_flags = 0;
   581                         }
   582                     }
   583                     ready += 1;  /* this will cause an abrupt return */
   584                     pd->out_flags = PR_POLL_NVAL;  /* bogii */
   585                 }
   586             }
   587         }
   588     }
   590     if (0 != ready)
   591     {
   592         /* no need to block */
   593         PR_DELETE(unixpds);
   594         return ready;
   595     }
   597     ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout);
   599     /*
   600      * Copy the out_flags from the _PRUnixPollDesc structures to the
   601      * user's PRPollDesc structures and free the allocated memory
   602      */
   603     unixpd = unixpds;
   604     for (pd = pds, epd = pd + npds; pd < epd; pd++)
   605     {
   606         PRInt16 out_flags = 0;
   607         if ((NULL != pd->fd) && (0 != pd->in_flags))
   608         {
   609             /*
   610              * take errors from the poll operation,
   611              * the R/W bits from the request
   612              */
   613             if (0 != unixpd->out_flags)
   614             {
   615                 if (unixpd->out_flags & _PR_UNIX_POLL_READ)
   616                 {
   617                     if (pd->out_flags & _PR_POLL_READ_SYS_READ)
   618                         out_flags |= PR_POLL_READ;
   619                     if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
   620                         out_flags |= PR_POLL_WRITE;
   621                 }
   622                 if (unixpd->out_flags & _PR_UNIX_POLL_WRITE)
   623                 {
   624                     if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
   625                         out_flags |= PR_POLL_READ;
   626                     if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
   627                         out_flags |= PR_POLL_WRITE;
   628                 }
   629                 if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT)
   630                     out_flags |= PR_POLL_EXCEPT;
   631                 if (unixpd->out_flags & _PR_UNIX_POLL_ERR)
   632                     out_flags |= PR_POLL_ERR;
   633                 if (unixpd->out_flags & _PR_UNIX_POLL_NVAL)
   634                     out_flags |= PR_POLL_NVAL;
   635                 if (unixpd->out_flags & _PR_UNIX_POLL_HUP)
   636                     out_flags |= PR_POLL_HUP;
   637             }
   638             unixpd++;
   639         }
   640         pd->out_flags = out_flags;
   641     }
   643     PR_DELETE(unixpds);
   645     return ready;
   646 }  /* LocalThreads */
   648 #if defined(_PR_USE_POLL)
   649 #define NativeThreads NativeThreadPoll
   650 #else
   651 #define NativeThreads NativeThreadSelect
   652 #endif
   654 PRInt32 _MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
   655 {
   656     PRInt32 rv = 0;
   657     PRThread *me = _PR_MD_CURRENT_THREAD();
   659     if (_PR_PENDING_INTERRUPT(me))
   660     {
   661         me->flags &= ~_PR_INTERRUPT;
   662         PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
   663         return -1;
   664     }
   665     if (0 == npds) PR_Sleep(timeout);
   666     else if (_PR_IS_NATIVE_THREAD(me))
   667         rv = NativeThreads(pds, npds, timeout);
   668     else rv = LocalThreads(pds, npds, timeout);
   670     return rv;
   671 }  /* _MD_pr_poll */
   673 #endif  /* defined(_PR_PTHREADS) */               
   675 /* uxpoll.c */

mercurial