Suspended threads should not acquire synchronization objects.
diff --git a/server/process.c b/server/process.c
index 785c4cb..c3cf436 100644
--- a/server/process.c
+++ b/server/process.c
@@ -673,7 +673,11 @@
while (thread)
{
struct thread *next = thread->proc_next;
- if (!thread->suspend) continue_thread( thread );
+ if (!thread->suspend)
+ {
+ continue_thread( thread );
+ wake_thread( thread );
+ }
thread = next;
}
}
@@ -818,7 +822,7 @@
if (!check_process_write_access( thread, addr, len ))
{
set_error( STATUS_ACCESS_DENIED );
- return;
+ goto done;
}
/* first word is special */
if (len > 1)
diff --git a/server/thread.c b/server/thread.c
index 1a9244f..7e4ae69 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -319,7 +319,11 @@
int old_count = thread->suspend;
if (thread->suspend > 0)
{
- if (!(--thread->suspend + thread->process->suspend)) continue_thread( thread );
+ if (!(--thread->suspend + thread->process->suspend))
+ {
+ continue_thread( thread );
+ wake_thread( thread );
+ }
}
return old_count;
}
@@ -403,6 +407,9 @@
struct thread_wait *wait = thread->wait;
struct wait_queue_entry *entry = wait->queues;
+ /* Suspended threads may not acquire locks */
+ if( thread->process->suspend + thread->suspend > 0 ) return -1;
+
assert( wait );
if (wait->flags & SELECT_ALL)
{
@@ -465,7 +472,7 @@
/* attempt to wake up a thread */
/* return >0 if OK, 0 if the wait condition is still not satisfied */
-static int wake_thread( struct thread *thread )
+int wake_thread( struct thread *thread )
{
int signaled, count;
void *cookie;
diff --git a/server/thread.h b/server/thread.h
index a46f389..6e244c6 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -112,6 +112,7 @@
extern struct thread *get_thread_from_pid( int pid );
extern int suspend_thread( struct thread *thread, int check_limit );
extern int resume_thread( struct thread *thread );
+extern int wake_thread( struct thread *thread );
extern int add_queue( struct object *obj, struct wait_queue_entry *entry );
extern void remove_queue( struct object *obj, struct wait_queue_entry *entry );
extern void kill_thread( struct thread *thread, int violent_death );