Bugsplat bug #367096: need to set md.thr_bound_cpu to NULL when we

resume a falsely timed-out or abort a really timed-out AcceptEx call.
Also we must add a thread to its current CPU if md.thr_bound_cpu is
not NULL.
Modified files: ntio.c, ntthread.c, and pruthr.c
This commit is contained in:
wtc%netscape.com 1999-11-17 05:25:27 +00:00
Родитель 6ebc2715a6
Коммит 646291b218
3 изменённых файлов: 24 добавлений и 11 удалений

Просмотреть файл

@ -339,7 +339,9 @@ _PR_MD_PAUSE_CPU(PRIntervalTime ticks)
* wakeup occurs by calling ReleaseSemaphore.
*/
if ( key == KEY_CVAR ) {
PR_ASSERT(completed_io->io_pending == PR_FALSE || completed_io->io_suspended == PR_TRUE);
PR_ASSERT(completed_io->io_pending == PR_FALSE);
PR_ASSERT(completed_io->io_suspended == PR_FALSE);
PR_ASSERT(completed_io->md.thr_bound_cpu == NULL);
/* Thread has already been deleted from sleepQ */
@ -801,7 +803,8 @@ _PR_MD_WAKEUP_WAITER(PRThread *thread)
* XXXMB - can we know when we are truely idle (and not checking
* the runq)?
*/
if (_PR_IS_NATIVE_THREAD(me) || (thread->cpu != me->cpu)) {
if ((_PR_IS_NATIVE_THREAD(me) || (thread->cpu != me->cpu)) &&
(!thread->md.thr_bound_cpu)) {
/* The thread should not be in any queue */
PR_ASSERT(thread->queueCount == 0);
if ( PostQueuedCompletionStatus(_pr_completion_port, 0,
@ -1027,6 +1030,7 @@ _NT_IO_ABORT(PRInt32 sock)
/* Set up to wait for I/O completion again */
me->state = _PR_IO_WAIT;
me->io_suspended = PR_FALSE;
me->md.interrupt_disabled = PR_TRUE;
}
_PR_THREAD_UNLOCK(me);
@ -1061,11 +1065,13 @@ _NT_IO_ABORT(PRInt32 sock)
++missing_completions;
}
me->md.interrupt_disabled = PR_FALSE;
me->io_pending = PR_FALSE;
me->state = _PR_RUNNING;
}
PR_ASSERT(me->io_pending == PR_FALSE);
me->md.thr_bound_cpu = NULL;
me->io_suspended = PR_FALSE;
return rv;
@ -1543,7 +1549,7 @@ retry:
}
if (elapsed < timeout) {
/* Socket is not connected but time not elapsed, RESUME IO */
/* Socket is connected but time not elapsed, RESUME IO */
timeout -= elapsed;
me->state = _PR_IO_WAIT;
if (_NT_ResumeIO(me, timeout) == PR_FAILURE)
@ -1558,8 +1564,9 @@ retry:
rv = _NT_IO_ABORT(*newSock);
PR_ASSERT(me->io_suspended == PR_FALSE);
PR_ASSERT(me->io_pending == PR_FALSE);
PR_ASSERT(me->io_suspended == PR_FALSE);
PR_ASSERT(me->md.thr_bound_cpu == NULL);
/* If the IO is still suspended, it means we didn't get any
* completion from NT_IO_WAIT. This is not disasterous, I hope,
* but it may mean we still have an IO outstanding... Try to
@ -1576,7 +1583,9 @@ retry:
return -1;
}
PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE);
PR_ASSERT(me->io_pending == PR_FALSE);
PR_ASSERT(me->io_suspended == PR_FALSE);
PR_ASSERT(me->md.thr_bound_cpu == NULL);
if (me->md.blocked_io_status == 0) {
_PR_MD_MAP_ACCEPTEX_ERROR(me->md.blocked_io_error);
@ -1598,8 +1607,6 @@ retry:
(LPSOCKADDR *)(raddr),
(unsigned int *)&rlen);
PR_ASSERT(me->io_pending == PR_FALSE);
return me->md.blocked_io_bytes;
}
@ -3685,12 +3692,12 @@ PR_IMPLEMENT(PRStatus) PR_NT_CancelIo(PRFileDesc *fd)
_PR_THREAD_UNLOCK(me);
if (fWait)
_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
me->md.thr_bound_cpu = NULL;
PR_ASSERT(me->io_suspended == PR_FALSE);
PR_ASSERT(me->io_pending == PR_FALSE);
_PR_THREAD_LOCK(me);
me->md.interrupt_disabled = PR_FALSE;
me->md.thr_bound_cpu = NULL;
me->io_suspended = PR_FALSE;
me->io_pending = PR_FALSE;
me->state = _PR_RUNNING;

Просмотреть файл

@ -62,6 +62,7 @@ _nt_handle_restarted_io(PRThread *restarted_io)
* be the result for a context switch too..
*/
PR_ASSERT(restarted_io->io_suspended == PR_TRUE);
PR_ASSERT(restarted_io->md.thr_bound_cpu == restarted_io->cpu);
_PR_THREAD_LOCK(restarted_io);
if (restarted_io->io_pending == PR_FALSE) {
@ -79,6 +80,7 @@ _nt_handle_restarted_io(PRThread *restarted_io)
_PR_SLEEPQ_UNLOCK(restarted_io->cpu);
}
restarted_io->io_suspended = PR_FALSE;
restarted_io->md.thr_bound_cpu = NULL;
_PR_THREAD_UNLOCK(restarted_io);

Просмотреть файл

@ -1844,10 +1844,14 @@ _PR_AddThreadToRunQ(
* _PR_MD_WAKEUP_WAITER).
* Threads with a suspended I/O operation remain bound to
* the same cpu until I/O is cancelled
*
* NOTE: the boolean expression below must be the exact
* opposite of the corresponding boolean expression in
* _PR_MD_WAKEUP_WAITER.
*/
if (!_PR_IS_NATIVE_THREAD(me) && ((cpu == me->cpu) ||
(thread->io_suspended))) {
PR_ASSERT(!thread->io_suspended ||
if ((!_PR_IS_NATIVE_THREAD(me) && (cpu == me->cpu)) ||
(thread->md.thr_bound_cpu)) {
PR_ASSERT(!thread->md.thr_bound_cpu ||
(thread->md.thr_bound_cpu == cpu));
_PR_RUNQ_LOCK(cpu);
_PR_ADD_RUNQ(thread, cpu, pri);