Removed client-side wait functions; all waiting is now done through
the server.

diff --git a/scheduler/client.c b/scheduler/client.c
index 47670a4..4f01efd 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -328,32 +328,6 @@
 }
 
 /***********************************************************************
- *           CLIENT_TerminateProcess
- *
- * Send a terminate process request. Return 0 if OK.
- */
-int CLIENT_TerminateProcess( int handle, int exit_code )
-{
-    CLIENT_SendRequest( REQ_TERMINATE_PROCESS, -1, 2,
-                        &handle, sizeof(handle),
-                        &exit_code, sizeof(exit_code) );
-    return CLIENT_WaitReply( NULL, NULL, 0 );
-}
-
-/***********************************************************************
- *           CLIENT_TerminateThread
- *
- * Send a terminate thread request. Return 0 if OK.
- */
-int CLIENT_TerminateThread( int handle, int exit_code )
-{
-    CLIENT_SendRequest( REQ_TERMINATE_THREAD, -1, 2,
-                        &handle, sizeof(handle),
-                        &exit_code, sizeof(exit_code) );
-    return CLIENT_WaitReply( NULL, NULL, 0 );
-}
-
-/***********************************************************************
  *           CLIENT_CloseHandle
  *
  * Send a close handle request. Return 0 if OK.
diff --git a/scheduler/event.c b/scheduler/event.c
index 552568d..30a1c76 100644
--- a/scheduler/event.c
+++ b/scheduler/event.c
@@ -18,69 +18,17 @@
 typedef struct
 {
     K32OBJ        header;
-    THREAD_QUEUE  wait_queue;
-    BOOL32        manual_reset;
-    BOOL32        signaled;
 } EVENT;
 
-static BOOL32 EVENT_Signaled( K32OBJ *obj, DWORD thread_id );
-static BOOL32 EVENT_Satisfied( K32OBJ *obj, DWORD thread_id );
-static void EVENT_AddWait( K32OBJ *obj, DWORD thread_id );
-static void EVENT_RemoveWait( K32OBJ *obj, DWORD thread_id );
 static void EVENT_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS EVENT_Ops =
 {
-    EVENT_Signaled,     /* signaled */
-    EVENT_Satisfied,    /* satisfied */
-    EVENT_AddWait,      /* add_wait */
-    EVENT_RemoveWait,   /* remove_wait */
-    NULL,               /* read */
-    NULL,               /* write */
     EVENT_Destroy       /* destroy */
 };
 
 
 /***********************************************************************
- *           EVENT_Set
- *
- * Implementation of SetEvent. Used by ExitThread and ExitProcess.
- */
-void EVENT_Set( K32OBJ *obj )
-{
-    EVENT *event = (EVENT *)obj;
-    assert( obj->type == K32OBJ_EVENT );
-    SYSTEM_LOCK();
-    event->signaled = TRUE;
-    SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
-    SYSTEM_UNLOCK();
-}
-
-/***********************************************************************
- *           EVENT_Create
- *
- * Partial implementation of CreateEvent.
- * Used internally by processes and threads.
- */
-K32OBJ *EVENT_Create( BOOL32 manual_reset, BOOL32 initial_state )
-{
-    EVENT *event;
-
-    SYSTEM_LOCK();
-    if ((event = HeapAlloc( SystemHeap, 0, sizeof(*event) )))
-    {
-        event->header.type     = K32OBJ_EVENT;
-        event->header.refcount = 1;
-        event->wait_queue      = NULL;
-        event->manual_reset    = manual_reset;
-        event->signaled        = initial_state;
-    }
-    SYSTEM_UNLOCK();
-    return event ? &event->header : NULL;
-}
-
-
-/***********************************************************************
  *           CreateEvent32A    (KERNEL32.156)
  */
 HANDLE32 WINAPI CreateEvent32A( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset,
@@ -99,20 +47,15 @@
     CLIENT_SendRequest( REQ_CREATE_EVENT, -1, 2, &req, sizeof(req), name, len );
     CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
     CHECK_LEN( len, sizeof(reply) );
-    if (reply.handle == -1) return NULL;
+    if (reply.handle == -1) return 0;
 
     SYSTEM_LOCK();
     event = (EVENT *)K32OBJ_Create( K32OBJ_EVENT, sizeof(*event), name,
                                     reply.handle, EVENT_ALL_ACCESS, sa, &handle );
     if (event)
-    {
-        /* Finish initializing it */
-        event->wait_queue   = NULL;
-        event->manual_reset = manual_reset;
-        event->signaled     = initial_state;
         K32OBJ_DecCount( &event->header );
-    }
     SYSTEM_UNLOCK();
+    if (handle == INVALID_HANDLE_VALUE32) handle = 0;
     return handle;
 }
 
@@ -145,13 +88,29 @@
 {
     HANDLE32 handle = 0;
     K32OBJ *obj;
-    SYSTEM_LOCK();
-    if ((obj = K32OBJ_FindNameType( name, K32OBJ_EVENT )) != NULL)
+    struct open_named_obj_request req;
+    struct open_named_obj_reply reply;
+    int len = name ? strlen(name) + 1 : 0;
+
+    req.type    = OPEN_EVENT;
+    req.access  = access;
+    req.inherit = inherit;
+    CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
+    CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
+    CHECK_LEN( len, sizeof(reply) );
+    if (reply.handle != -1)
     {
-        handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, -1 );
-        K32OBJ_DecCount( obj );
+        SYSTEM_LOCK();
+        if ((obj = K32OBJ_FindNameType( name, K32OBJ_EVENT )) != NULL)
+        {
+            handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, reply.handle );
+            K32OBJ_DecCount( obj );
+            if (handle == INVALID_HANDLE_VALUE32)
+                handle = 0; /* must return 0 on failure, not -1 */
+        }
+        else CLIENT_CloseHandle( reply.handle );
+        SYSTEM_UNLOCK();
     }
-    SYSTEM_UNLOCK();
     return handle;
 }
 
@@ -169,33 +128,29 @@
 
 
 /***********************************************************************
+ *           EVENT_Operation
+ *
+ * Execute an event operation (set,reset,pulse).
+ */
+static BOOL32 EVENT_Operation( HANDLE32 handle, enum event_op op )
+{
+    struct event_op_request req;
+
+    req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
+                                         K32OBJ_EVENT, EVENT_MODIFY_STATE );
+    if (req.handle == -1) return FALSE;
+    req.op = op;
+    CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
+    return !CLIENT_WaitReply( NULL, NULL, 0 );
+}
+
+
+/***********************************************************************
  *           PulseEvent    (KERNEL32.557)
  */
 BOOL32 WINAPI PulseEvent( HANDLE32 handle )
 {
-    struct event_op_request req;
-    EVENT *event;
-    SYSTEM_LOCK();
-    if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
-                                            K32OBJ_EVENT, EVENT_MODIFY_STATE,
-                                            &req.handle )))
-    {
-        SYSTEM_UNLOCK();
-        return FALSE;
-    }
-    if (req.handle != -1)
-    {
-        SYSTEM_UNLOCK();
-        req.op = PULSE_EVENT;
-        CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
-        return !CLIENT_WaitReply( NULL, NULL, 0 );
-    }
-    event->signaled = TRUE;
-    SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
-    event->signaled = FALSE;
-    K32OBJ_DecCount( &event->header );
-    SYSTEM_UNLOCK();
-    return TRUE;
+    return EVENT_Operation( handle, PULSE_EVENT );
 }
 
 
