Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: nspr/pr/src/md/unix/uxwrap.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nspr/pr/src/md/unix/uxshm.c ('k') | nspr/pr/src/md/windows/ntgc.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/. */
5
6 /*
7 *------------------------------------------------------------------------
8 * File: uxwrap.c
9 *
10 * Our wrapped versions of the Unix select() and poll() system calls.
11 *
12 *------------------------------------------------------------------------
13 */
14
15 #include "primpl.h"
16
17 #if defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) || defined(QNX)
18 /* Do not wrap select() and poll(). */
19 #else /* defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) */
20 /* The include files for select() */
21 #ifdef IRIX
22 #include <unistd.h>
23 #include <bstring.h>
24 #endif
25
26 #include <string.h>
27 #include <sys/types.h>
28 #include <sys/time.h>
29
30 #define ZAP_SET(_to, _width) \
31 PR_BEGIN_MACRO \
32 memset(_to, 0, \
33 ((_width + 8*sizeof(int)-1) / (8*sizeof(int))) \
34 * sizeof(int) \
35 ); \
36 PR_END_MACRO
37
38 /* see comments in ns/cmd/xfe/mozilla.c (look for "PR_XGetXtHackFD") */
39 static int _pr_xt_hack_fd = -1;
40
41 int PR_XGetXtHackFD(void)
42 {
43 int fds[2];
44
45 if (_pr_xt_hack_fd == -1) {
46 if (!pipe(fds)) {
47 _pr_xt_hack_fd = fds[0];
48 }
49 }
50 return _pr_xt_hack_fd;
51 }
52
53 static int (*_pr_xt_hack_okayToReleaseXLock)(void) = 0;
54
55 void PR_SetXtHackOkayToReleaseXLockFn(int (*fn)(void))
56 {
57 _pr_xt_hack_okayToReleaseXLock = fn;
58 }
59
60
61 /*
62 *-----------------------------------------------------------------------
63 * select() --
64 *
65 * Wrap up the select system call so that we can deschedule
66 * a thread that tries to wait for i/o.
67 *
68 *-----------------------------------------------------------------------
69 */
70
71 #if defined(HPUX9)
72 int select(size_t width, int *rl, int *wl, int *el, const struct timeval *tv)
73 #elif defined(AIX_RENAME_SELECT)
74 int wrap_select(unsigned long width, void *rl, void *wl, void *el,
75 struct timeval *tv)
76 #elif defined(_PR_SELECT_CONST_TIMEVAL)
77 int select(int width, fd_set *rd, fd_set *wr, fd_set *ex,
78 const struct timeval *tv)
79 #else
80 int select(int width, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *tv)
81 #endif
82 {
83 int osfd;
84 _PRUnixPollDesc *unixpds, *unixpd, *eunixpd;
85 PRInt32 pdcnt;
86 PRIntervalTime timeout;
87 int retVal;
88 #if defined(HPUX9) || defined(AIX_RENAME_SELECT)
89 fd_set *rd = (fd_set*) rl;
90 fd_set *wr = (fd_set*) wl;
91 fd_set *ex = (fd_set*) el;
92 #endif
93
94 #if 0
95 /*
96 * Easy special case: zero timeout. Simply call the native
97 * select() with no fear of blocking.
98 */
99 if (tv != NULL && tv->tv_sec == 0 && tv->tv_usec == 0) {
100 #if defined(HPUX9) || defined(AIX_RENAME_SELECT)
101 return _MD_SELECT(width, rl, wl, el, tv);
102 #else
103 return _MD_SELECT(width, rd, wr, ex, tv);
104 #endif
105 }
106 #endif
107
108 if (!_pr_initialized) {
109 _PR_ImplicitInitialization();
110 }
111
112 #ifndef _PR_LOCAL_THREADS_ONLY
113 if (_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) {
114 return _MD_SELECT(width, rd, wr, ex, tv);
115 }
116 #endif
117
118 if (width < 0 || width > FD_SETSIZE) {
119 errno = EINVAL;
120 return -1;
121 }
122
123 /* Compute timeout */
124 if (tv) {
125 /*
126 * These acceptable ranges for t_sec and t_usec are taken
127 * from the select() man pages.
128 */
129 if (tv->tv_sec < 0 || tv->tv_sec > 100000000
130 || tv->tv_usec < 0 || tv->tv_usec >= 1000000) {
131 errno = EINVAL;
132 return -1;
133 }
134
135 /* Convert microseconds to ticks */
136 timeout = PR_MicrosecondsToInterval(1000000*tv->tv_sec + tv->tv_usec);
137 } else {
138 /* tv being a NULL pointer means blocking indefinitely */
139 timeout = PR_INTERVAL_NO_TIMEOUT;
140 }
141
142 /* Check for no descriptors case (just doing a timeout) */
143 if ((!rd && !wr && !ex) || !width) {
144 PR_Sleep(timeout);
145 return 0;
146 }
147
148 /*
149 * Set up for PR_Poll(). The PRPollDesc array is allocated
150 * dynamically. If this turns out to have high performance
151 * penalty, one can change to use a large PRPollDesc array
152 * on the stack, and allocate dynamically only when it turns
153 * out to be not large enough.
154 *
155 * I allocate an array of size 'width', which is the maximum
156 * number of fds we may need to poll.
157 */
158 unixpds = (_PRUnixPollDesc *) PR_CALLOC(width * sizeof(_PRUnixPollDesc));
159 if (!unixpds) {
160 errno = ENOMEM;
161 return -1;
162 }
163
164 pdcnt = 0;
165 unixpd = unixpds;
166 for (osfd = 0; osfd < width; osfd++) {
167 int in_flags = 0;
168 if (rd && FD_ISSET(osfd, rd)) {
169 in_flags |= _PR_UNIX_POLL_READ;
170 }
171 if (wr && FD_ISSET(osfd, wr)) {
172 in_flags |= _PR_UNIX_POLL_WRITE;
173 }
174 if (ex && FD_ISSET(osfd, ex)) {
175 in_flags |= _PR_UNIX_POLL_EXCEPT;
176 }
177 if (in_flags) {
178 unixpd->osfd = osfd;
179 unixpd->in_flags = in_flags;
180 unixpd->out_flags = 0;
181 unixpd++;
182 pdcnt++;
183 }
184 }
185
186 /*
187 * see comments in mozilla/cmd/xfe/mozilla.c (look for
188 * "PR_XGetXtHackFD")
189 */
190 {
191 int needToLockXAgain;
192
193 needToLockXAgain = 0;
194 if (rd && (_pr_xt_hack_fd != -1)
195 && FD_ISSET(_pr_xt_hack_fd, rd) && PR_XIsLocked()
196 && (!_pr_xt_hack_okayToReleaseXLock
197 || _pr_xt_hack_okayToReleaseXLock())) {
198 PR_XUnlock();
199 needToLockXAgain = 1;
200 }
201
202 /* This is the potentially blocking step */
203 retVal = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout);
204
205 if (needToLockXAgain) {
206 PR_XLock();
207 }
208 }
209
210 if (retVal > 0) {
211 /* Compute select results */
212 if (rd) ZAP_SET(rd, width);
213 if (wr) ZAP_SET(wr, width);
214 if (ex) ZAP_SET(ex, width);
215
216 /*
217 * The return value can be either the number of ready file
218 * descriptors or the number of set bits in the three fd_set's.
219 */
220 retVal = 0; /* we're going to recompute */
221 eunixpd = unixpds + pdcnt;
222 for (unixpd = unixpds; unixpd < eunixpd; unixpd++) {
223 if (unixpd->out_flags) {
224 int nbits = 0; /* The number of set bits on for this fd */
225
226 if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) {
227 errno = EBADF;
228 PR_LOG(_pr_io_lm, PR_LOG_ERROR,
229 ("select returns EBADF for %d", unixpd->osfd));
230 retVal = -1;
231 break;
232 }
233 /*
234 * If a socket has a pending error, it is considered
235 * both readable and writable. (See W. Richard Stevens,
236 * Unix Network Programming, Vol. 1, 2nd Ed., Section 6.3,
237 * pp. 153-154.) We also consider a socket readable if
238 * it has a hangup condition.
239 */
240 if (rd && (unixpd->in_flags & _PR_UNIX_POLL_READ)
241 && (unixpd->out_flags & (_PR_UNIX_POLL_READ
242 | _PR_UNIX_POLL_ERR | _PR_UNIX_POLL_HUP))) {
243 FD_SET(unixpd->osfd, rd);
244 nbits++;
245 }
246 if (wr && (unixpd->in_flags & _PR_UNIX_POLL_WRITE)
247 && (unixpd->out_flags & (_PR_UNIX_POLL_WRITE
248 | _PR_UNIX_POLL_ERR))) {
249 FD_SET(unixpd->osfd, wr);
250 nbits++;
251 }
252 if (ex && (unixpd->in_flags & _PR_UNIX_POLL_WRITE)
253 && (unixpd->out_flags & PR_POLL_EXCEPT)) {
254 FD_SET(unixpd->osfd, ex);
255 nbits++;
256 }
257 PR_ASSERT(nbits > 0);
258 #if defined(HPUX) || defined(SOLARIS) || defined(OSF1) || defined(AIX)
259 retVal += nbits;
260 #else /* IRIX */
261 retVal += 1;
262 #endif
263 }
264 }
265 }
266
267 PR_ASSERT(tv || retVal != 0);
268 PR_LOG(_pr_io_lm, PR_LOG_MIN, ("select returns %d", retVal));
269 PR_DELETE(unixpds);
270
271 return retVal;
272 }
273
274 /*
275 * Redefine poll, when supported on platforms, for local threads
276 */
277
278 /*
279 * I am commenting out the poll() wrapper for Linux for now
280 * because it is difficult to define _MD_POLL that works on all
281 * Linux varieties. People reported that glibc 2.0.7 on Debian
282 * 2.0 Linux machines doesn't have the __syscall_poll symbol
283 * defined. (WTC 30 Nov. 1998)
284 */
285 #if defined(_PR_POLL_AVAILABLE) && !defined(LINUX)
286
287 /*
288 *-----------------------------------------------------------------------
289 * poll() --
290 *
291 * RETURN VALUES:
292 * -1: fails, errno indicates the error.
293 * 0: timed out, the revents bitmasks are not set.
294 * positive value: the number of file descriptors for which poll()
295 * has set the revents bitmask.
296 *
297 *-----------------------------------------------------------------------
298 */
299
300 #include <poll.h>
301
302 #if defined(AIX_RENAME_SELECT)
303 int wrap_poll(void *listptr, unsigned long nfds, long timeout)
304 #elif (defined(AIX) && !defined(AIX_RENAME_SELECT))
305 int poll(void *listptr, unsigned long nfds, long timeout)
306 #elif defined(OSF1) || (defined(HPUX) && !defined(HPUX9))
307 int poll(struct pollfd filedes[], unsigned int nfds, int timeout)
308 #elif defined(HPUX9)
309 int poll(struct pollfd filedes[], int nfds, int timeout)
310 #elif defined(NETBSD)
311 int poll(struct pollfd *filedes, nfds_t nfds, int timeout)
312 #elif defined(OPENBSD)
313 int poll(struct pollfd filedes[], nfds_t nfds, int timeout)
314 #elif defined(FREEBSD)
315 int poll(struct pollfd *filedes, unsigned nfds, int timeout)
316 #else
317 int poll(struct pollfd *filedes, unsigned long nfds, int timeout)
318 #endif
319 {
320 #ifdef AIX
321 struct pollfd *filedes = (struct pollfd *) listptr;
322 #endif
323 struct pollfd *pfd, *epfd;
324 _PRUnixPollDesc *unixpds, *unixpd, *eunixpd;
325 PRIntervalTime ticks;
326 PRInt32 pdcnt;
327 int ready;
328
329 /*
330 * Easy special case: zero timeout. Simply call the native
331 * poll() with no fear of blocking.
332 */
333 if (timeout == 0) {
334 #if defined(AIX)
335 return _MD_POLL(listptr, nfds, timeout);
336 #else
337 return _MD_POLL(filedes, nfds, timeout);
338 #endif
339 }
340
341 if (!_pr_initialized) {
342 _PR_ImplicitInitialization();
343 }
344
345 #ifndef _PR_LOCAL_THREADS_ONLY
346 if (_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) {
347 return _MD_POLL(filedes, nfds, timeout);
348 }
349 #endif
350
351 /* We do not support the pollmsg structures on AIX */
352 #ifdef AIX
353 PR_ASSERT((nfds & 0xff00) == 0);
354 #endif
355
356 if (timeout < 0 && timeout != -1) {
357 errno = EINVAL;
358 return -1;
359 }
360
361 /* Convert timeout from miliseconds to ticks */
362 if (timeout == -1) {
363 ticks = PR_INTERVAL_NO_TIMEOUT;
364 } else {
365 ticks = PR_MillisecondsToInterval(timeout);
366 }
367
368 /* Check for no descriptor case (just do a timeout) */
369 if (nfds == 0) {
370 PR_Sleep(ticks);
371 return 0;
372 }
373
374 unixpds = (_PRUnixPollDesc *)
375 PR_MALLOC(nfds * sizeof(_PRUnixPollDesc));
376 if (NULL == unixpds) {
377 errno = EAGAIN;
378 return -1;
379 }
380
381 pdcnt = 0;
382 epfd = filedes + nfds;
383 unixpd = unixpds;
384 for (pfd = filedes; pfd < epfd; pfd++) {
385 /*
386 * poll() ignores negative fd's.
387 */
388 if (pfd->fd >= 0) {
389 unixpd->osfd = pfd->fd;
390 #ifdef _PR_USE_POLL
391 unixpd->in_flags = pfd->events;
392 #else
393 /*
394 * Map the poll events to one of the three that can be
395 * represented by the select fd_sets:
396 * POLLIN, POLLRDNORM ===> readable
397 * POLLOUT, POLLWRNORM ===> writable
398 * POLLPRI, POLLRDBAND ===> exception
399 * POLLNORM, POLLWRBAND (and POLLMSG on some platforms)
400 * are ignored.
401 *
402 * The output events POLLERR and POLLHUP are never turned on.
403 * POLLNVAL may be turned on.
404 */
405 unixpd->in_flags = 0;
406 if (pfd->events & (POLLIN
407 #ifdef POLLRDNORM
408 | POLLRDNORM
409 #endif
410 )) {
411 unixpd->in_flags |= _PR_UNIX_POLL_READ;
412 }
413 if (pfd->events & (POLLOUT
414 #ifdef POLLWRNORM
415 | POLLWRNORM
416 #endif
417 )) {
418 unixpd->in_flags |= _PR_UNIX_POLL_WRITE;
419 }
420 if (pfd->events & (POLLPRI
421 #ifdef POLLRDBAND
422 | POLLRDBAND
423 #endif
424 )) {
425 unixpd->in_flags |= PR_POLL_EXCEPT;
426 }
427 #endif /* _PR_USE_POLL */
428 unixpd->out_flags = 0;
429 unixpd++;
430 pdcnt++;
431 }
432 }
433
434 ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, ticks);
435 if (-1 == ready) {
436 if (PR_GetError() == PR_PENDING_INTERRUPT_ERROR) {
437 errno = EINTR; /* XXX we aren't interrupted by a signal, but... */
438 } else {
439 errno = PR_GetOSError();
440 }
441 }
442 if (ready <= 0) {
443 goto done;
444 }
445
446 /*
447 * Copy the out_flags from the _PRUnixPollDesc structures to the
448 * user's pollfd structures and free the allocated memory
449 */
450 unixpd = unixpds;
451 for (pfd = filedes; pfd < epfd; pfd++) {
452 pfd->revents = 0;
453 if (pfd->fd >= 0) {
454 #ifdef _PR_USE_POLL
455 pfd->revents = unixpd->out_flags;
456 #else
457 if (0 != unixpd->out_flags) {
458 if (unixpd->out_flags & _PR_UNIX_POLL_READ) {
459 if (pfd->events & POLLIN) {
460 pfd->revents |= POLLIN;
461 }
462 #ifdef POLLRDNORM
463 if (pfd->events & POLLRDNORM) {
464 pfd->revents |= POLLRDNORM;
465 }
466 #endif
467 }
468 if (unixpd->out_flags & _PR_UNIX_POLL_WRITE) {
469 if (pfd->events & POLLOUT) {
470 pfd->revents |= POLLOUT;
471 }
472 #ifdef POLLWRNORM
473 if (pfd->events & POLLWRNORM) {
474 pfd->revents |= POLLWRNORM;
475 }
476 #endif
477 }
478 if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT) {
479 if (pfd->events & POLLPRI) {
480 pfd->revents |= POLLPRI;
481 }
482 #ifdef POLLRDBAND
483 if (pfd->events & POLLRDBAND) {
484 pfd->revents |= POLLRDBAND;
485 }
486 #endif
487 }
488 if (unixpd->out_flags & _PR_UNIX_POLL_ERR) {
489 pfd->revents |= POLLERR;
490 }
491 if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) {
492 pfd->revents |= POLLNVAL;
493 }
494 if (unixpd->out_flags & _PR_UNIX_POLL_HUP) {
495 pfd->revents |= POLLHUP;
496 }
497 }
498 #endif /* _PR_USE_POLL */
499 unixpd++;
500 }
501 }
502
503 done:
504 PR_DELETE(unixpds);
505 return ready;
506 }
507
508 #endif /* !defined(LINUX) */
509
510 #endif /* defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) */
511
512 /* uxwrap.c */
513
OLDNEW
« no previous file with comments | « nspr/pr/src/md/unix/uxshm.c ('k') | nspr/pr/src/md/windows/ntgc.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698