[PATCH 2/2] wineserver: Fixed bug #7286, waiting thread is last
thread referencing a change notification object.
Misha Koshelev
mk144210 at bcm.tmc.edu
Sat Feb 3 13:29:01 CST 2007
This is the second patch of my patchset. I made my two patches into a
patchset, one that adds a conformance test to tickle bug #7286, and the
other to fix the bug. The first encloses the code that crashes
wineserver with the line "wineserver: object.c:274: release_object:
Assertion `obj->refcount' failed" in an if (0) { } statement so that
other tests can run. The second patch undoes this enclosure. This occurs
on wine 0.9.22,0.9.29,0.9.30, and git when a waiting thread is the last
one that references a ChangeNotification handle and is waiting on it. In
this case, end_wait tries to destroy the changenotification object, and
dir_destroy in turn tries to queue a user APC to the thread. If no user
APCs are already waiting for the thread, it tries to call end_wait
again, which references the same thread->wait object as its caller
end_wait function and thus runs into a problem releasing an object which
has a refcount of zero. This problem is present when running the Vector
NTI software on wine. Thanks for everybody's help with this.
Changelog:
* wineserver: Fixed bug #7286, waiting thread is last thread
referencing a change notification object.
Disallows recursive calls to end_wait for the same thread.
-------------- next part --------------
From f3efeecad551e03ce5d1e513b74c91e2277dcba8 Mon Sep 17 00:00:00 2001
From: Misha Koshelev <mk144210 at bcm.tmc.edu>
Date: Sat, 3 Feb 2007 13:17:24 -0600
Subject: wineserver: Fixed bug #7286, waiting thread is last thread referencing a change notification object.
Disallows recursive calls to end_wait for the same thread.
---
dlls/kernel32/tests/change.c | 6 ++----
server/thread.c | 7 +++++++
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/change.c b/dlls/kernel32/tests/change.c
index fdcaa34..f31bdcf 100644
--- a/dlls/kernel32/tests/change.c
+++ b/dlls/kernel32/tests/change.c
@@ -354,10 +354,8 @@ static void test_ffcnMultipleThreads()
* process awakening, which causes an APC to be sent to the process from
* within the end_wait function. This crashes Wine GIT as of 2/3/7 and
* 0.9.22, 0.9.29, 0.9.30. Works fine on Windows XP. */
- if (0) {
- status = WaitForMultipleObjects(2, handles, FALSE, 5000);
- ok(status == WAIT_OBJECT_0 || status == WAIT_OBJECT_0+1, "WaitForMultipleObjects status %d error %d\n", status, GetLastError());
- }
+ status = WaitForMultipleObjects(2, handles, FALSE, 5000);
+ ok(status == WAIT_OBJECT_0 || status == WAIT_OBJECT_0+1, "WaitForMultipleObjects status %d error %d\n", status, GetLastError());
ok(GetExitCodeThread(handles[1], &exitcode), "Could not retrieve thread exit code\n");
/* Clean up */
diff --git a/server/thread.c b/server/thread.c
index b4a16cd..b477364 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -58,6 +58,8 @@ struct thread_wait
struct thread *thread; /* owner thread */
int count; /* count of objects */
int flags;
+ int waking; /* whether we are currently waking this
+ * thread */
void *cookie; /* magic cookie to return to client */
struct timeval timeout;
struct timeout_user *user;
@@ -447,6 +449,7 @@ static void end_wait( struct thread *thr
int i;
assert( wait );
+ thread->wait->waking = 1;
for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
entry->obj->ops->remove_queue( entry->obj, entry );
if (wait->user) remove_timeout_user( wait->user );
@@ -467,6 +470,7 @@ static int wait_on( int count, struct ob
wait->count = count;
wait->flags = flags;
wait->user = NULL;
+ wait->waking = 0;
current->wait = wait;
if (flags & SELECT_TIMEOUT)
{
@@ -495,6 +499,9 @@ static int check_wait( struct thread *th
struct thread_wait *wait = thread->wait;
struct wait_queue_entry *entry = wait->queues;
+ /* If we are already waking this thread, no need to wake it again */
+ if (wait->waking) return -1;
+
/* Suspended threads may not acquire locks, but they can run system APCs */
if (thread->process->suspend + thread->suspend > 0)
{
--
1.4.1
More information about the wine-patches
mailing list