@@ -204,28 +159,7 @@
  */
 BOOL32 WINAPI SetEvent( HANDLE32 handle )
 {
-    struct event_op_request req;
-    EVENT *event;
-    SYSTEM_LOCK();
-    if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
-                                            K32OBJ_EVENT, EVENT_MODIFY_STATE,
-                                            &req.handle )))
-    {
-        SYSTEM_UNLOCK();
-        return FALSE;
-    }
-    if (req.handle != -1)
-    {
-        SYSTEM_UNLOCK();
-        req.op = SET_EVENT;
-        CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
-        return !CLIENT_WaitReply( NULL, NULL, 0 );
-    }
-    event->signaled = TRUE;
-    SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
-    K32OBJ_DecCount( &event->header );
-    SYSTEM_UNLOCK();
-    return TRUE;
+    return EVENT_Operation( handle, SET_EVENT );
 }
 
 
@@ -234,79 +168,7 @@
  */
 BOOL32 WINAPI ResetEvent( HANDLE32 handle )
 {
-    struct event_op_request req;
-    EVENT *event;
-    SYSTEM_LOCK();
-    if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
-                                            K32OBJ_EVENT, EVENT_MODIFY_STATE,
-                                            &req.handle )))
-    {
-        SYSTEM_UNLOCK();
-        return FALSE;
-    }
-    if (req.handle != -1)
-    {
-        SYSTEM_UNLOCK();
-        req.op = RESET_EVENT;
-        CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
-        return !CLIENT_WaitReply( NULL, NULL, 0 );
-    }
-    event->signaled = FALSE;
-    K32OBJ_DecCount( &event->header );
-    SYSTEM_UNLOCK();
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           EVENT_Signaled
- */
-static BOOL32 EVENT_Signaled( K32OBJ *obj, DWORD thread_id )
-{
-    EVENT *event = (EVENT *)obj;
-    assert( obj->type == K32OBJ_EVENT );
-    return event->signaled;
-}
-
-
-/***********************************************************************
- *           EVENT_Satisfied
- *
- * Wait on this object has been satisfied.
- */
-static BOOL32 EVENT_Satisfied( K32OBJ *obj, DWORD thread_id )
-{
-    EVENT *event = (EVENT *)obj;
-    assert( obj->type == K32OBJ_EVENT );
-    /* Reset if it's an auto-reset event */
-    if (!event->manual_reset) event->signaled = FALSE;
-    return FALSE;  /* Not abandoned */
-}
-
-
-/***********************************************************************
- *           EVENT_AddWait
- *
- * Add thread to object wait queue.
- */
-static void EVENT_AddWait( K32OBJ *obj, DWORD thread_id )
-{
-    EVENT *event = (EVENT *)obj;
-    assert( obj->type == K32OBJ_EVENT );
-    THREAD_AddQueue( &event->wait_queue, THREAD_ID_TO_THDB(thread_id) );
-}
-
-
-/***********************************************************************
- *           EVENT_RemoveWait
- *
- * Remove thread from object wait queue.
- */
-static void EVENT_RemoveWait( K32OBJ *obj, DWORD thread_id )
-{
-    EVENT *event = (EVENT *)obj;
-    assert( obj->type == K32OBJ_EVENT );
-    THREAD_RemoveQueue( &event->wait_queue, THREAD_ID_TO_THDB(thread_id) );
+    return EVENT_Operation( handle, RESET_EVENT );
 }
 
 
@@ -317,8 +179,6 @@
 {
     EVENT *event = (EVENT *)obj;
     assert( obj->type == K32OBJ_EVENT );
-    /* There cannot be any thread on the list since the ref count is 0 */
-    assert( event->wait_queue == NULL );
     obj->type = K32OBJ_UNKNOWN;
     HeapFree( SystemHeap, 0, event );
 }
diff --git a/scheduler/handle.c b/scheduler/handle.c
index 5abf0a6..ec34184 100644
--- a/scheduler/handle.c
+++ b/scheduler/handle.c
@@ -192,6 +192,27 @@
 
 
 /***********************************************************************
+ *           HANDLE_GetServerHandle
+ *
+ * Retrieve the server handle associated to an object.
+ */
+int HANDLE_GetServerHandle( PDB32 *pdb, HANDLE32 handle,
+                            K32OBJ_TYPE type, DWORD access )
+{
+    int server_handle;
+    K32OBJ *obj;
+
+    SYSTEM_LOCK();
+    if ((obj = HANDLE_GetObjPtr( pdb, handle, type, access, &server_handle )))
+        K32OBJ_DecCount( obj );
+    else
+        server_handle = -1;
+    SYSTEM_UNLOCK();
+    return server_handle;
+}
+
+
+/***********************************************************************
  *           HANDLE_SetObjPtr
  *
  * Change the object pointer of a handle, and increment the refcount.
@@ -413,3 +434,38 @@
     SYSTEM_UNLOCK();
     return ret;
 }
+
+
+/***********************************************************************
+ *           ConvertToGlobalHandle    		(KERNEL32)
+ */
+HANDLE32 WINAPI ConvertToGlobalHandle(HANDLE32 hSrc)
+{
+    int src_handle, dst_handle;
+    HANDLE32 handle;
+    K32OBJ *obj = NULL;
+    DWORD access;
+
+    if (HANDLE_IS_GLOBAL(hSrc))
+        return hSrc;
+
+    if (!(obj = HANDLE_GetObjPtr( PROCESS_Current(), hSrc, K32OBJ_UNKNOWN, 0, &src_handle )))
+        return 0;
+
+    HANDLE_GetAccess( PROCESS_Current(), hSrc, &access );
+
+    if (src_handle != -1)
+        dst_handle = CLIENT_DuplicateHandle( GetCurrentProcess(), src_handle, -1, -1, 0, FALSE,
+                                             DUP_HANDLE_MAKE_GLOBAL | DUP_HANDLE_SAME_ACCESS );
+    else
+        dst_handle = -1;
+
+    if ((handle = HANDLE_Alloc( PROCESS_Initial(), obj, access, FALSE,
+                                dst_handle )) != INVALID_HANDLE_VALUE32)
+        handle = HANDLE_LOCAL_TO_GLOBAL(handle);
+    else
+        handle = 0;
+
+    CloseHandle( hSrc );
+    return handle;
+}
diff --git a/scheduler/k32obj.c b/scheduler/k32obj.c
index d8aca63..a0b8e82 100644
--- a/scheduler/k32obj.c
+++ b/scheduler/k32obj.c
@@ -12,7 +12,6 @@
 
 
 /* The declarations are here to avoid including a lot of unnecessary files */
-extern const K32OBJ_OPS CRITICAL_SECTION_Ops;
 extern const K32OBJ_OPS PROCESS_Ops;
 extern const K32OBJ_OPS THREAD_Ops;
 extern const K32OBJ_OPS FILE_Ops;
@@ -30,12 +29,6 @@
 
 static const K32OBJ_OPS K32OBJ_NullOps =
 {
-    NULL,    /* signaled */
-    NULL,    /* satisfied */
-    NULL,    /* add_wait */
-    NULL,    /* remove_wait */
-    NULL,    /* read */
-    NULL,    /* write */
     NULL     /* destroy */
 };
 
@@ -45,7 +38,7 @@
     &SEMAPHORE_Ops,         /* K32OBJ_SEMAPHORE */
     &EVENT_Ops,             /* K32OBJ_EVENT */
     &MUTEX_Ops,             /* K32OBJ_MUTEX */
