From 646291b218864c3c3905ed47de2ae952cf5803ab Mon Sep 17 00:00:00 2001 From: "wtc%netscape.com" Date: Wed, 17 Nov 1999 05:25:27 +0000 Subject: [PATCH] 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 --- nsprpub/pr/src/md/windows/ntio.c | 23 +++++++++++++++-------- nsprpub/pr/src/md/windows/ntthread.c | 2 ++ nsprpub/pr/src/threads/combined/pruthr.c | 10 +++++++--- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/nsprpub/pr/src/md/windows/ntio.c b/nsprpub/pr/src/md/windows/ntio.c index 35bd82fbf99a..b58740f7fb65 100644 --- a/nsprpub/pr/src/md/windows/ntio.c +++ b/nsprpub/pr/src/md/windows/ntio.c @@ -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; diff --git a/nsprpub/pr/src/md/windows/ntthread.c b/nsprpub/pr/src/md/windows/ntthread.c index b6b41ea5dbb1..37cb2e3a3954 100644 --- a/nsprpub/pr/src/md/windows/ntthread.c +++ b/nsprpub/pr/src/md/windows/ntthread.c @@ -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); diff --git a/nsprpub/pr/src/threads/combined/pruthr.c b/nsprpub/pr/src/threads/combined/pruthr.c index a55fc39b31fa..473da9c2e457 100644 --- a/nsprpub/pr/src/threads/combined/pruthr.c +++ b/nsprpub/pr/src/threads/combined/pruthr.c @@ -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);