summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%netscape.com <devnull@localhost>2003-02-28 03:45:27 +0000
committerwtc%netscape.com <devnull@localhost>2003-02-28 03:45:27 +0000
commit191b412daa9a3b66aa5a635f9cc6afd2c7f920a1 (patch)
tree65a34879444f67828d0cb84362e1ded6b0f6820d
parentcc4ab57d52d2f19b79dc1ae518168e03e3a109aa (diff)
downloadnspr-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.c33
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
/*