-    &CRITICAL_SECTION_Ops,  /* K32OBJ_CRITICAL_SECTION */
+    &K32OBJ_NullOps,        /* K32OBJ_CRITICAL_SECTION */
     &PROCESS_Ops,           /* K32OBJ_PROCESS */
     &THREAD_Ops,            /* K32OBJ_THREAD */
     &FILE_Ops,              /* K32OBJ_FILE */
diff --git a/scheduler/mutex.c b/scheduler/mutex.c
index 4a32e15..05c72ed 100644
--- a/scheduler/mutex.c
+++ b/scheduler/mutex.c
@@ -17,67 +17,17 @@
 typedef struct _MUTEX
 {
     K32OBJ         header;
-    THREAD_QUEUE   wait_queue;
-    DWORD          owner;
-    DWORD          count;
-    BOOL32         abandoned;
-    struct _MUTEX *next;
-    struct _MUTEX *prev;
 } MUTEX;
 
-static BOOL32 MUTEX_Signaled( K32OBJ *obj, DWORD thread_id );
-static BOOL32 MUTEX_Satisfied( K32OBJ *obj, DWORD thread_id );
-static void MUTEX_AddWait( K32OBJ *obj, DWORD thread_id );
-static void MUTEX_RemoveWait( K32OBJ *obj, DWORD thread_id );
 static void MUTEX_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS MUTEX_Ops =
 {
-    MUTEX_Signaled,    /* signaled */
-    MUTEX_Satisfied,   /* satisfied */
-    MUTEX_AddWait,     /* add_wait */
-    MUTEX_RemoveWait,  /* remove_wait */
-    NULL,              /* read */
-    NULL,              /* write */
     MUTEX_Destroy      /* destroy */
 };
 
 
 /***********************************************************************
- *           MUTEX_Release
- *
- * Release a mutex once the count is 0.
- * Helper function for MUTEX_Abandon and ReleaseMutex.
- */
-static void MUTEX_Release( MUTEX *mutex )
-{
-    /* Remove the mutex from the thread list of owned mutexes */
-    if (mutex->next) mutex->next->prev = mutex->prev;
-    if (mutex->prev) mutex->prev->next = mutex->next;
-    else THREAD_Current()->mutex_list = &mutex->next->header;
-    mutex->next = mutex->prev = NULL;
-    mutex->owner = 0;
-    SYNC_WakeUp( &mutex->wait_queue, INFINITE32 );
-}
-
-
-/***********************************************************************
- *           MUTEX_Abandon
- *
- * Abandon a mutex.
- */
-void MUTEX_Abandon( K32OBJ *obj )
-{
-    MUTEX *mutex = (MUTEX *)obj;
-    assert( obj->type == K32OBJ_MUTEX );
-    assert( mutex->count && (mutex->owner == GetCurrentThreadId()) );
-    mutex->count = 0;
-    mutex->abandoned = TRUE;
-    MUTEX_Release( mutex );
-}
-
-
-/***********************************************************************
  *           CreateMutex32A   (KERNEL32.166)
  */
 HANDLE32 WINAPI CreateMutex32A( SECURITY_ATTRIBUTES *sa, BOOL32 owner,
@@ -95,37 +45,14 @@
     CLIENT_SendRequest( REQ_CREATE_MUTEX, -1, 2, &req, sizeof(req), name, len );
     CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
     CHECK_LEN( len, sizeof(reply) );
-    if (reply.handle == -1) return NULL;
+    if (reply.handle == -1) return 0;
 
     SYSTEM_LOCK();
     mutex = (MUTEX *)K32OBJ_Create( K32OBJ_MUTEX, sizeof(*mutex),
                                     name, reply.handle, MUTEX_ALL_ACCESS,
                                     sa, &handle );
-    if (mutex)
-    {
-        /* Finish initializing it */
-        mutex->wait_queue = NULL;
-        mutex->abandoned  = FALSE;
-        mutex->prev       = NULL;
-        if (owner)
-        {
-            K32OBJ **list;
-            mutex->owner = GetCurrentThreadId();
-            mutex->count = 1;
-            /* Add the mutex in the thread list of owned mutexes */
-            list = &THREAD_Current()->mutex_list;
-            if ((mutex->next = (MUTEX *)*list)) mutex->next->prev = mutex;
-            *list = &mutex->header;
-        }
-        else
-        {
-            mutex->owner = 0;
-            mutex->count = 0;
-            mutex->next  = NULL;
-        }
-        K32OBJ_DecCount( &mutex->header );
-    }
-    SetLastError(0); /* FIXME */
+    if (mutex) K32OBJ_DecCount( &mutex->header );
+    if (handle == INVALID_HANDLE_VALUE32) handle = 0;
     SYSTEM_UNLOCK();
     return handle;
 }
@@ -151,13 +78,29 @@
 {
     HANDLE32 handle = 0;
     K32OBJ *obj;
-    SYSTEM_LOCK();
-    if ((obj = K32OBJ_FindNameType( name, K32OBJ_MUTEX )) != NULL)
+    struct open_named_obj_request req;
+    struct open_named_obj_reply reply;
+    int len = name ? strlen(name) + 1 : 0;
+
+    req.type    = OPEN_MUTEX;
+    req.access  = access;
+    req.inherit = inherit;
+    CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
+    CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
+    CHECK_LEN( len, sizeof(reply) );
+    if (reply.handle != -1)
     {
-        handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, -1 );
-        K32OBJ_DecCount( obj );
+        SYSTEM_LOCK();
+        if ((obj = K32OBJ_FindNameType( name, K32OBJ_MUTEX )) != NULL)
+        {
+            handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, reply.handle );
+            K32OBJ_DecCount( obj );
+            if (handle == INVALID_HANDLE_VALUE32)
+                handle = 0; /* must return 0 on failure, not -1 */
+        }
+        else CLIENT_CloseHandle( reply.handle );
+        SYSTEM_UNLOCK();
     }
-    SYSTEM_UNLOCK();
     return handle;
 }
 
@@ -180,95 +123,12 @@
 BOOL32 WINAPI ReleaseMutex( HANDLE32 handle )
 {
     struct release_mutex_request req;
-    MUTEX *mutex;
-    SYSTEM_LOCK();
-    if (!(mutex = (MUTEX *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
-                                            K32OBJ_MUTEX, MUTEX_MODIFY_STATE,
-                                            &req.handle )))
-    {
-        SYSTEM_UNLOCK();
-        return FALSE;
-    }
-    if (req.handle != -1)
-    {
-        SYSTEM_UNLOCK();
-        CLIENT_SendRequest( REQ_RELEASE_MUTEX, -1, 1, &req, sizeof(req) );
-        return !CLIENT_WaitReply( NULL, NULL, 0 );
-    }
-    if (!mutex->count || (mutex->owner != GetCurrentThreadId()))
-    {
-        SYSTEM_UNLOCK();
-        SetLastError( ERROR_NOT_OWNER );
-        return FALSE;
-    }
-    if (!--mutex->count) MUTEX_Release( mutex );
-    K32OBJ_DecCount( &mutex->header );
-    SYSTEM_UNLOCK();
-    return TRUE;
-}
 
