Bugzilla bug 134192: fixed a bug that may cause us to poll or select with

a zero timeout forever.  Thanks to Jeff Stewart of Good Technology for the
bug report and explaining the bug to me.
Modified files: bnet.c os2sock.c unix.c w95sock.c ptio.c
This commit is contained in:
wtc%netscape.com 2002-03-29 16:08:14 +00:00
parent 66b70399fe
commit b1e1a5e873
5 changed files with 71 additions and 16 deletions

View File

@ -80,6 +80,7 @@ static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
struct timeval tv;
PRThread *me = _PR_MD_CURRENT_THREAD();
PRIntervalTime epoch, now, elapsed, remaining;
PRBool wait_for_remaining;
PRInt32 syserror;
fd_set rd_wr;
@ -132,8 +133,10 @@ static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
* so that there is an upper limit on the delay
* before the interrupt bit is checked.
*/
wait_for_remaining = PR_TRUE;
tv.tv_sec = PR_IntervalToSeconds(remaining);
if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
wait_for_remaining = PR_FALSE;
tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
tv.tv_usec = 0;
} else {
@ -178,8 +181,12 @@ static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
* PR_IntervalNow() call.
*/
if (rv == 0) {
now += PR_SecondsToInterval(tv.tv_sec)
+ PR_MicrosecondsToInterval(tv.tv_usec);
if (wait_for_remaining) {
now += remaining;
} else {
now += PR_SecondsToInterval(tv.tv_sec)
+ PR_MicrosecondsToInterval(tv.tv_usec);
}
} else {
now = PR_IntervalNow();
}

View File

@ -113,6 +113,7 @@ socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout )
PRInt32 rv = -1;
PRThread *me = _PR_MD_CURRENT_THREAD();
PRIntervalTime epoch, now, elapsed, remaining;
PRBool wait_for_remaining;
PRInt32 syserror;
#ifdef BSD_SELECT
struct timeval tv;
@ -176,8 +177,10 @@ socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout )
* before the interrupt bit is checked.
*/
#ifdef BSD_SELECT
wait_for_remaining = PR_TRUE;
tv.tv_sec = PR_IntervalToSeconds(remaining);
if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
wait_for_remaining = PR_FALSE;
tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
tv.tv_usec = 0;
} else {
@ -191,9 +194,12 @@ socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout )
else
rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
#else
wait_for_remaining = PR_TRUE;
lTimeout = PR_IntervalToMilliseconds(remaining);
if (lTimeout > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000)
if (lTimeout > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) {
wait_for_remaining = PR_FALSE;
lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
}
socks[0] = osfd;
if (fd_type == READ_FD)
rv = _MD_SELECT(socks, 1, 0, 0, lTimeout);
@ -224,12 +230,16 @@ socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout )
* PR_IntervalNow() call.
*/
if (rv == 0) {
if (wait_for_remaining) {
now += remaining;
} else {
#ifdef BSD_SELECT
now += PR_SecondsToInterval(tv.tv_sec)
+ PR_MicrosecondsToInterval(tv.tv_usec);
now += PR_SecondsToInterval(tv.tv_sec)
+ PR_MicrosecondsToInterval(tv.tv_usec);
#else
now += PR_MillisecondsToInterval(lTimeout);
now += PR_MillisecondsToInterval(lTimeout);
#endif
}
} else {
now = PR_IntervalNow();
}

View File

