<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7650.28">
<TITLE>wineserver: Make sure while we are waking a thread we do not try to do it again (try #2)</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->

<P><FONT SIZE=2>Hi, this is my first patch. It is for the following bug:<BR>
<A HREF="http://bugs.winehq.org/show_bug.cgi?id=7286">http://bugs.winehq.org/show_bug.cgi?id=7286</A> . This patch solves the<BR>
following problem: currently, in wineserver when a thread is being woken<BR>
and end_wait is called, the wait object is not updated in any meaningful<BR>
way until all the objects that need to be released from the thread-&gt;wait<BR>
object are in fact release. This causes a problem if one of the<BR>
release_objects methods for a specific object that is being released<BR>
ends up waking up the thread again, as occurs in this bug with the<BR>
directory objects and the dir_destroy method, which sends a user APC to<BR>
all the threads on its change queue. For Vector NTI, the same thread<BR>
that is being woken by a timeout after waiting for the directory object<BR>
is also on the change queue for this directory, so with this patch the<BR>
user APC is queued but the thread is not immediately woken because it is<BR>
already in the process of being woken for a timeout. In general, this<BR>
patch will keep a thread from being woken if it is in the process of<BR>
being woken, which could in theory come up in other situations.<BR>
<BR>
Changelog:<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wineserver: Do not allow a thread to be woken when it is already in the process of being woken.<BR>
<BR>
---<BR>
&nbsp;server/thread.c |&nbsp;&nbsp;&nbsp; 7 +++++++<BR>
&nbsp;1 files changed, 7 insertions(+), 0 deletions(-)<BR>
<BR>
diff --git a/server/thread.c b/server/thread.c<BR>
index b4a16cd..b477364 100644<BR>
--- a/server/thread.c<BR>
+++ b/server/thread.c<BR>
@@ -58,6 +58,8 @@ struct thread_wait<BR>
&nbsp;&nbsp;&nbsp;&nbsp; struct thread&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *thread;&nbsp;&nbsp;&nbsp;&nbsp; /* owner thread */<BR>
&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* count of objects */<BR>
&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; flags;<BR>
+&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; waking;&nbsp;&nbsp;&nbsp;&nbsp; /* whether we are currently waking this<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * thread */<BR>
&nbsp;&nbsp;&nbsp;&nbsp; void&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *cookie;&nbsp;&nbsp;&nbsp;&nbsp; /* magic cookie to return to client */<BR>
&nbsp;&nbsp;&nbsp;&nbsp; struct timeval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeout;<BR>
&nbsp;&nbsp;&nbsp;&nbsp; struct timeout_user&nbsp;&nbsp;&nbsp; *user;<BR>
@@ -447,6 +449,7 @@ static void end_wait( struct thread *thr<BR>
&nbsp;&nbsp;&nbsp;&nbsp; int i;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp; assert( wait );<BR>
+&nbsp;&nbsp;&nbsp; thread-&gt;wait-&gt;waking = 1;<BR>
&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0, entry = wait-&gt;queues; i &lt; wait-&gt;count; i++, entry++)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; entry-&gt;obj-&gt;ops-&gt;remove_queue( entry-&gt;obj, entry );<BR>
&nbsp;&nbsp;&nbsp;&nbsp; if (wait-&gt;user) remove_timeout_user( wait-&gt;user );<BR>
@@ -467,6 +470,7 @@ static int wait_on( int count, struct ob<BR>
&nbsp;&nbsp;&nbsp;&nbsp; wait-&gt;count&nbsp;&nbsp; = count;<BR>
&nbsp;&nbsp;&nbsp;&nbsp; wait-&gt;flags&nbsp;&nbsp; = flags;<BR>
&nbsp;&nbsp;&nbsp;&nbsp; wait-&gt;user&nbsp;&nbsp;&nbsp; = NULL;<BR>
+&nbsp;&nbsp;&nbsp; wait-&gt;waking&nbsp; = 0;<BR>
&nbsp;&nbsp;&nbsp;&nbsp; current-&gt;wait = wait;<BR>
&nbsp;&nbsp;&nbsp;&nbsp; if (flags &amp; SELECT_TIMEOUT)<BR>
&nbsp;&nbsp;&nbsp;&nbsp; {<BR>
@@ -495,6 +499,9 @@ static int check_wait( struct thread *th<BR>
&nbsp;&nbsp;&nbsp;&nbsp; struct thread_wait *wait = thread-&gt;wait;<BR>
&nbsp;&nbsp;&nbsp;&nbsp; struct wait_queue_entry *entry = wait-&gt;queues;<BR>
<BR>
+&nbsp;&nbsp;&nbsp; /* If we are already waking this thread, no need to wake it again */<BR>
+&nbsp;&nbsp;&nbsp; if (wait-&gt;waking) return -1;<BR>
+<BR>
&nbsp;&nbsp;&nbsp;&nbsp; /* Suspended threads may not acquire locks, but they can run system APCs */<BR>
&nbsp;&nbsp;&nbsp;&nbsp; if (thread-&gt;process-&gt;suspend + thread-&gt;suspend &gt; 0)<BR>
&nbsp;&nbsp;&nbsp;&nbsp; {<BR>
--<BR>
1.4.1<BR>
<BR>
<BR>
</FONT>
</P>

</BODY>
</HTML>