-
-/***********************************************************************
- *           MUTEX_Signaled
- */
-static BOOL32 MUTEX_Signaled( K32OBJ *obj, DWORD thread_id )
-{
-    MUTEX *mutex = (MUTEX *)obj;
-    assert( obj->type == K32OBJ_MUTEX );
-    return (!mutex->count || (mutex->owner == thread_id));
-}
-
-
-/***********************************************************************
- *           MUTEX_Satisfied
- *
- * Wait on this object has been satisfied.
- */
-static BOOL32 MUTEX_Satisfied( K32OBJ *obj, DWORD thread_id )
-{
-    BOOL32 ret;
-    MUTEX *mutex = (MUTEX *)obj;
-    assert( obj->type == K32OBJ_MUTEX );
-    assert( !mutex->count || (mutex->owner == thread_id) );
-    mutex->owner = thread_id;
-    if (!mutex->count++)
-    {
-        /* Add the mutex in the thread list of owned mutexes */
-        K32OBJ **list = &THREAD_ID_TO_THDB( thread_id )->mutex_list;
-        assert( !mutex->next );
-        if ((mutex->next = (MUTEX *)*list)) mutex->next->prev = mutex;
-        *list = &mutex->header;
-        mutex->prev = NULL;
-    }
-    ret = mutex->abandoned;
-    mutex->abandoned = FALSE;
-    return ret;
-}
-
-
-/***********************************************************************
- *           MUTEX_AddWait
- *
- * Add a thread to the object wait queue.
- */
-static void MUTEX_AddWait( K32OBJ *obj, DWORD thread_id )
-{
-    MUTEX *mutex = (MUTEX *)obj;
-    assert( obj->type == K32OBJ_MUTEX );
-    THREAD_AddQueue( &mutex->wait_queue, THREAD_ID_TO_THDB(thread_id) );
-}
-
-
-/***********************************************************************
- *           MUTEX_RemoveWait
- *
- * Remove a thread from the object wait queue.
- */
-static void MUTEX_RemoveWait( K32OBJ *obj, DWORD thread_id )
-{
-    MUTEX *mutex = (MUTEX *)obj;
-    assert( obj->type == K32OBJ_MUTEX );
-    THREAD_RemoveQueue( &mutex->wait_queue, THREAD_ID_TO_THDB(thread_id) );
+    req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
+                                         K32OBJ_MUTEX, MUTEX_MODIFY_STATE );
+    if (req.handle == -1) return FALSE;
+    CLIENT_SendRequest( REQ_RELEASE_MUTEX, -1, 1, &req, sizeof(req) );
+    return !CLIENT_WaitReply( NULL, NULL, 0 );
 }
 
 
@@ -279,8 +139,6 @@
 {
     MUTEX *mutex = (MUTEX *)obj;
     assert( obj->type == K32OBJ_MUTEX );
-    /* There cannot be any thread on the list since the ref count is 0 */
-    assert( mutex->wait_queue == NULL );
     obj->type = K32OBJ_UNKNOWN;
     HeapFree( SystemHeap, 0, mutex );
 }
diff --git a/scheduler/pipe.c b/scheduler/pipe.c
index 8548013..94279fb 100644
--- a/scheduler/pipe.c
+++ b/scheduler/pipe.c
@@ -23,12 +23,6 @@
 
 const K32OBJ_OPS PIPE_Ops =
 {
-    NULL,             /* signaled */
-    NULL,             /* satisfied */
-    NULL,             /* add_wait */
-    NULL,             /* remove_wait */
-    NULL,             /* read */
-    NULL,             /* write */
     PIPE_Destroy      /* destroy */
 };
 
diff --git a/scheduler/process.c b/scheduler/process.c
index 1432ea7..6ddc950 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -23,20 +23,10 @@
 #include "server.h"
 #include "debug.h"
 
-static BOOL32 PROCESS_Signaled( K32OBJ *obj, DWORD thread_id );
-static BOOL32 PROCESS_Satisfied( K32OBJ *obj, DWORD thread_id );
-static void PROCESS_AddWait( K32OBJ *obj, DWORD thread_id );
-static void PROCESS_RemoveWait( K32OBJ *obj, DWORD thread_id );
 static void PROCESS_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS PROCESS_Ops =
 {
-    PROCESS_Signaled,    /* signaled */
-    PROCESS_Satisfied,   /* satisfied */
-    PROCESS_AddWait,     /* add_wait */
-    PROCESS_RemoveWait,  /* remove_wait */
-    NULL,                /* read */
-    NULL,                /* write */
     PROCESS_Destroy      /* destroy */
 };
 
@@ -295,8 +285,6 @@
     if (pdb->handle_table) HANDLE_CloseAll( pdb, NULL );
     ENV_FreeEnvironment( pdb );
     if (pdb->heap && (pdb->heap != pdb->system_heap)) HeapDestroy( pdb->heap );
-    if (pdb->load_done_evt) K32OBJ_DecCount( pdb->load_done_evt );
-    if (pdb->event) K32OBJ_DecCount( pdb->event );
     DeleteCriticalSection( &pdb->crit_section );
     HeapFree( SystemHeap, 0, pdb );
 }
@@ -325,19 +313,11 @@
     pdb->priority        = 8;  /* Normal */
     pdb->heap            = pdb->system_heap;  /* will be changed later on */
 
-    InitializeCriticalSection( &pdb->crit_section );
-
-    /* Allocate the events */
-
-    if (!(pdb->event = EVENT_Create( TRUE, FALSE ))) goto error;
-    if (!(pdb->load_done_evt = EVENT_Create( TRUE, FALSE ))) goto error;
-
     /* Create the handle table */
 
     if (!HANDLE_CreateTable( pdb, TRUE )) goto error;
 
     PROCESS_PDBList_Insert (pdb);
-
     return pdb;
 
 error:
@@ -347,6 +327,21 @@
 
 
 /***********************************************************************
+ *           PROCESS_FinishCreatePDB
+ *
+ * Second part of CreatePDB
+ */
+static BOOL32 PROCESS_FinishCreatePDB( PDB32 *pdb )
+{
+    InitializeCriticalSection( &pdb->crit_section );
+    /* Allocate the event */
+    if (!(pdb->load_done_evt = CreateEvent32A( NULL, TRUE, FALSE, NULL )))
+        return FALSE;
+    return TRUE;
+}
+
+
+/***********************************************************************
  *           PROCESS_Init
  */
 BOOL32 PROCESS_Init(void)
@@ -357,9 +352,8 @@
     /* Initialize virtual memory management */
     if (!VIRTUAL_Init()) return FALSE;
 
-    /* Create the system and SEGPTR heaps */
+    /* Create the system heaps */
     if (!(SystemHeap = HeapCreate( HEAP_GROWABLE, 0x10000, 0 ))) return FALSE;
-    if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE;
 
     /* Create the initial process and thread structures */
     if (!(pdb = PROCESS_CreatePDB( NULL ))) return FALSE;
@@ -376,6 +370,10 @@
 
     /* Initialize the first thread */
     if (CLIENT_InitThread()) return FALSE;
+    if (!PROCESS_FinishCreatePDB( pdb )) return FALSE;
+
+    /* Create the SEGPTR heap */
+    if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE;
 
     return TRUE;
 }
@@ -400,6 +398,7 @@
 
     if (!pdb) return NULL;
     info->hThread = info->hProcess = INVALID_HANDLE_VALUE32;
+    if (!PROCESS_FinishCreatePDB( pdb )) goto error;
 
     /* Create the heap */
 