@ -514,6 +514,7 @@ static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
struct timeval tv;
PRThread *me = _PR_MD_CURRENT_THREAD();
PRIntervalTime epoch, now, elapsed, remaining;
PRBool wait_for_remaining;
PRInt32 syserror;
fd_set rd_wr;
@ -558,8 +559,10 @@ static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
* so that there is an upper limit on the delay
* before the interrupt bit is checked.
*/
wait_for_remaining = PR_TRUE;
tv.tv_sec = PR_IntervalToSeconds(remaining);
if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
wait_for_remaining = PR_FALSE;
tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
tv.tv_usec = 0;
} else {
@ -596,8 +599,12 @@ static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
* PR_IntervalNow() call.
*/
if (rv == 0) {
now += PR_SecondsToInterval(tv.tv_sec)
+ PR_MicrosecondsToInterval(tv.tv_usec);
if (wait_for_remaining) {
now += remaining;
} else {
now += PR_SecondsToInterval(tv.tv_sec)
+ PR_MicrosecondsToInterval(tv.tv_usec);
}
} else {
now = PR_IntervalNow();
}
@ -625,6 +632,7 @@ static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
int msecs;
PRThread *me = _PR_MD_CURRENT_THREAD();
PRIntervalTime epoch, now, elapsed, remaining;
PRBool wait_for_remaining;
PRInt32 syserror;
struct pollfd pfd;
@ -682,8 +690,10 @@ static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
* so that there is an upper limit on the delay
* before the interrupt bit is checked.
*/
wait_for_remaining = PR_TRUE;
msecs = PR_IntervalToMilliseconds(remaining);
if (msecs > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) {
wait_for_remaining = PR_FALSE;
msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
}
rv = _MD_POLL(&pfd, 1, msecs);
@ -719,7 +729,11 @@ static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
* PR_IntervalNow() call.
*/
if (rv == 0) {
now += PR_MillisecondsToInterval(msecs);
if (wait_for_remaining) {
now += remaining;
} else {
now += PR_MillisecondsToInterval(msecs);
}
} else {
now = PR_IntervalNow();
}

View File

@ -474,6 +474,7 @@ static PRInt32 socket_io_wait(
struct timeval tv;
PRThread *me = _PR_MD_CURRENT_THREAD();
PRIntervalTime elapsed, remaining;
PRBool wait_for_remaining;
fd_set rd_wr, ex;
int err, len;
@ -560,8 +561,10 @@ static PRInt32 socket_io_wait(
* so that there is an upper limit on the delay
* before the interrupt bit is checked.
*/
wait_for_remaining = PR_TRUE;
tv.tv_sec = PR_IntervalToSeconds(remaining);
if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
wait_for_remaining = PR_FALSE;
tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
tv.tv_usec = 0;
} else {
@ -631,8 +634,12 @@ static PRInt32 socket_io_wait(
*/
if (rv == 0 )
{
elapsed = PR_SecondsToInterval(tv.tv_sec)
+ PR_MicrosecondsToInterval(tv.tv_usec);
if (wait_for_remaining) {
elapsed = remaining;
} else {
elapsed = PR_SecondsToInterval(tv.tv_sec)
+ PR_MicrosecondsToInterval(tv.tv_usec);
}
if (elapsed >= remaining) {
PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
rv = -1;

View File

@ -425,6 +425,7 @@ static void pt_poll_now_with_select(pt_Continuation *op)
fd_set rd, wr, *rdp, *wrp;
struct timeval tv;
PRIntervalTime epoch, now, elapsed, remaining;
PRBool wait_for_remaining;
PRThread *self = PR_GetCurrentThread();
PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout);
@ -504,9 +505,12 @@ static void pt_poll_now_with_select(pt_Continuation *op)
} else
wrp = NULL;
wait_for_remaining = PR_TRUE;
msecs = (PRInt32)PR_IntervalToMilliseconds(remaining);
if (msecs > PT_DEFAULT_POLL_MSEC)
if (msecs > PT_DEFAULT_POLL_MSEC) {
wait_for_remaining = PR_FALSE;
msecs = PT_DEFAULT_POLL_MSEC;
}
tv.tv_sec = msecs/PR_MSEC_PER_SEC;
tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC;
rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv);
@ -533,9 +537,12 @@ static void pt_poll_now_with_select(pt_Continuation *op)
} else if ((rv == 0) ||
((errno == EINTR) || (errno == EAGAIN))) {
if (rv == 0) /* select timed out */
now += PR_MillisecondsToInterval(msecs);
else
if (rv == 0) { /* select timed out */
if (wait_for_remaining)
now += remaining;
else
now += PR_MillisecondsToInterval(msecs);
} else
now = PR_IntervalNow();
elapsed = (PRIntervalTime) (now - epoch);
if (elapsed >= op->timeout) {
@ -561,6 +568,7 @@ static void pt_poll_now(pt_Continuation *op)
{
PRInt32 msecs;
PRIntervalTime epoch, now, elapsed, remaining;
PRBool wait_for_remaining;
PRThread *self = PR_GetCurrentThread();
PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout);
@ -637,9 +645,13 @@ static void pt_poll_now(pt_Continuation *op)
tmp_pfd.fd = op->arg1.osfd;
tmp_pfd.events = op->event;
wait_for_remaining = PR_TRUE;
msecs = (PRInt32)PR_IntervalToMilliseconds(remaining);
if (msecs > PT_DEFAULT_POLL_MSEC)
{
wait_for_remaining = PR_FALSE;
msecs = PT_DEFAULT_POLL_MSEC;
}
rv = poll(&tmp_pfd, 1, msecs);
if (self->state & PT_THREAD_ABORTED)
@ -673,7 +685,12 @@ static void pt_poll_now(pt_Continuation *op)
} else if ((rv == 0) ||
((errno == EINTR) || (errno == EAGAIN))) {
if (rv == 0) /* poll timed out */
now += PR_MillisecondsToInterval(msecs);
{
if (wait_for_remaining)
now += remaining;
else
now += PR_MillisecondsToInterval(msecs);
}
else
now = PR_IntervalNow();
elapsed = (PRIntervalTime) (now - epoch);