1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/src/md/unix/uxpoll.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,676 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#if defined(_PR_PTHREADS) 1.10 + 1.11 +#error "This file should not be compiled" 1.12 + 1.13 +#else /* defined(_PR_PTHREADS) */ 1.14 + 1.15 +#include "primpl.h" 1.16 + 1.17 +#include <sys/time.h> 1.18 + 1.19 +#include <fcntl.h> 1.20 +#ifdef _PR_USE_POLL 1.21 +#include <poll.h> 1.22 +#endif 1.23 + 1.24 +#if defined(_PR_USE_POLL) 1.25 +static PRInt32 NativeThreadPoll( 1.26 + PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) 1.27 +{ 1.28 + /* 1.29 + * This function is mostly duplicated from ptio.s's PR_Poll(). 1.30 + */ 1.31 + PRInt32 ready = 0; 1.32 + /* 1.33 + * For restarting poll() if it is interrupted by a signal. 1.34 + * We use these variables to figure out how much time has 1.35 + * elapsed and how much of the timeout still remains. 1.36 + */ 1.37 + PRIntn index, msecs; 1.38 + struct pollfd *syspoll = NULL; 1.39 + PRIntervalTime start, elapsed, remaining; 1.40 + 1.41 + syspoll = (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd)); 1.42 + if (NULL == syspoll) 1.43 + { 1.44 + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); 1.45 + return -1; 1.46 + } 1.47 + for (index = 0; index < npds; ++index) 1.48 + { 1.49 + PRFileDesc *bottom; 1.50 + PRInt16 in_flags_read = 0, in_flags_write = 0; 1.51 + PRInt16 out_flags_read = 0, out_flags_write = 0; 1.52 + 1.53 + if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) 1.54 + { 1.55 + if (pds[index].in_flags & PR_POLL_READ) 1.56 + { 1.57 + in_flags_read = (pds[index].fd->methods->poll)( 1.58 + pds[index].fd, 1.59 + pds[index].in_flags & ~PR_POLL_WRITE, 1.60 + &out_flags_read); 1.61 + } 1.62 + if (pds[index].in_flags & PR_POLL_WRITE) 1.63 + { 1.64 + in_flags_write = (pds[index].fd->methods->poll)( 1.65 + pds[index].fd, 1.66 + pds[index].in_flags & ~PR_POLL_READ, 1.67 + &out_flags_write); 1.68 + } 1.69 + if ((0 != (in_flags_read & out_flags_read)) 1.70 + || (0 != (in_flags_write & out_flags_write))) 1.71 + { 1.72 + /* this one is ready right now */ 1.73 + if (0 == ready) 1.74 + { 1.75 + /* 1.76 + * We will return without calling the system 1.77 + * poll function. So zero the out_flags 1.78 + * fields of all the poll descriptors before 1.79 + * this one. 1.80 + */ 1.81 + int i; 1.82 + for (i = 0; i < index; i++) 1.83 + { 1.84 + pds[i].out_flags = 0; 1.85 + } 1.86 + } 1.87 + ready += 1; 1.88 + pds[index].out_flags = out_flags_read | out_flags_write; 1.89 + } 1.90 + else 1.91 + { 1.92 + pds[index].out_flags = 0; /* pre-condition */ 1.93 + /* now locate the NSPR layer at the bottom of the stack */ 1.94 + bottom = PR_GetIdentitiesLayer(pds[index].fd, PR_NSPR_IO_LAYER); 1.95 + PR_ASSERT(NULL != bottom); /* what to do about that? */ 1.96 + if ((NULL != bottom) 1.97 + && (_PR_FILEDESC_OPEN == bottom->secret->state)) 1.98 + { 1.99 + if (0 == ready) 1.100 + { 1.101 + syspoll[index].fd = bottom->secret->md.osfd; 1.102 + syspoll[index].events = 0; /* pre-condition */ 1.103 + if (in_flags_read & PR_POLL_READ) 1.104 + { 1.105 + pds[index].out_flags |= 1.106 + _PR_POLL_READ_SYS_READ; 1.107 + syspoll[index].events |= POLLIN; 1.108 + } 1.109 + if (in_flags_read & PR_POLL_WRITE) 1.110 + { 1.111 + pds[index].out_flags |= 1.112 + _PR_POLL_READ_SYS_WRITE; 1.113 + syspoll[index].events |= POLLOUT; 1.114 + } 1.115 + if (in_flags_write & PR_POLL_READ) 1.116 + { 1.117 + pds[index].out_flags |= 1.118 + _PR_POLL_WRITE_SYS_READ; 1.119 + syspoll[index].events |= POLLIN; 1.120 + } 1.121 + if (in_flags_write & PR_POLL_WRITE) 1.122 + { 1.123 + pds[index].out_flags |= 1.124 + _PR_POLL_WRITE_SYS_WRITE; 1.125 + syspoll[index].events |= POLLOUT; 1.126 + } 1.127 + if (pds[index].in_flags & PR_POLL_EXCEPT) 1.128 + syspoll[index].events |= POLLPRI; 1.129 + } 1.130 + } 1.131 + else 1.132 + { 1.133 + if (0 == ready) 1.134 + { 1.135 + int i; 1.136 + for (i = 0; i < index; i++) 1.137 + { 1.138 + pds[i].out_flags = 0; 1.139 + } 1.140 + } 1.141 + ready += 1; /* this will cause an abrupt return */ 1.142 + pds[index].out_flags = PR_POLL_NVAL; /* bogii */ 1.143 + } 1.144 + } 1.145 + } 1.146 + else 1.147 + { 1.148 + /* make poll() ignore this entry */ 1.149 + syspoll[index].fd = -1; 1.150 + syspoll[index].events = 0; 1.151 + pds[index].out_flags = 0; 1.152 + } 1.153 + } 1.154 + 1.155 + if (0 == ready) 1.156 + { 1.157 + switch (timeout) 1.158 + { 1.159 + case PR_INTERVAL_NO_WAIT: msecs = 0; break; 1.160 + case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break; 1.161 + default: 1.162 + msecs = PR_IntervalToMilliseconds(timeout); 1.163 + start = PR_IntervalNow(); 1.164 + } 1.165 + 1.166 +retry: 1.167 + ready = _MD_POLL(syspoll, npds, msecs); 1.168 + if (-1 == ready) 1.169 + { 1.170 + PRIntn oserror = errno; 1.171 + 1.172 + if (EINTR == oserror) 1.173 + { 1.174 + if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry; 1.175 + else if (timeout == PR_INTERVAL_NO_WAIT) ready = 0; 1.176 + else 1.177 + { 1.178 + elapsed = (PRIntervalTime)(PR_IntervalNow() - start); 1.179 + if (elapsed > timeout) ready = 0; /* timed out */ 1.180 + else 1.181 + { 1.182 + remaining = timeout - elapsed; 1.183 + msecs = PR_IntervalToMilliseconds(remaining); 1.184 + goto retry; 1.185 + } 1.186 + } 1.187 + } 1.188 + else _PR_MD_MAP_POLL_ERROR(oserror); 1.189 + } 1.190 + else if (ready > 0) 1.191 + { 1.192 + for (index = 0; index < npds; ++index) 1.193 + { 1.194 + PRInt16 out_flags = 0; 1.195 + if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) 1.196 + { 1.197 + if (0 != syspoll[index].revents) 1.198 + { 1.199 + /* 1.200 + ** Set up the out_flags so that it contains the 1.201 + ** bits that the highest layer thinks are nice 1.202 + ** to have. Then the client of that layer will 1.203 + ** call the appropriate I/O function and maybe 1.204 + ** the protocol will make progress. 1.205 + */ 1.206 + if (syspoll[index].revents & POLLIN) 1.207 + { 1.208 + if (pds[index].out_flags 1.209 + & _PR_POLL_READ_SYS_READ) 1.210 + { 1.211 + out_flags |= PR_POLL_READ; 1.212 + } 1.213 + if (pds[index].out_flags 1.214 + & _PR_POLL_WRITE_SYS_READ) 1.215 + { 1.216 + out_flags |= PR_POLL_WRITE; 1.217 + } 1.218 + } 1.219 + if (syspoll[index].revents & POLLOUT) 1.220 + { 1.221 + if (pds[index].out_flags 1.222 + & _PR_POLL_READ_SYS_WRITE) 1.223 + { 1.224 + out_flags |= PR_POLL_READ; 1.225 + } 1.226 + if (pds[index].out_flags 1.227 + & _PR_POLL_WRITE_SYS_WRITE) 1.228 + { 1.229 + out_flags |= PR_POLL_WRITE; 1.230 + } 1.231 + } 1.232 + if (syspoll[index].revents & POLLPRI) 1.233 + out_flags |= PR_POLL_EXCEPT; 1.234 + if (syspoll[index].revents & POLLERR) 1.235 + out_flags |= PR_POLL_ERR; 1.236 + if (syspoll[index].revents & POLLNVAL) 1.237 + out_flags |= PR_POLL_NVAL; 1.238 + if (syspoll[index].revents & POLLHUP) 1.239 + out_flags |= PR_POLL_HUP; 1.240 + } 1.241 + } 1.242 + pds[index].out_flags = out_flags; 1.243 + } 1.244 + } 1.245 + } 1.246 + 1.247 + PR_DELETE(syspoll); 1.248 + return ready; 1.249 + 1.250 +} /* NativeThreadPoll */ 1.251 +#endif /* defined(_PR_USE_POLL) */ 1.252 + 1.253 +#if !defined(_PR_USE_POLL) 1.254 +static PRInt32 NativeThreadSelect( 1.255 + PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) 1.256 +{ 1.257 + /* 1.258 + * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL(). 1.259 + */ 1.260 + fd_set rd, wt, ex; 1.261 + PRFileDesc *bottom; 1.262 + PRPollDesc *pd, *epd; 1.263 + PRInt32 maxfd = -1, ready, err; 1.264 + PRIntervalTime remaining, elapsed, start; 1.265 + 1.266 + struct timeval tv, *tvp = NULL; 1.267 + 1.268 + FD_ZERO(&rd); 1.269 + FD_ZERO(&wt); 1.270 + FD_ZERO(&ex); 1.271 + 1.272 + ready = 0; 1.273 + for (pd = pds, epd = pd + npds; pd < epd; pd++) 1.274 + { 1.275 + PRInt16 in_flags_read = 0, in_flags_write = 0; 1.276 + PRInt16 out_flags_read = 0, out_flags_write = 0; 1.277 + 1.278 + if ((NULL != pd->fd) && (0 != pd->in_flags)) 1.279 + { 1.280 + if (pd->in_flags & PR_POLL_READ) 1.281 + { 1.282 + in_flags_read = (pd->fd->methods->poll)( 1.283 + pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); 1.284 + } 1.285 + if (pd->in_flags & PR_POLL_WRITE) 1.286 + { 1.287 + in_flags_write = (pd->fd->methods->poll)( 1.288 + pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); 1.289 + } 1.290 + if ((0 != (in_flags_read & out_flags_read)) 1.291 + || (0 != (in_flags_write & out_flags_write))) 1.292 + { 1.293 + /* this one's ready right now */ 1.294 + if (0 == ready) 1.295 + { 1.296 + /* 1.297 + * We will have to return without calling the 1.298 + * system poll/select function. So zero the 1.299 + * out_flags fields of all the poll descriptors 1.300 + * before this one. 1.301 + */ 1.302 + PRPollDesc *prev; 1.303 + for (prev = pds; prev < pd; prev++) 1.304 + { 1.305 + prev->out_flags = 0; 1.306 + } 1.307 + } 1.308 + ready += 1; 1.309 + pd->out_flags = out_flags_read | out_flags_write; 1.310 + } 1.311 + else 1.312 + { 1.313 + pd->out_flags = 0; /* pre-condition */ 1.314 + 1.315 + /* make sure this is an NSPR supported stack */ 1.316 + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); 1.317 + PR_ASSERT(NULL != bottom); /* what to do about that? */ 1.318 + if ((NULL != bottom) 1.319 + && (_PR_FILEDESC_OPEN == bottom->secret->state)) 1.320 + { 1.321 + if (0 == ready) 1.322 + { 1.323 + PRInt32 osfd = bottom->secret->md.osfd; 1.324 + if (osfd > maxfd) maxfd = osfd; 1.325 + if (in_flags_read & PR_POLL_READ) 1.326 + { 1.327 + pd->out_flags |= _PR_POLL_READ_SYS_READ; 1.328 + FD_SET(osfd, &rd); 1.329 + } 1.330 + if (in_flags_read & PR_POLL_WRITE) 1.331 + { 1.332 + pd->out_flags |= _PR_POLL_READ_SYS_WRITE; 1.333 + FD_SET(osfd, &wt); 1.334 + } 1.335 + if (in_flags_write & PR_POLL_READ) 1.336 + { 1.337 + pd->out_flags |= _PR_POLL_WRITE_SYS_READ; 1.338 + FD_SET(osfd, &rd); 1.339 + } 1.340 + if (in_flags_write & PR_POLL_WRITE) 1.341 + { 1.342 + pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; 1.343 + FD_SET(osfd, &wt); 1.344 + } 1.345 + if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex); 1.346 + } 1.347 + } 1.348 + else 1.349 + { 1.350 + if (0 == ready) 1.351 + { 1.352 + PRPollDesc *prev; 1.353 + for (prev = pds; prev < pd; prev++) 1.354 + { 1.355 + prev->out_flags = 0; 1.356 + } 1.357 + } 1.358 + ready += 1; /* this will cause an abrupt return */ 1.359 + pd->out_flags = PR_POLL_NVAL; /* bogii */ 1.360 + } 1.361 + } 1.362 + } 1.363 + else 1.364 + { 1.365 + pd->out_flags = 0; 1.366 + } 1.367 + } 1.368 + 1.369 + if (0 != ready) return ready; /* no need to block */ 1.370 + 1.371 + remaining = timeout; 1.372 + start = PR_IntervalNow(); 1.373 + 1.374 +retry: 1.375 + if (timeout != PR_INTERVAL_NO_TIMEOUT) 1.376 + { 1.377 + PRInt32 ticksPerSecond = PR_TicksPerSecond(); 1.378 + tv.tv_sec = remaining / ticksPerSecond; 1.379 + tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond ); 1.380 + tvp = &tv; 1.381 + } 1.382 + 1.383 + ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp); 1.384 + 1.385 + if (ready == -1 && errno == EINTR) 1.386 + { 1.387 + if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry; 1.388 + else 1.389 + { 1.390 + elapsed = (PRIntervalTime) (PR_IntervalNow() - start); 1.391 + if (elapsed > timeout) ready = 0; /* timed out */ 1.392 + else 1.393 + { 1.394 + remaining = timeout - elapsed; 1.395 + goto retry; 1.396 + } 1.397 + } 1.398 + } 1.399 + 1.400 + /* 1.401 + ** Now to unravel the select sets back into the client's poll 1.402 + ** descriptor list. Is this possibly an area for pissing away 1.403 + ** a few cycles or what? 1.404 + */ 1.405 + if (ready > 0) 1.406 + { 1.407 + ready = 0; 1.408 + for (pd = pds, epd = pd + npds; pd < epd; pd++) 1.409 + { 1.410 + PRInt16 out_flags = 0; 1.411 + if ((NULL != pd->fd) && (0 != pd->in_flags)) 1.412 + { 1.413 + PRInt32 osfd; 1.414 + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); 1.415 + PR_ASSERT(NULL != bottom); 1.416 + 1.417 + osfd = bottom->secret->md.osfd; 1.418 + 1.419 + if (FD_ISSET(osfd, &rd)) 1.420 + { 1.421 + if (pd->out_flags & _PR_POLL_READ_SYS_READ) 1.422 + out_flags |= PR_POLL_READ; 1.423 + if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) 1.424 + out_flags |= PR_POLL_WRITE; 1.425 + } 1.426 + if (FD_ISSET(osfd, &wt)) 1.427 + { 1.428 + if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) 1.429 + out_flags |= PR_POLL_READ; 1.430 + if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) 1.431 + out_flags |= PR_POLL_WRITE; 1.432 + } 1.433 + if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT; 1.434 + } 1.435 + pd->out_flags = out_flags; 1.436 + if (out_flags) ready++; 1.437 + } 1.438 + PR_ASSERT(ready > 0); 1.439 + } 1.440 + else if (ready < 0) 1.441 + { 1.442 + err = _MD_ERRNO(); 1.443 + if (err == EBADF) 1.444 + { 1.445 + /* Find the bad fds */ 1.446 + ready = 0; 1.447 + for (pd = pds, epd = pd + npds; pd < epd; pd++) 1.448 + { 1.449 + pd->out_flags = 0; 1.450 + if ((NULL != pd->fd) && (0 != pd->in_flags)) 1.451 + { 1.452 + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); 1.453 + if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1) 1.454 + { 1.455 + pd->out_flags = PR_POLL_NVAL; 1.456 + ready++; 1.457 + } 1.458 + } 1.459 + } 1.460 + PR_ASSERT(ready > 0); 1.461 + } 1.462 + else _PR_MD_MAP_SELECT_ERROR(err); 1.463 + } 1.464 + 1.465 + return ready; 1.466 +} /* NativeThreadSelect */ 1.467 +#endif /* !defined(_PR_USE_POLL) */ 1.468 + 1.469 +static PRInt32 LocalThreads( 1.470 + PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) 1.471 +{ 1.472 + PRPollDesc *pd, *epd; 1.473 + PRInt32 ready, pdcnt; 1.474 + _PRUnixPollDesc *unixpds, *unixpd; 1.475 + 1.476 + /* 1.477 + * XXX 1.478 + * PRPollDesc has a PRFileDesc field, fd, while the IOQ 1.479 + * is a list of PRPollQueue structures, each of which contains 1.480 + * a _PRUnixPollDesc. A _PRUnixPollDesc struct contains 1.481 + * the OS file descriptor, osfd, and not a PRFileDesc. 1.482 + * So, we have allocate memory for _PRUnixPollDesc structures, 1.483 + * copy the flags information from the pds list and have pq 1.484 + * point to this list of _PRUnixPollDesc structures. 1.485 + * 1.486 + * It would be better if the memory allocation can be avoided. 1.487 + */ 1.488 + 1.489 + unixpd = unixpds = (_PRUnixPollDesc*) 1.490 + PR_MALLOC(npds * sizeof(_PRUnixPollDesc)); 1.491 + if (NULL == unixpds) 1.492 + { 1.493 + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); 1.494 + return -1; 1.495 + } 1.496 + 1.497 + ready = 0; 1.498 + for (pdcnt = 0, pd = pds, epd = pd + npds; pd < epd; pd++) 1.499 + { 1.500 + PRFileDesc *bottom; 1.501 + PRInt16 in_flags_read = 0, in_flags_write = 0; 1.502 + PRInt16 out_flags_read = 0, out_flags_write = 0; 1.503 + 1.504 + if ((NULL != pd->fd) && (0 != pd->in_flags)) 1.505 + { 1.506 + if (pd->in_flags & PR_POLL_READ) 1.507 + { 1.508 + in_flags_read = (pd->fd->methods->poll)( 1.509 + pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); 1.510 + } 1.511 + if (pd->in_flags & PR_POLL_WRITE) 1.512 + { 1.513 + in_flags_write = (pd->fd->methods->poll)( 1.514 + pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); 1.515 + } 1.516 + if ((0 != (in_flags_read & out_flags_read)) 1.517 + || (0 != (in_flags_write & out_flags_write))) 1.518 + { 1.519 + /* this one's ready right now */ 1.520 + if (0 == ready) 1.521 + { 1.522 + /* 1.523 + * We will have to return without calling the 1.524 + * system poll/select function. So zero the 1.525 + * out_flags fields of all the poll descriptors 1.526 + * before this one. 1.527 + */ 1.528 + PRPollDesc *prev; 1.529 + for (prev = pds; prev < pd; prev++) 1.530 + { 1.531 + prev->out_flags = 0; 1.532 + } 1.533 + } 1.534 + ready += 1; 1.535 + pd->out_flags = out_flags_read | out_flags_write; 1.536 + } 1.537 + else 1.538 + { 1.539 + pd->out_flags = 0; /* pre-condition */ 1.540 + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); 1.541 + PR_ASSERT(NULL != bottom); /* what to do about that? */ 1.542 + if ((NULL != bottom) 1.543 + && (_PR_FILEDESC_OPEN == bottom->secret->state)) 1.544 + { 1.545 + if (0 == ready) 1.546 + { 1.547 + unixpd->osfd = bottom->secret->md.osfd; 1.548 + unixpd->in_flags = 0; 1.549 + if (in_flags_read & PR_POLL_READ) 1.550 + { 1.551 + unixpd->in_flags |= _PR_UNIX_POLL_READ; 1.552 + pd->out_flags |= _PR_POLL_READ_SYS_READ; 1.553 + } 1.554 + if (in_flags_read & PR_POLL_WRITE) 1.555 + { 1.556 + unixpd->in_flags |= _PR_UNIX_POLL_WRITE; 1.557 + pd->out_flags |= _PR_POLL_READ_SYS_WRITE; 1.558 + } 1.559 + if (in_flags_write & PR_POLL_READ) 1.560 + { 1.561 + unixpd->in_flags |= _PR_UNIX_POLL_READ; 1.562 + pd->out_flags |= _PR_POLL_WRITE_SYS_READ; 1.563 + } 1.564 + if (in_flags_write & PR_POLL_WRITE) 1.565 + { 1.566 + unixpd->in_flags |= _PR_UNIX_POLL_WRITE; 1.567 + pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; 1.568 + } 1.569 + if ((in_flags_read | in_flags_write) & PR_POLL_EXCEPT) 1.570 + { 1.571 + unixpd->in_flags |= _PR_UNIX_POLL_EXCEPT; 1.572 + } 1.573 + unixpd++; pdcnt++; 1.574 + } 1.575 + } 1.576 + else 1.577 + { 1.578 + if (0 == ready) 1.579 + { 1.580 + PRPollDesc *prev; 1.581 + for (prev = pds; prev < pd; prev++) 1.582 + { 1.583 + prev->out_flags = 0; 1.584 + } 1.585 + } 1.586 + ready += 1; /* this will cause an abrupt return */ 1.587 + pd->out_flags = PR_POLL_NVAL; /* bogii */ 1.588 + } 1.589 + } 1.590 + } 1.591 + } 1.592 + 1.593 + if (0 != ready) 1.594 + { 1.595 + /* no need to block */ 1.596 + PR_DELETE(unixpds); 1.597 + return ready; 1.598 + } 1.599 + 1.600 + ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout); 1.601 + 1.602 + /* 1.603 + * Copy the out_flags from the _PRUnixPollDesc structures to the 1.604 + * user's PRPollDesc structures and free the allocated memory 1.605 + */ 1.606 + unixpd = unixpds; 1.607 + for (pd = pds, epd = pd + npds; pd < epd; pd++) 1.608 + { 1.609 + PRInt16 out_flags = 0; 1.610 + if ((NULL != pd->fd) && (0 != pd->in_flags)) 1.611 + { 1.612 + /* 1.613 + * take errors from the poll operation, 1.614 + * the R/W bits from the request 1.615 + */ 1.616 + if (0 != unixpd->out_flags) 1.617 + { 1.618 + if (unixpd->out_flags & _PR_UNIX_POLL_READ) 1.619 + { 1.620 + if (pd->out_flags & _PR_POLL_READ_SYS_READ) 1.621 + out_flags |= PR_POLL_READ; 1.622 + if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) 1.623 + out_flags |= PR_POLL_WRITE; 1.624 + } 1.625 + if (unixpd->out_flags & _PR_UNIX_POLL_WRITE) 1.626 + { 1.627 + if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) 1.628 + out_flags |= PR_POLL_READ; 1.629 + if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) 1.630 + out_flags |= PR_POLL_WRITE; 1.631 + } 1.632 + if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT) 1.633 + out_flags |= PR_POLL_EXCEPT; 1.634 + if (unixpd->out_flags & _PR_UNIX_POLL_ERR) 1.635 + out_flags |= PR_POLL_ERR; 1.636 + if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) 1.637 + out_flags |= PR_POLL_NVAL; 1.638 + if (unixpd->out_flags & _PR_UNIX_POLL_HUP) 1.639 + out_flags |= PR_POLL_HUP; 1.640 + } 1.641 + unixpd++; 1.642 + } 1.643 + pd->out_flags = out_flags; 1.644 + } 1.645 + 1.646 + PR_DELETE(unixpds); 1.647 + 1.648 + return ready; 1.649 +} /* LocalThreads */ 1.650 + 1.651 +#if defined(_PR_USE_POLL) 1.652 +#define NativeThreads NativeThreadPoll 1.653 +#else 1.654 +#define NativeThreads NativeThreadSelect 1.655 +#endif 1.656 + 1.657 +PRInt32 _MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) 1.658 +{ 1.659 + PRInt32 rv = 0; 1.660 + PRThread *me = _PR_MD_CURRENT_THREAD(); 1.661 + 1.662 + if (_PR_PENDING_INTERRUPT(me)) 1.663 + { 1.664 + me->flags &= ~_PR_INTERRUPT; 1.665 + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); 1.666 + return -1; 1.667 + } 1.668 + if (0 == npds) PR_Sleep(timeout); 1.669 + else if (_PR_IS_NATIVE_THREAD(me)) 1.670 + rv = NativeThreads(pds, npds, timeout); 1.671 + else rv = LocalThreads(pds, npds, timeout); 1.672 + 1.673 + return rv; 1.674 +} /* _MD_pr_poll */ 1.675 + 1.676 +#endif /* defined(_PR_PTHREADS) */ 1.677 + 1.678 +/* uxpoll.c */ 1.679 +