@@ -473,56 +472,6 @@
 
 
 /***********************************************************************
- *           PROCESS_Signaled
- */
-static BOOL32 PROCESS_Signaled( K32OBJ *obj, DWORD thread_id )
-{
-    PDB32 *pdb = (PDB32 *)obj;
-    assert( obj->type == K32OBJ_PROCESS );
-    return K32OBJ_OPS( pdb->event )->signaled( pdb->event, thread_id );
-}
-
-
-/***********************************************************************
- *           PROCESS_Satisfied
- *
- * Wait on this object has been satisfied.
- */
-static BOOL32 PROCESS_Satisfied( K32OBJ *obj, DWORD thread_id )
-{
-    PDB32 *pdb = (PDB32 *)obj;
-    assert( obj->type == K32OBJ_PROCESS );
-    return K32OBJ_OPS( pdb->event )->satisfied( pdb->event, thread_id );
-}
-
-
-/***********************************************************************
- *           PROCESS_AddWait
- *
- * Add thread to object wait queue.
- */
-static void PROCESS_AddWait( K32OBJ *obj, DWORD thread_id )
-{
-    PDB32 *pdb = (PDB32 *)obj;
-    assert( obj->type == K32OBJ_PROCESS );
-    return K32OBJ_OPS( pdb->event )->add_wait( pdb->event, thread_id );
-}
-
-
-/***********************************************************************
- *           PROCESS_RemoveWait
- *
- * Remove thread from object wait queue.
- */
-static void PROCESS_RemoveWait( K32OBJ *obj, DWORD thread_id )
-{
-    PDB32 *pdb = (PDB32 *)obj;
-    assert( obj->type == K32OBJ_PROCESS );
-    return K32OBJ_OPS( pdb->event )->remove_wait( pdb->event, thread_id );
-}
-
-
-/***********************************************************************
  *           PROCESS_Destroy
  */
 static void PROCESS_Destroy( K32OBJ *ptr )
@@ -552,7 +501,6 @@
     SYSTEM_LOCK();
     /* FIXME: should kill all running threads of this process */
     pdb->exit_code = status;
-    EVENT_Set( pdb->event );
     if (pdb->console) FreeConsole();
     SYSTEM_UNLOCK();
 
@@ -566,13 +514,13 @@
  */
 BOOL32 WINAPI TerminateProcess( HANDLE32 handle, DWORD exit_code )
 {
-    int server_handle;
-    BOOL32 ret;
-    PDB32 *pdb = PROCESS_GetPtr( handle, PROCESS_TERMINATE, &server_handle );
-    if (!pdb) return FALSE;
-    ret = !CLIENT_TerminateProcess( server_handle, exit_code );
-    K32OBJ_DecCount( &pdb->header );
-    return ret;
+    struct terminate_process_request req;
+
+    req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
+                                         K32OBJ_PROCESS, PROCESS_TERMINATE );
+    req.exit_code = exit_code;
+    CLIENT_SendRequest( REQ_TERMINATE_PROCESS, -1, 1, &req, sizeof(req) );
+    return !CLIENT_WaitReply( NULL, NULL, 0 );
 }
 
 /***********************************************************************
@@ -832,8 +780,8 @@
  * It really shouldn't be here, but I'll move it when it's been checked!
  */
 #define SHUTDOWN_NORETRY 1
-extern unsigned int shutdown_noretry = 0;
-extern unsigned int shutdown_priority = 0x280L;
+static unsigned int shutdown_noretry = 0;
+static unsigned int shutdown_priority = 0x280L;
 BOOL32 WINAPI SetProcessShutdownParameters(DWORD level,DWORD flags)
 {
     if (flags & SHUTDOWN_NORETRY)
@@ -901,28 +849,6 @@
 }
 
 /***********************************************************************
- *           ConvertToGlobalHandle    		(KERNEL32)
- */
-HANDLE32 WINAPI ConvertToGlobalHandle(HANDLE32 hSrc)
-{
-    HANDLE32 hProcessInit, hDest;
-
-    /* Get a handle to the initial process */
-    hProcessInit = OpenProcess( PROCESS_ALL_ACCESS, FALSE, PROCESS_InitialProcessID );
-
-    /* Duplicate the handle into the initial process */
-    if ( !DuplicateHandle( GetCurrentProcess(), hSrc, hProcessInit, &hDest,
-                           0, FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE ) )
-        hDest = 0;
-
-    /* Close initial process handle */
-    CloseHandle( hProcessInit );
-
-    /* Return obfuscated global handle */
-    return hDest? HANDLE_LOCAL_TO_GLOBAL( hDest ) : 0;
-}
-
-/***********************************************************************
  *           RegisterServiceProcess             (KERNEL, KERNEL32)
  *
  * A service process calls this function to ensure that it continues to run
@@ -942,28 +868,17 @@
  * RETURNS
  *   Success: TRUE
  *   Failure: FALSE
- * 
- * FIXME
- *   Should call SetLastError (but doesn't).
  */
 BOOL32 WINAPI GetExitCodeProcess(
     HANDLE32 hProcess,  /* [I] handle to the process */
     LPDWORD lpExitCode) /* [O] address to receive termination status */
 {
-    PDB32 *process;
-    int server_handle;
     struct get_process_info_reply info;
+    int handle = HANDLE_GetServerHandle( PROCESS_Current(), hProcess,
+                                         K32OBJ_PROCESS, PROCESS_QUERY_INFORMATION );
 
-    if (!(process = PROCESS_GetPtr( hProcess, PROCESS_QUERY_INFORMATION,
-                                    &server_handle )))
-        return FALSE;
-    if (server_handle != -1)
-    {
-        CLIENT_GetProcessInfo( server_handle, &info );
-        if (lpExitCode) *lpExitCode = info.exit_code;
-    }
-    else if (lpExitCode) *lpExitCode = process->exit_code;
-    K32OBJ_DecCount( &process->header );
+    if (CLIENT_GetProcessInfo( handle, &info )) return FALSE;
+    if (lpExitCode) *lpExitCode = info.exit_code;
     return TRUE;
 }
 
diff --git a/scheduler/semaphore.c b/scheduler/semaphore.c
index 7c71a10..561d536 100644
--- a/scheduler/semaphore.c
+++ b/scheduler/semaphore.c
@@ -17,25 +17,12 @@
 typedef struct
 {
     K32OBJ        header;
-    THREAD_QUEUE  wait_queue;
-    LONG          count;
-    LONG          max;
 } SEMAPHORE;
 
-static BOOL32 SEMAPHORE_Signaled( K32OBJ *obj, DWORD thread_id );
-static BOOL32 SEMAPHORE_Satisfied( K32OBJ *obj, DWORD thread_id );
-static void SEMAPHORE_AddWait( K32OBJ *obj, DWORD thread_id );
-static void SEMAPHORE_RemoveWait( K32OBJ *obj, DWORD thread_id );
 static void SEMAPHORE_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS SEMAPHORE_Ops =
 {
-    SEMAPHORE_Signaled,    /* signaled */
-    SEMAPHORE_Satisfied,   /* satisfied */
-    SEMAPHORE_AddWait,     /* add_wait */
-    SEMAPHORE_RemoveWait,  /* remove_wait */
-    NULL,                  /* read */
-    NULL,                  /* write */
     SEMAPHORE_Destroy      /* destroy */
 };
 
@@ -57,7 +44,7 @@
     if ((max <= 0) || (initial < 0) || (initial > max))
     {
         SetLastError( ERROR_INVALID_PARAMETER );
-        return INVALID_HANDLE_VALUE32;
+        return 0;
     }
 
     req.initial = (unsigned int)initial;
@@ -67,21 +54,15 @@
     CLIENT_SendRequest( REQ_CREATE_SEMAPHORE, -1, 2, &req, sizeof(req), name, len );
     CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
     CHECK_LEN( len, sizeof(reply) );
