mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-01 19:39:13 +00:00
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:
parent
66b70399fe
commit
b1e1a5e873
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user