diff options
author | wtc%netscape.com <devnull@localhost> | 2003-02-28 03:45:27 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 2003-02-28 03:45:27 +0000 |
commit | 191b412daa9a3b66aa5a635f9cc6afd2c7f920a1 (patch) | |
tree | 65a34879444f67828d0cb84362e1ded6b0f6820d | |
parent | cc4ab57d52d2f19b79dc1ae518168e03e3a109aa (diff) | |
download | nspr-hg-191b412daa9a3b66aa5a635f9cc6afd2c7f920a1.tar.gz |
Bug 192797: improved the implementation of PR_Poll for Win32. Increase
FD_SETSIZE from the default 64 to 1024. Make PR_Poll fail with
PR_INVALID_ARGUMENT_ERROR if we try to add more than FD_SETSIZE fd's to a
fd_set. Do not pass an empty fd_set to select, and do not call select if
all three fd_sets are empty.
Tag: NSPRPUB_PRE_4_2_CLIENT_BRANCH
-rw-r--r-- | pr/src/md/windows/w32poll.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/pr/src/md/windows/w32poll.c b/pr/src/md/windows/w32poll.c index 9c4836f3..93a9a2d3 100644 --- a/pr/src/md/windows/w32poll.c +++ b/pr/src/md/windows/w32poll.c @@ -36,6 +36,9 @@ * 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) @@ -105,6 +108,8 @@ 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(); @@ -127,6 +132,7 @@ PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) return 0; } + nrd = nwt = nex = 0; FD_ZERO(&rd); FD_ZERO(&wt); FD_ZERO(&ex); @@ -189,23 +195,30 @@ PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) { 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++; } - if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex); } } else @@ -231,6 +244,20 @@ PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) if (0 != ready) return ready; /* no need to block */ + 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(); @@ -241,9 +268,9 @@ PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) } #if defined(_PR_GLOBAL_THREADS_ONLY) - ready = _MD_SELECT(0, &rd, &wt, &ex, tvp); + ready = _MD_SELECT(0, rdp, wtp, exp, tvp); #else - ready = _PR_NTFiberSafeSelect(0, &rd, &wt, &ex, tvp); + ready = _PR_NTFiberSafeSelect(0, rdp, wtp, exp, tvp); #endif /* |