-    if (reply.handle == -1) return NULL;
+    if (reply.handle == -1) return 0;
 
     SYSTEM_LOCK();
     sem = (SEMAPHORE *)K32OBJ_Create( K32OBJ_SEMAPHORE, sizeof(*sem),
                                       name, reply.handle, SEMAPHORE_ALL_ACCESS,
                                       sa, &handle);
-    if (sem)
-    {
-        /* Finish initializing it */
-        sem->wait_queue = NULL;
-        sem->count      = initial;
-        sem->max        = max;
-        K32OBJ_DecCount( &sem->header );
-    }
+    if (sem) K32OBJ_DecCount( &sem->header );
     SYSTEM_UNLOCK();
+    if (handle == INVALID_HANDLE_VALUE32) handle = 0;
     return handle;
 }
 
@@ -106,13 +87,29 @@
 {
     HANDLE32 handle = 0;
     K32OBJ *obj;
-    SYSTEM_LOCK();
-    if ((obj = K32OBJ_FindNameType( name, K32OBJ_SEMAPHORE )) != NULL)
+    struct open_named_obj_request req;
+    struct open_named_obj_reply reply;
+    int len = name ? strlen(name) + 1 : 0;
+
+    req.type    = OPEN_SEMAPHORE;
+    req.access  = access;
+    req.inherit = inherit;
+    CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
+    CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
+    CHECK_LEN( len, sizeof(reply) );
+    if (reply.handle != -1)
     {
-        handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, -1 );
-        K32OBJ_DecCount( obj );
+        SYSTEM_LOCK();
+        if ((obj = K32OBJ_FindNameType( name, K32OBJ_SEMAPHORE )) != NULL)
+        {
+            handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, reply.handle );
+            K32OBJ_DecCount( obj );
+            if (handle == INVALID_HANDLE_VALUE32)
+                handle = 0; /* must return 0 on failure, not -1 */
+        }
+        else CLIENT_CloseHandle( reply.handle );
+        SYSTEM_UNLOCK();
     }
-    SYSTEM_UNLOCK();
     return handle;
 }
 
@@ -135,111 +132,27 @@
 BOOL32 WINAPI ReleaseSemaphore( HANDLE32 handle, LONG count, LONG *previous )
 {
     struct release_semaphore_request req;
-    SEMAPHORE *sem;
+    struct release_semaphore_reply reply;
+    int len;
 
     if (count < 0)
     {
         SetLastError( ERROR_INVALID_PARAMETER );
         return FALSE;
     }
-    SYSTEM_LOCK();
-    if (!(sem = (SEMAPHORE *)HANDLE_GetObjPtr( PROCESS_Current(), handle,
-                                               K32OBJ_SEMAPHORE,
-                                               SEMAPHORE_MODIFY_STATE, &req.handle )))
-    {
-        SYSTEM_UNLOCK();
-        return FALSE;
-    }
-    if (req.handle != -1)
-    {
-        struct release_semaphore_reply reply;
-        int len;
-
-        SYSTEM_UNLOCK();
-        req.count = (unsigned int)count;
-        CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) );
-        if (CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) )) return FALSE;
-        CHECK_LEN( len, sizeof(reply) );
-        if (previous) *previous = reply.prev_count;
-        return TRUE;
-    }
-    if (previous) *previous = sem->count;
-    if (sem->count + count > sem->max)
-    {
-        SYSTEM_UNLOCK();
-        SetLastError( ERROR_TOO_MANY_POSTS );
-        return FALSE;
-    }
-    if (sem->count > 0)
-    {
-        /* There cannot be any thread waiting if the count is > 0 */
-        assert( sem->wait_queue == NULL );
-        sem->count += count;
-    }
-    else
-    {
-        sem->count = count;
-        SYNC_WakeUp( &sem->wait_queue, count );
-    }
-    K32OBJ_DecCount( &sem->header );
-    SYSTEM_UNLOCK();
+    req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
+                                         K32OBJ_SEMAPHORE, SEMAPHORE_MODIFY_STATE );
+    if (req.handle == -1) return FALSE;
+    req.count = (unsigned int)count;
+    CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) );
+    if (CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) )) return FALSE;
+    CHECK_LEN( len, sizeof(reply) );
+    if (previous) *previous = reply.prev_count;
     return TRUE;
 }
 
 
 /***********************************************************************
- *           SEMAPHORE_Signaled
- */
-static BOOL32 SEMAPHORE_Signaled( K32OBJ *obj, DWORD thread_id )
-{
-    SEMAPHORE *sem = (SEMAPHORE *)obj;
-    assert( obj->type == K32OBJ_SEMAPHORE );
-    return (sem->count > 0);
-}
-
-
-/***********************************************************************
- *           SEMAPHORE_Satisfied
- *
- * Wait on this object has been satisfied.
- */
-static BOOL32 SEMAPHORE_Satisfied( K32OBJ *obj, DWORD thread_id )
-{
-    SEMAPHORE *sem = (SEMAPHORE *)obj;
-    assert( obj->type == K32OBJ_SEMAPHORE );
-    assert( sem->count > 0 );
-    sem->count--;
-    return FALSE;  /* Not abandoned */
-}
-
-
-/***********************************************************************
- *           SEMAPHORE_AddWait
- *
- * Add current thread to object wait queue.
- */
-static void SEMAPHORE_AddWait( K32OBJ *obj, DWORD thread_id )
-{
-    SEMAPHORE *sem = (SEMAPHORE *)obj;
-    assert( obj->type == K32OBJ_SEMAPHORE );
-    THREAD_AddQueue( &sem->wait_queue, THREAD_ID_TO_THDB(thread_id) );
-}
-
-
-/***********************************************************************
- *           SEMAPHORE_RemoveWait
- *
- * Remove thread from object wait queue.
- */
-static void SEMAPHORE_RemoveWait( K32OBJ *obj, DWORD thread_id )
-{
-    SEMAPHORE *sem = (SEMAPHORE *)obj;
-    assert( obj->type == K32OBJ_SEMAPHORE );
-    THREAD_RemoveQueue( &sem->wait_queue, THREAD_ID_TO_THDB(thread_id) );
-}
-
-
-/***********************************************************************
  *           SEMAPHORE_Destroy
  */
 static void SEMAPHORE_Destroy( K32OBJ *obj )
@@ -247,7 +160,6 @@
     SEMAPHORE *sem = (SEMAPHORE *)obj;
     assert( obj->type == K32OBJ_SEMAPHORE );
     /* There cannot be any thread on the list since the ref count is 0 */
-    assert( sem->wait_queue == NULL );
     obj->type = K32OBJ_UNKNOWN;
     HeapFree( SystemHeap, 0, sem );
 }
diff --git a/scheduler/synchro.c b/scheduler/synchro.c
index 9fdea03..f2f4560 100644
--- a/scheduler/synchro.c
+++ b/scheduler/synchro.c
@@ -24,7 +24,7 @@
                                     BOOL32 wait_all, BOOL32 wait_msg, 
                                     WAIT_STRUCT *wait )
 {
-    DWORD i, j;
+    DWORD i;
     K32OBJ **ptr;
 
     SYSTEM_LOCK();
@@ -32,7 +32,6 @@
     wait->signaled = WAIT_FAILED;
     wait->wait_all = wait_all;
     wait->wait_msg = wait_msg;
-    wait->use_server = TRUE;
     for (i = 0, ptr = wait->objs; i < count; i++, ptr++)
     {
         if (!(*ptr = HANDLE_GetObjPtr( PROCESS_Current(), handles[i],
@@ -43,28 +42,11 @@
             break; 
         }
         if (wait->server[i] == -1)
-        {
             WARN(win32,"No server handle for %08x (type %d)\n",
                  handles[i], (*ptr)->type );
-            wait->use_server = FALSE;
-        }
     }
 
-    if (!wait->use_server)
-    {
-        for (j = 0, ptr = wait->objs; j < i; j++, ptr++)
-        {
-            if (!K32OBJ_OPS( *ptr )->signaled)
-            {
-                /* This object type cannot be waited upon */
-                ERR(win32, "Cannot wait on handle %08x\n", handles[j]); 
-                break;
-            }
-        }
-    }
-    else j = count;
-
-    if ((i != count) || (j != count))
+    if (i != count)
     {
         /* There was an error */
         wait->wait_msg = FALSE;
@@ -91,224 +73,6 @@
 
 
 /***********************************************************************
- *           SYNC_CheckCondition
- */
-static BOOL32 SYNC_CheckCondition( WAIT_STRUCT *wait, DWORD thread_id )
-{
-    DWORD i;
-    K32OBJ **ptr;
-
-    SYSTEM_LOCK();
-    if (wait->wait_all)
-    {
-        for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++)
-        {
-            if (!K32OBJ_OPS( *ptr )->signaled( *ptr, thread_id ))
-            {
-                SYSTEM_UNLOCK();
-                return FALSE;
-            }
-        }
-        /* Wait satisfied: tell it to all objects */
-        wait->signaled = WAIT_OBJECT_0;
-        for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++)
-            if (K32OBJ_OPS( *ptr )->satisfied( *ptr, thread_id ))
-                wait->signaled = WAIT_ABANDONED_0;
-        SYSTEM_UNLOCK();
-        return TRUE;
-    }
-    else
-    {
-        for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++)
-        {
-            if (K32OBJ_OPS( *ptr )->signaled( *ptr, thread_id ))
-            {
-                /* Wait satisfied: tell it to the object */
-                wait->signaled = WAIT_OBJECT_0 + i;
-                if (K32OBJ_OPS( *ptr )->satisfied( *ptr, thread_id ))
-                    wait->signaled = WAIT_ABANDONED_0 + i;
-                SYSTEM_UNLOCK();
-                return TRUE;
-            }
-        }
-        SYSTEM_UNLOCK();
-        return FALSE;
-    }
-}
-
-
-/***********************************************************************
- *           SYNC_WaitForCondition
- */
-void SYNC_WaitForCondition( WAIT_STRUCT *wait, DWORD timeout )
-{
-    DWORD i, thread_id = GetCurrentThreadId();
-    LONG count;
-    K32OBJ **ptr;
-    sigset_t set;
-
-    SYSTEM_LOCK();
-    if (SYNC_CheckCondition( wait, thread_id ))
-        goto done;  /* Condition already satisfied */
-    if (!timeout)
-    {
-        /* No need to wait */
-        wait->signaled = WAIT_TIMEOUT;
-        goto done;
-    }
-
-    /* Add ourselves to the waiting list of all objects */
-
-    for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++)
-        K32OBJ_OPS( *ptr )->add_wait( *ptr, thread_id );
-
-    /* Release the system lock completely */
-
-    count = SYSTEM_LOCK_COUNT();
-    for (i = count; i > 0; i--) SYSTEM_UNLOCK();
-
-    /* Now wait for it */
-
-    TRACE(win32, "starting wait (%p %04x)\n",
-		 THREAD_Current(), THREAD_Current()->teb_sel );
-
-    sigprocmask( SIG_SETMASK, NULL, &set );
-    sigdelset( &set, SIGUSR1 );
-    sigdelset( &set, SIGALRM );
-    if (timeout != INFINITE32)
-    {
-        while (wait->signaled == WAIT_FAILED)
-        {
-            struct itimerval timer;
-            DWORD start_ticks, elapsed;
-            timer.it_interval.tv_sec = timer.it_interval.tv_usec = 0;
-            timer.it_value.tv_sec = timeout / 1000;
-            timer.it_value.tv_usec = (timeout % 1000) * 1000;
-            start_ticks = GetTickCount();
-            setitimer( ITIMER_REAL, &timer, NULL );
-            sigsuspend( &set );
-            if (wait->signaled != WAIT_FAILED) break;
-            /* Recompute the timer value */
-            elapsed = GetTickCount() - start_ticks;
-            if (elapsed >= timeout) wait->signaled = WAIT_TIMEOUT;
-            else timeout -= elapsed;
-        }
-    }
-    else
-    {
-        while (wait->signaled == WAIT_FAILED)
-        {
-            sigsuspend( &set );
-        }
-    }
-
-    /* Grab the system lock again */
-
-    while (count--) SYSTEM_LOCK();
-    TRACE(win32, "wait finished (%p %04x)\n",
-		 THREAD_Current(), THREAD_Current()->teb_sel );
-
-    /* Remove ourselves from the lists */
-
-    for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++)
-        K32OBJ_OPS( *ptr )->remove_wait( *ptr, thread_id );
-
-done:
-    SYSTEM_UNLOCK();
-}
-
-
-/***********************************************************************
- *           SYNC_DummySigHandler
- *
- * Dummy signal handler
- */
-static void SYNC_DummySigHandler(void)
-{
-}
-
-
-/***********************************************************************
- *           SYNC_SetupSignals
- *
- * Setup signal handlers for a new thread.
- * FIXME: should merge with SIGNAL_Init.
- */
-void SYNC_SetupSignals(void)
-{
-    sigset_t set;
-    SIGNAL_SetHandler( SIGUSR1, SYNC_DummySigHandler, 0 );
-    /* FIXME: conflicts with system timers */
-    SIGNAL_SetHandler( SIGALRM, SYNC_DummySigHandler, 0 );
-    sigemptyset( &set );
-    /* Make sure these are blocked by default */
-    sigaddset( &set, SIGUSR1 );
-    sigaddset( &set, SIGALRM );
-    sigprocmask( SIG_BLOCK , &set, NULL);
-}
-
-
-/***********************************************************************
- *           SYNC_WakeUp
- */
-void SYNC_WakeUp( THREAD_QUEUE *wait_queue, DWORD max )
-{
-    THREAD_ENTRY *entry;
-
-    if (!max) max = INFINITE32;
-    SYSTEM_LOCK();
-    if (!*wait_queue)
-    {
-        SYSTEM_UNLOCK();
-        return;
-    }
-    entry = (*wait_queue)->next;
-    for (;;)
-    {
-        THDB *thdb = entry->thread;
-        if (SYNC_CheckCondition( &thdb->wait_struct, THDB_TO_THREAD_ID(thdb) ))
-        {
-            TRACE(win32, "waking up %04x (pid %d)\n", thdb->teb_sel, thdb->unix_pid );
-            if (thdb->unix_pid)
-	    	kill( thdb->unix_pid, SIGUSR1 );
-	    else
-	    	FIXME(win32,"have got unix_pid 0\n");
-            if (!--max) break;
-        }
-        if (entry == *wait_queue) break;
-        entry = entry->next;
-    }
-    SYSTEM_UNLOCK();
-}
-
-/***********************************************************************
- *           SYNC_MsgWakeUp
- */
-void SYNC_MsgWakeUp( THDB *thdb )
-{
-    SYSTEM_LOCK();
-
-    if (!thdb) 
-    {
-        SYSTEM_UNLOCK();
-        return;
-    }
-
-    if (thdb->wait_struct.wait_msg)
-    {
-        thdb->wait_struct.signaled = thdb->wait_struct.count;
-
-        TRACE(win32, "waking up %04x for message\n", thdb->teb_sel );
-        if (thdb->unix_pid)
-            kill( thdb->unix_pid, SIGUSR1 );
-        else
-            FIXME(win32,"have got unix_pid 0\n");
-    }
-
-    SYSTEM_UNLOCK();
-}
-
-/***********************************************************************
  *           SYNC_DoWait
  */
 DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
@@ -326,30 +90,18 @@
     if (alertable)
         FIXME(win32, "alertable not implemented\n" );
 
-    SYSTEM_LOCK();
     if (!SYNC_BuildWaitStruct( count, handles, wait_all, wait_msg, wait ))
         wait->signaled = WAIT_FAILED;
     else
     {
-        /* Check if we can use a server wait */
-        if (wait->use_server)
-        {
-            int flags = 0;
-            SYSTEM_UNLOCK();
-            if (wait_all) flags |= SELECT_ALL;
-            if (alertable) flags |= SELECT_ALERTABLE;
-            if (wait_msg) flags |= SELECT_MSG;
-            if (timeout != INFINITE32) flags |= SELECT_TIMEOUT;
-            return CLIENT_Select( count, wait->server, flags, timeout );
-        }
-        else
-        {
-            /* Now wait for it */
-            SYNC_WaitForCondition( wait, timeout );
-            SYNC_FreeWaitStruct( wait );
-        }
+        int flags = 0;
+        if (wait_all) flags |= SELECT_ALL;
+        if (alertable) flags |= SELECT_ALERTABLE;
+        if (wait_msg) flags |= SELECT_MSG;
+        if (timeout != INFINITE32) flags |= SELECT_TIMEOUT;
+        wait->signaled = CLIENT_Select( count, wait->server, flags, timeout );
+        SYNC_FreeWaitStruct( wait );
     }
-    SYSTEM_UNLOCK();
     return wait->signaled;
 }
 
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 91eb183..4888ae7 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -25,20 +25,10 @@
 THDB *pCurrentThread;
 #endif
 
-static BOOL32 THREAD_Signaled( K32OBJ *obj, DWORD thread_id );
-static BOOL32 THREAD_Satisfied( K32OBJ *obj, DWORD thread_id );
-static void THREAD_AddWait( K32OBJ *obj, DWORD thread_id );
-static void THREAD_RemoveWait( K32OBJ *obj, DWORD thread_id );
 static void THREAD_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS THREAD_Ops =
 {
-    THREAD_Signaled,    /* signaled */
-    THREAD_Satisfied,   /* satisfied */
-    THREAD_AddWait,     /* add_wait */
-    THREAD_RemoveWait,  /* remove_wait */
-    NULL,               /* read */
-    NULL,               /* write */
     THREAD_Destroy      /* destroy */
 };
 
@@ -234,10 +224,6 @@
                                                  0x10000 - sizeof(STACK16FRAME) );
     }
 
-    /* Allocate the event */
-
-    if (!(thdb->event = EVENT_Create( TRUE, FALSE ))) goto error;
-
     /* Create the thread socket */
 
     if (CLIENT_NewThread( thdb, server_thandle, server_phandle )) goto error;
@@ -274,56 +260,6 @@
 
 
 /***********************************************************************
- *           THREAD_Signaled
- */
-static BOOL32 THREAD_Signaled( K32OBJ *obj, DWORD thread_id )
-{
-    THDB *thdb = (THDB *)obj;
-    assert( obj->type == K32OBJ_THREAD );
-    return K32OBJ_OPS( thdb->event )->signaled( thdb->event, thread_id );
-}
-
-
-/***********************************************************************
- *           THREAD_Satisfied
- *
- * Wait on this object has been satisfied.
- */
-static BOOL32 THREAD_Satisfied( K32OBJ *obj, DWORD thread_id )
-{
-    THDB *thdb = (THDB *)obj;
-    assert( obj->type == K32OBJ_THREAD );
-    return K32OBJ_OPS( thdb->event )->satisfied( thdb->event, thread_id );
-}
-
-
-/***********************************************************************
- *           THREAD_AddWait
- *
- * Add thread to object wait queue.
- */
-static void THREAD_AddWait( K32OBJ *obj, DWORD thread_id )
-{
-    THDB *thdb = (THDB *)obj;
-    assert( obj->type == K32OBJ_THREAD );
-    return K32OBJ_OPS( thdb->event )->add_wait( thdb->event, thread_id );
-}
-
-
-/***********************************************************************
- *           THREAD_RemoveWait
- *
- * Remove thread from object wait queue.
- */
-static void THREAD_RemoveWait( K32OBJ *obj, DWORD thread_id )
-{
-    THDB *thdb = (THDB *)obj;
-    assert( obj->type == K32OBJ_THREAD );
-    return K32OBJ_OPS( thdb->event )->remove_wait( thdb->event, thread_id );
-}
-
-
-/***********************************************************************
  *           THREAD_Destroy
  */
 static void THREAD_Destroy( K32OBJ *ptr )
@@ -348,7 +284,6 @@
     }
 #endif
     close( thdb->socket );
-    K32OBJ_DecCount( thdb->event );
     SELECTOR_FreeBlock( thdb->teb_sel, 1 );
     if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 );
     HeapFree( SystemHeap, 0, thdb );
@@ -418,10 +353,6 @@
 
     SYSTEM_LOCK();
     thdb->exit_code = code;
-    EVENT_Set( thdb->event );
-
-    /* Abandon all owned mutexes */
-    while (thdb->mutex_list) MUTEX_Abandon( thdb->mutex_list );
 
     /* FIXME: should free the stack somehow */
 #if 0
@@ -731,15 +662,13 @@
     HANDLE32 handle, /* [in] Handle to thread */
     DWORD exitcode)  /* [in] Exit code for thread */
 {
-    int server_handle;
-    BOOL32 ret;
-    THDB *thread;
-    
-    if (!(thread = THREAD_GetPtr( handle, THREAD_TERMINATE, &server_handle )))
-        return FALSE;
-    ret = !CLIENT_TerminateThread( server_handle, exitcode );
-    K32OBJ_DecCount( &thread->header );
-    return ret;
+    struct terminate_thread_request req;
+
+    req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
+                                         K32OBJ_THREAD, THREAD_TERMINATE );
+    req.exit_code = exitcode;
+    CLIENT_SendRequest( REQ_TERMINATE_THREAD, -1, 1, &req, sizeof(req) );
+    return !CLIENT_WaitReply( NULL, NULL, 0 );
 }
 
 
@@ -754,19 +683,11 @@
     HANDLE32 hthread, /* [in]  Handle to thread */
     LPDWORD exitcode) /* [out] Address to receive termination status */
 {
-    THDB *thread;
-    int server_handle;
-
-    if (!(thread = THREAD_GetPtr( hthread, THREAD_QUERY_INFORMATION, &server_handle )))
-        return FALSE;
-    if (server_handle != -1)
-    {
-        struct get_thread_info_reply info;
-        CLIENT_GetThreadInfo( server_handle, &info );
-        if (exitcode) *exitcode = info.exit_code;
-    }
-    else if (exitcode) *exitcode = thread->exit_code;
-    K32OBJ_DecCount( &thread->header );
+    struct get_thread_info_reply info;
+    int handle = HANDLE_GetServerHandle( PROCESS_Current(), hthread,
+                                         K32OBJ_THREAD, THREAD_QUERY_INFORMATION );
+    if (CLIENT_GetThreadInfo( handle, &info )) return FALSE;
+    if (exitcode) *exitcode = info.exit_code;
     return TRUE;
 }