From 55443878fcbf4c74134d03dde9ab5a444f2531cf Mon Sep 17 00:00:00 2001 From: Alexandre Julliard <julliard@winehq.org> Date: Thu, 31 Dec 1998 15:52:06 +0000 Subject: [PATCH] Removed client-side wait functions; all waiting is now done through the server. --- files/change.c | 81 +++---------- files/file.c | 139 +++++----------------- include/k32obj.h | 6 - include/process.h | 6 +- include/thread.h | 15 +-- loader/signal.c | 4 - memory/virtual.c | 7 -- misc/toolhelp.c | 6 - scheduler/client.c | 26 ----- scheduler/event.c | 224 +++++++---------------------------- scheduler/handle.c | 56 +++++++++ scheduler/k32obj.c | 9 +- scheduler/mutex.c | 200 +++++-------------------------- scheduler/pipe.c | 6 - scheduler/process.c | 153 ++++++------------------ scheduler/semaphore.c | 158 ++++++------------------- scheduler/synchro.c | 266 ++---------------------------------------- scheduler/thread.c | 103 ++-------------- win32/console.c | 195 ++++--------------------------- win32/device.c | 7 +- windows/queue.c | 3 + 21 files changed, 301 insertions(+), 1369 deletions(-) diff --git a/files/change.c b/files/change.c index 5b99ca5eb8e..331700c43fd 100644 --- a/files/change.c +++ b/files/change.c @@ -15,22 +15,13 @@ #include "process.h" #include "thread.h" #include "heap.h" +#include "server.h" #include "debug.h" -static BOOL32 CHANGE_Signaled( K32OBJ *obj, DWORD thread_id ); -static BOOL32 CHANGE_Satisfied( K32OBJ *obj, DWORD thread_id ); -static void CHANGE_AddWait( K32OBJ *obj, DWORD thread_id ); -static void CHANGE_RemoveWait( K32OBJ *obj, DWORD thread_id ); static void CHANGE_Destroy( K32OBJ *obj ); const K32OBJ_OPS CHANGE_Ops = { - CHANGE_Signaled, /* signaled */ - CHANGE_Satisfied, /* satisfied */ - CHANGE_AddWait, /* add_wait */ - CHANGE_RemoveWait, /* remove_wait */ - NULL, /* read */ - NULL, /* write */ CHANGE_Destroy /* destroy */ }; @@ -48,51 +39,6 @@ typedef struct } CHANGE_OBJECT; -/*********************************************************************** - * CHANGE_Signaled - */ -static BOOL32 CHANGE_Signaled( K32OBJ *obj, DWORD thread_id ) -{ - CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj; - assert( obj->type == K32OBJ_CHANGE ); - return change->notify; -} - -/*********************************************************************** - * CHANGE_Satisfied - * - * Wait on this object has been satisfied. - */ -static BOOL32 CHANGE_Satisfied( K32OBJ *obj, DWORD thread_id ) -{ - assert( obj->type == K32OBJ_CHANGE ); - return FALSE; /* Not abandoned */ -} - -/*********************************************************************** - * CHANGE_AddWait - * - * Add thread to object wait queue. - */ -static void CHANGE_AddWait( K32OBJ *obj, DWORD thread_id ) -{ - CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj; - assert( obj->type == K32OBJ_CHANGE ); - THREAD_AddQueue( &change->wait_queue, THREAD_ID_TO_THDB(thread_id) ); -} - -/*********************************************************************** - * CHANGE_RemoveWait - * - * Remove thread from object wait queue. - */ -static void CHANGE_RemoveWait( K32OBJ *obj, DWORD thread_id ) -{ - CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj; - assert( obj->type == K32OBJ_CHANGE ); - THREAD_RemoveQueue( &change->wait_queue, THREAD_ID_TO_THDB(thread_id) ); -} - /**************************************************************************** * CHANGE_Destroy */ @@ -118,11 +64,24 @@ HANDLE32 WINAPI FindFirstChangeNotification32A( LPCSTR lpPathName, BOOL32 bWatchSubtree, DWORD dwNotifyFilter ) { - HANDLE32 handle; CHANGE_OBJECT *change; + struct create_change_notification_request req; + struct create_change_notification_reply reply; + int len; + + req.subtree = bWatchSubtree; + req.filter = dwNotifyFilter; + CLIENT_SendRequest( REQ_CREATE_CHANGE_NOTIFICATION, -1, 1, &req, sizeof(req) ); + CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) ); + CHECK_LEN( len, sizeof(reply) ); + if (reply.handle == -1) return INVALID_HANDLE_VALUE32; change = HeapAlloc( SystemHeap, 0, sizeof(CHANGE_OBJECT) ); - if (!change) return INVALID_HANDLE_VALUE32; + if (!change) + { + CLIENT_CloseHandle( reply.handle ); + return INVALID_HANDLE_VALUE32; + } change->header.type = K32OBJ_CHANGE; change->header.refcount = 1; @@ -134,11 +93,9 @@ HANDLE32 WINAPI FindFirstChangeNotification32A( LPCSTR lpPathName, change->wait_queue = NULL; change->notify = FALSE; - handle = HANDLE_Alloc( PROCESS_Current(), &change->header, - FILE_ALL_ACCESS /*FIXME*/, TRUE, -1 ); - /* If the allocation failed, the object is already destroyed */ - if (handle == INVALID_HANDLE_VALUE32) change = NULL; - return handle; + return HANDLE_Alloc( PROCESS_Current(), &change->header, + STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE /*FIXME*/, + FALSE, reply.handle ); } /**************************************************************************** diff --git a/files/file.c b/files/file.c index 585b461b632..5b000cf4274 100644 --- a/files/file.c +++ b/files/file.c @@ -45,29 +45,10 @@ #define MAP_ANON MAP_ANONYMOUS #endif -#if 0 -static BOOL32 FILE_Signaled(K32OBJ *ptr, DWORD tid); -static BOOL32 FILE_Satisfied(K32OBJ *ptr, DWORD thread_id); -static void FILE_AddWait(K32OBJ *ptr, DWORD tid); -static void FILE_RemoveWait(K32OBJ *ptr, DWORD thread_id); -#endif static void FILE_Destroy( K32OBJ *obj ); const K32OBJ_OPS FILE_Ops = { -#if 0 - FILE_Signaled, /* signaled */ - FILE_Satisfied, /* satisfied */ - FILE_AddWait, /* add_wait */ - FILE_RemoveWait, /* remove_wait */ -#else - NULL, /* signaled */ - NULL, /* satisfied */ - NULL, /* add_wait */ - NULL, /* remove_wait */ -#endif - NULL, /* read */ - NULL, /* write */ FILE_Destroy /* destroy */ }; @@ -126,58 +107,6 @@ HFILE32 FILE_Alloc( FILE_OBJECT **file, int unix_handle ) return handle; } -/*********************************************************************** - * FILE_async_handler [internal] - */ -#if 0 -static void -FILE_async_handler(int unixfd,void *private) { - FILE_OBJECT *file = (FILE_OBJECT*)private; - - SYNC_WakeUp(&file->wait_queue,INFINITE32); -} - -static BOOL32 FILE_Signaled(K32OBJ *ptr, DWORD thread_id) -{ - fd_set fds,*readfds = NULL,*writefds = NULL; - struct timeval tv; - FILE_OBJECT *file = (FILE_OBJECT *)ptr; - - FD_ZERO(&fds); - FD_SET(file->unix_handle,&fds); - if (file->mode == OF_READ) readfds = &fds; - if (file->mode == OF_WRITE) writefds = &fds; - if (file->mode == OF_READWRITE) {writefds = &fds; readfds = &fds;} - tv.tv_sec = 0; - tv.tv_usec = 0; - assert(readfds || writefds); - if (select(file->unix_handle+1,readfds,writefds,NULL,&tv)>0) - return TRUE; /* we triggered one fd. Whereever. */ - return FALSE; -} - -static void FILE_AddWait(K32OBJ *ptr, DWORD thread_id) -{ - FILE_OBJECT *file = (FILE_OBJECT*)ptr; - if (!file->wait_queue) - ASYNC_RegisterFD(file->unix_handle,FILE_async_handler,file); - THREAD_AddQueue(&file->wait_queue,thread_id); -} - -static void FILE_RemoveWait(K32OBJ *ptr, DWORD thread_id) -{ - FILE_OBJECT *file = (FILE_OBJECT*)ptr; - THREAD_RemoveQueue(&file->wait_queue,thread_id); - if (!file->wait_queue) - ASYNC_UnregisterFD(file->unix_handle,FILE_async_handler); -} - -static BOOL32 FILE_Satisfied(K32OBJ *ptr, DWORD thread_id) -{ - return FALSE; /* not abandoned. Hmm? */ -} -#endif - /*********************************************************************** * FILE_Destroy @@ -1248,6 +1177,7 @@ BOOL32 WINAPI ReadFile( HANDLE32 hFile, LPVOID buffer, DWORD bytesToRead, { K32OBJ *ptr; struct get_read_fd_request req; + int unix_handle, result; TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToRead ); @@ -1258,29 +1188,25 @@ BOOL32 WINAPI ReadFile( HANDLE32 hFile, LPVOID buffer, DWORD bytesToRead, K32OBJ_UNKNOWN, GENERIC_READ, &req.handle ))) return FALSE; - if (req.handle != -1) /* We have a server handle */ + if (req.handle == -1) /* We need a server handle */ { - int unix_handle, result; - - CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &req, sizeof(req) ); - CLIENT_WaitReply( NULL, &unix_handle, 0 ); - if (unix_handle == -1) return FALSE; - if ((result = read( unix_handle, buffer, bytesToRead )) == -1) - FILE_SetDosError(); - close( unix_handle ); K32OBJ_DecCount( ptr ); - if (result == -1) return FALSE; - if (bytesRead) *bytesRead = result; - return TRUE; + return FALSE; } - else + CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &req, sizeof(req) ); + CLIENT_WaitReply( NULL, &unix_handle, 0 ); + K32OBJ_DecCount( ptr ); + if (unix_handle == -1) return FALSE; + while ((result = read( unix_handle, buffer, bytesToRead )) == -1) { - BOOL32 status = FALSE; - if (K32OBJ_OPS(ptr)->read) - status = K32OBJ_OPS(ptr)->read(ptr, buffer, bytesToRead, bytesRead, overlapped ); - K32OBJ_DecCount( ptr ); - return status; + if ((errno == EAGAIN) || (errno == EINTR)) continue; + FILE_SetDosError(); + break; } + close( unix_handle ); + if (result == -1) return FALSE; + if (bytesRead) *bytesRead = result; + return TRUE; } @@ -1292,6 +1218,7 @@ BOOL32 WINAPI WriteFile( HANDLE32 hFile, LPCVOID buffer, DWORD bytesToWrite, { K32OBJ *ptr; struct get_write_fd_request req; + int unix_handle, result; TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToWrite ); @@ -1302,31 +1229,25 @@ BOOL32 WINAPI WriteFile( HANDLE32 hFile, LPCVOID buffer, DWORD bytesToWrite, K32OBJ_UNKNOWN, GENERIC_WRITE, &req.handle ))) return FALSE; - if (req.handle != -1) /* We have a server handle */ + if (req.handle == -1) /* We need a server handle */ { - int unix_handle, result; - - CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &req, sizeof(req) ); - CLIENT_WaitReply( NULL, &unix_handle, 0 ); - if (unix_handle == -1) return FALSE; - - if ((result = write( unix_handle, buffer, bytesToWrite )) == -1) - FILE_SetDosError(); - close( unix_handle ); K32OBJ_DecCount( ptr ); - if (result == -1) return FALSE; - if (bytesWritten) *bytesWritten = result; - return TRUE; + return FALSE; } - else + CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &req, sizeof(req) ); + CLIENT_WaitReply( NULL, &unix_handle, 0 ); + K32OBJ_DecCount( ptr ); + if (unix_handle == -1) return FALSE; + while ((result = write( unix_handle, buffer, bytesToWrite )) == -1) { - BOOL32 status = FALSE; - if (K32OBJ_OPS(ptr)->write) - status = K32OBJ_OPS(ptr)->write( ptr, buffer, bytesToWrite, - bytesWritten, overlapped ); - K32OBJ_DecCount( ptr ); - return status; + if ((errno == EAGAIN) || (errno == EINTR)) continue; + FILE_SetDosError(); + break; } + close( unix_handle ); + if (result == -1) return FALSE; + if (bytesWritten) *bytesWritten = result; + return TRUE; } diff --git a/include/k32obj.h b/include/k32obj.h index b0e8633f4bb..281b3ed996e 100644 --- a/include/k32obj.h +++ b/include/k32obj.h @@ -44,12 +44,6 @@ typedef struct /* Kernel object operations */ typedef struct { - BOOL32 (*signaled)(K32OBJ*,DWORD); /* Is object signaled? */ - BOOL32 (*satisfied)(K32OBJ*,DWORD); /* Wait on object is satisfied */ - void (*add_wait)(K32OBJ*,DWORD); /* Add thread to wait queue */ - void (*remove_wait)(K32OBJ*,DWORD); /* Remove thread from wait queue */ - BOOL32 (*read)(K32OBJ*,LPVOID,DWORD,LPDWORD,LPOVERLAPPED); - BOOL32 (*write)(K32OBJ*,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED); void (*destroy)(K32OBJ *); /* Destroy object on refcount==0 */ } K32OBJ_OPS; diff --git a/include/process.h b/include/process.h index 51e62073ed6..f562ac5adae 100644 --- a/include/process.h +++ b/include/process.h @@ -63,7 +63,7 @@ typedef struct _PDB32 { K32OBJ header; /* 00 Kernel object header */ DWORD unknown1; /* 08 Unknown */ - K32OBJ *event; /* 0c Pointer to an event object */ + K32OBJ *event; /* 0c Pointer to an event object (unused) */ DWORD exit_code; /* 10 Process exit code */ DWORD unknown2; /* 14 Unknown */ HANDLE32 heap; /* 18 Default process heap */ @@ -102,7 +102,7 @@ typedef struct _PDB32 K32OBJ *console_provider; /* b0 Console provider (??) */ WORD env_selector; /* b4 Selector to process environment */ WORD error_mode; /* b6 Error mode */ - K32OBJ *load_done_evt; /* b8 Event for process loading done */ + HANDLE32 load_done_evt; /* b8 Event for process loading done */ DWORD unknown7; /* bc Unknown */ DWORD unknown8; /* c0 Unknown (NT) */ LCID locale; /* c4 Locale to be queried by GetThreadLocale (NT) */ @@ -136,6 +136,8 @@ extern HANDLE32 HANDLE_Alloc( PDB32 *pdb, K32OBJ *ptr, DWORD access, extern K32OBJ *HANDLE_GetObjPtr( PDB32 *pdb, HANDLE32 handle, K32OBJ_TYPE type, DWORD access, int *server_handle ); +extern int HANDLE_GetServerHandle( PDB32 *pdb, HANDLE32 handle, + K32OBJ_TYPE type, DWORD access ); extern BOOL32 HANDLE_SetObjPtr( PDB32 *pdb, HANDLE32 handle, K32OBJ *ptr, DWORD access ); extern void HANDLE_CloseAll( PDB32 *pdb, K32OBJ *ptr ); diff --git a/include/thread.h b/include/thread.h index 4ce3e161f8b..3dac713d905 100644 --- a/include/thread.h +++ b/include/thread.h @@ -64,7 +64,6 @@ typedef struct DWORD signaled; /* Index of signaled object (or WAIT_FAILED)*/ BOOL32 wait_all; /* Wait for all objects flag */ BOOL32 wait_msg; /* Wait for message flag */ - BOOL32 use_server; /* Use server call for waiting */ K32OBJ *objs[MAXIMUM_WAIT_OBJECTS]; /* Object pointers */ int server[MAXIMUM_WAIT_OBJECTS]; /* Server handles */ } WAIT_STRUCT; @@ -107,8 +106,7 @@ typedef struct _THDB void *entry_point; /* 1c0 Thread entry point (was: unknown) */ void *entry_arg; /* 1c4 Entry point arg (was: unknown) */ int unix_pid; /* 1c8 Unix thread pid (was: unknown) */ - K32OBJ *mutex_list; /* 1cc List of owned mutex (was: unknown)*/ - DWORD unknown5[2]; /* 1d0 Unknown */ + DWORD unknown5[3]; /* 1cc Unknown */ DWORD sys_count[4]; /* 1d8 Syslevel mutex entry counters */ CRITICAL_SECTION *sys_mutex[4];/* 1e8 Syslevel mutex pointers */ DWORD unknown6[2]; /* 1f8 Unknown */ @@ -162,18 +160,7 @@ extern void THREAD_AddQueue( THREAD_QUEUE *queue, THDB *thread ); extern void THREAD_RemoveQueue( THREAD_QUEUE *queue, THDB *thread ); extern DWORD THREAD_TlsAlloc( THDB *thread ); -/* scheduler/event.c */ -extern void EVENT_Set( K32OBJ *obj ); -extern K32OBJ *EVENT_Create( BOOL32 manual_reset, BOOL32 initial_state ); - -/* scheduler/mutex.c */ -extern void MUTEX_Abandon( K32OBJ *obj ); - /* scheduler/synchro.c */ -extern void SYNC_WaitForCondition( WAIT_STRUCT *wait, DWORD timeout ); -extern void SYNC_WakeUp( THREAD_QUEUE *queue, DWORD max ); -extern void SYNC_MsgWakeUp( THDB *thdb ); -extern void SYNC_SetupSignals(void); extern DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles, BOOL32 wait_all, DWORD timeout, BOOL32 alertable, BOOL32 wait_msg ); diff --git a/loader/signal.c b/loader/signal.c index ed18a3a48bc..7e8c29f07c6 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -156,8 +156,6 @@ extern void ASYNC_sigio(int a); */ BOOL32 SIGNAL_Init(void) { - extern void SYNC_SetupSignals(void); - #ifdef HAVE_WORKING_SIGALTSTACK struct sigaltstack ss; ss.ss_sp = SIGNAL_Stack; @@ -187,8 +185,6 @@ BOOL32 SIGNAL_Init(void) /* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead */ signal (SIGPIPE, SIG_IGN); - - SYNC_SetupSignals(); return TRUE; } diff --git a/memory/virtual.c b/memory/virtual.c index 7493022ba8b..70779c5fde8 100644 --- a/memory/virtual.c +++ b/memory/virtual.c @@ -110,13 +110,6 @@ static void VIRTUAL_DestroyMapping( K32OBJ *obj ); const K32OBJ_OPS MEM_MAPPED_FILE_Ops = { - /* Object cannot be waited upon, so we don't need these (except destroy) */ - NULL, /* signaled */ - NULL, /* satisfied */ - NULL, /* add_wait */ - NULL, /* remove_wait */ - NULL, /* read */ - NULL, /* write */ VIRTUAL_DestroyMapping /* destroy */ }; diff --git a/misc/toolhelp.c b/misc/toolhelp.c index f69039c45a9..751b620fd3e 100644 --- a/misc/toolhelp.c +++ b/misc/toolhelp.c @@ -29,12 +29,6 @@ static void SNAPSHOT_Destroy( K32OBJ *obj ); const K32OBJ_OPS SNAPSHOT_Ops = { - NULL, /* signaled */ - NULL, /* satisfied */ - NULL, /* add_wait */ - NULL, /* remove_wait */ - NULL, /* read */ - NULL, /* write */ SNAPSHOT_Destroy /* destroy */ }; diff --git a/scheduler/client.c b/scheduler/client.c index 47670a4c421..4f01efd7856 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -327,32 +327,6 @@ int CLIENT_SetDebug( int level ) return CLIENT_WaitReply( NULL, NULL, 0 ); } -/*********************************************************************** - * 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 * diff --git a/scheduler/event.c b/scheduler/event.c index 552568d773b..30a1c76d48c 100644 --- a/scheduler/event.c +++ b/scheduler/event.c @@ -18,68 +18,16 @@ 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) */ @@ -99,20 +47,15 @@ HANDLE32 WINAPI CreateEvent32A( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset, 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 WINAPI OpenEvent32A( DWORD access, BOOL32 inherit, LPCSTR name ) { 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,144 +128,47 @@ HANDLE32 WINAPI OpenEvent32W( DWORD access, BOOL32 inherit, LPCWSTR name ) /*********************************************************************** - * 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; -} - - -/*********************************************************************** - * SetEvent (KERNEL32.644) - */ -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; -} - - -/*********************************************************************** - * ResetEvent (KERNEL32.586) + * EVENT_Operation + * + * Execute an event operation (set,reset,pulse). */ -BOOL32 WINAPI ResetEvent( HANDLE32 handle ) +static BOOL32 EVENT_Operation( HANDLE32 handle, enum event_op op ) { 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; + 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 ); } /*********************************************************************** - * EVENT_Satisfied - * - * Wait on this object has been satisfied. + * PulseEvent (KERNEL32.557) */ -static BOOL32 EVENT_Satisfied( K32OBJ *obj, DWORD thread_id ) +BOOL32 WINAPI PulseEvent( HANDLE32 handle ) { - 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 */ + return EVENT_Operation( handle, PULSE_EVENT ); } /*********************************************************************** - * EVENT_AddWait - * - * Add thread to object wait queue. + * SetEvent (KERNEL32.644) */ -static void EVENT_AddWait( K32OBJ *obj, DWORD thread_id ) +BOOL32 WINAPI SetEvent( HANDLE32 handle ) { - EVENT *event = (EVENT *)obj; - assert( obj->type == K32OBJ_EVENT ); - THREAD_AddQueue( &event->wait_queue, THREAD_ID_TO_THDB(thread_id) ); + return EVENT_Operation( handle, SET_EVENT ); } /*********************************************************************** - * EVENT_RemoveWait - * - * Remove thread from object wait queue. + * ResetEvent (KERNEL32.586) */ -static void EVENT_RemoveWait( K32OBJ *obj, DWORD thread_id ) +BOOL32 WINAPI ResetEvent( HANDLE32 handle ) { - 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 @@ static void EVENT_Destroy( K32OBJ *obj ) { 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 5abf0a65022..ec34184adf0 100644 --- a/scheduler/handle.c +++ b/scheduler/handle.c @@ -191,6 +191,27 @@ K32OBJ *HANDLE_GetObjPtr( PDB32 *pdb, HANDLE32 handle, } +/*********************************************************************** + * 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 * @@ -413,3 +434,38 @@ done: 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 d8aca634eac..a0b8e82f876 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 @@ extern const K32OBJ_OPS PIPE_Ops; 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 @@ const K32OBJ_OPS * const K32OBJ_Ops[K32OBJ_NBOBJECTS] = &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 4a32e15065b..05c72ed0d6f 100644 --- a/scheduler/mutex.c +++ b/scheduler/mutex.c @@ -17,66 +17,16 @@ 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) */ @@ -95,37 +45,14 @@ HANDLE32 WINAPI CreateMutex32A( SECURITY_ATTRIBUTES *sa, BOOL32 owner, 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 WINAPI OpenMutex32A( DWORD access, BOOL32 inherit, LPCSTR name ) { 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 @@ HANDLE32 WINAPI OpenMutex32W( DWORD access, BOOL32 inherit, LPCWSTR name ) 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 @@ static void MUTEX_Destroy( K32OBJ *obj ) { 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 854801304f4..94279fb3e3e 100644 --- a/scheduler/pipe.c +++ b/scheduler/pipe.c @@ -23,12 +23,6 @@ static void PIPE_Destroy( K32OBJ *obj ); 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 1432ea74d23..6ddc950d54c 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 @@ static void PROCESS_FreePDB( PDB32 *pdb ) 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 @@ static PDB32 *PROCESS_CreatePDB( PDB32 *parent ) 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: @@ -346,6 +326,21 @@ error: } +/*********************************************************************** + * 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 */ @@ -357,9 +352,8 @@ BOOL32 PROCESS_Init(void) /* 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 @@ BOOL32 PROCESS_Init(void) /* 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 @@ PDB32 *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, if (!pdb) return NULL; info->hThread = info->hProcess = INVALID_HANDLE_VALUE32; + if (!PROCESS_FinishCreatePDB( pdb )) goto error; /* Create the heap */ @@ -472,56 +471,6 @@ error: } -/*********************************************************************** - * 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 */ @@ -552,7 +501,6 @@ void WINAPI ExitProcess( DWORD status ) 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 @@ void WINAPI ExitProcess( DWORD status ) */ 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 @@ BOOL32 WINAPI GetProcessWorkingSetSize(HANDLE32 hProcess,LPDWORD minset, * 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) @@ -900,28 +848,6 @@ BOOL32 WINAPI WriteProcessMemory(HANDLE32 hProcess, LPVOID lpBaseAddress, return TRUE; } -/*********************************************************************** - * 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) * @@ -942,28 +868,17 @@ DWORD WINAPI RegisterServiceProcess(DWORD dwProcessId, DWORD dwType) * 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 7c71a100624..561d536d69c 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 @@ HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG initial, 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 @@ HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG initial, 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 WINAPI OpenSemaphore32A( DWORD access, BOOL32 inherit, LPCSTR name ) { 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,110 +132,26 @@ HANDLE32 WINAPI OpenSemaphore32W( DWORD access, BOOL32 inherit, LPCWSTR name ) 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 */ @@ -247,7 +160,6 @@ static void SEMAPHORE_Destroy( K32OBJ *obj ) 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 9fdea037119..f2f45600851 100644 --- a/scheduler/synchro.c +++ b/scheduler/synchro.c @@ -24,7 +24,7 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles, BOOL32 wait_all, BOOL32 wait_msg, WAIT_STRUCT *wait ) { - DWORD i, j; + DWORD i; K32OBJ **ptr; SYSTEM_LOCK(); @@ -32,7 +32,6 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles, 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 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles, 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; @@ -90,224 +72,6 @@ static void SYNC_FreeWaitStruct( WAIT_STRUCT *wait ) } -/*********************************************************************** - * 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 */ @@ -326,30 +90,18 @@ DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles, 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 91eb1837eee..4888ae7f837 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 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16, 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; @@ -273,56 +259,6 @@ error: } -/*********************************************************************** - * 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 */ @@ -348,7 +284,6 @@ static void THREAD_Destroy( K32OBJ *ptr ) } #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 @@ void WINAPI ExitThread( 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 @@ BOOL32 WINAPI TerminateThread( 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 @@ BOOL32 WINAPI GetExitCodeThread( 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; } diff --git a/win32/console.c b/win32/console.c index dad241f7f9b..ae53a8b5a29 100644 --- a/win32/console.c +++ b/win32/console.c @@ -63,26 +63,10 @@ typedef struct _CONSOLE { THREAD_QUEUE wait_queue; } CONSOLE; -static void CONSOLE_AddWait(K32OBJ *ptr, DWORD thread_id); -static void CONSOLE_RemoveWait(K32OBJ *ptr, DWORD thread_id); -static BOOL32 CONSOLE_Satisfied(K32OBJ *ptr, DWORD thread_id); -static BOOL32 CONSOLE_Signaled(K32OBJ *ptr, DWORD thread_id); static void CONSOLE_Destroy( K32OBJ *obj ); -static BOOL32 CONSOLE_Write(K32OBJ *ptr, LPCVOID lpBuffer, - DWORD nNumberOfChars, LPDWORD lpNumberOfChars, - LPOVERLAPPED lpOverlapped); -static BOOL32 CONSOLE_Read(K32OBJ *ptr, LPVOID lpBuffer, - DWORD nNumberOfChars, LPDWORD lpNumberOfChars, - LPOVERLAPPED lpOverlapped); const K32OBJ_OPS CONSOLE_Ops = { - CONSOLE_Signaled, /* signaled */ - CONSOLE_Satisfied, /* satisfied */ - CONSOLE_AddWait, /* add_wait */ - CONSOLE_RemoveWait, /* remove_wait */ - CONSOLE_Read, /* read */ - CONSOLE_Write, /* write */ CONSOLE_Destroy /* destroy */ }; @@ -106,63 +90,6 @@ static void CONSOLE_Destroy(K32OBJ *obj) } -/*********************************************************************** - * CONSOLE_Read - * - * NOTES - * lpOverlapped is ignored - */ -static BOOL32 CONSOLE_Read(K32OBJ *ptr, LPVOID lpBuffer, DWORD nNumberOfChars, - LPDWORD lpNumberOfChars, LPOVERLAPPED lpOverlapped) -{ - CONSOLE *console = (CONSOLE *)ptr; - int result; - - TRACE(console, "%p %p %ld\n", ptr, lpBuffer, nNumberOfChars); - *lpNumberOfChars = 0; - if ((result = read(console->infd, lpBuffer, nNumberOfChars)) == -1) { - FILE_SetDosError(); - return FALSE; - } - *lpNumberOfChars = result; - return TRUE; -} - - -/*********************************************************************** - * CONSOLE_Write - * - * NOTES - * lpOverlapped is ignored - */ -static BOOL32 CONSOLE_Write(K32OBJ *ptr, LPCVOID lpBuffer, - DWORD nNumberOfChars, - LPDWORD lpNumberOfChars, LPOVERLAPPED lpOverlapped) -{ - CONSOLE *console = (CONSOLE *)ptr; - int result; - - TRACE(console, "%p %p %ld\n", ptr, lpBuffer, nNumberOfChars); - *lpNumberOfChars = 0; - /* - * I assume this loop around EAGAIN is here because - * win32 doesn't have interrupted system calls - */ - - for (;;) - { - result = write(console->outfd, lpBuffer, nNumberOfChars); - if (result != -1) { - *lpNumberOfChars = result; - return TRUE; - } - if (errno != EINTR) { - FILE_SetDosError(); - return FALSE; - } - } -} - /**************************************************************************** * CONSOLE_add_input_record [internal] * @@ -181,9 +108,11 @@ CONSOLE_add_input_record(CONSOLE *console,INPUT_RECORD *inp) { * queue. Does translation of vt100 style function keys and xterm-mouse clicks. */ static void -CONSOLE_string_to_IR(CONSOLE *console,unsigned char *buf,int len) { +CONSOLE_string_to_IR( HANDLE32 hConsoleInput,unsigned char *buf,int len) { int j,k; INPUT_RECORD ir; + CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hConsoleInput, + K32OBJ_CONSOLE, 0, NULL); for (j=0;j<len;j++) { unsigned char inchar = buf[j]; @@ -326,39 +255,31 @@ CONSOLE_string_to_IR(CONSOLE *console,unsigned char *buf,int len) { } } } + K32OBJ_DecCount(&console->header); } + /**************************************************************************** * CONSOLE_get_input (internal) * * Reads (nonblocking) as much input events as possible and stores them * in an internal queue. - * (not necessarily XTERM dependend, but UNIX filedescriptor...) */ static void -CONSOLE_get_input(CONSOLE *console) { +CONSOLE_get_input( HANDLE32 handle ) +{ char *buf = HeapAlloc(GetProcessHeap(),0,1); int len = 0; - while (1) { - fd_set infds; - DWORD res; - struct timeval tv; - char inchar; - - FD_ZERO(&infds); - FD_SET(console->infd,&infds); - memset(&tv,0,sizeof(tv)); - if (select(console->infd+1,&infds,NULL,NULL,&tv)<1) - break; /* no input there */ - - if (!FD_ISSET(console->infd,&infds)) - break; - if (!CONSOLE_Read((K32OBJ*)console,&inchar,1,&res,NULL)) - break; + while (1) + { + DWORD res; + char inchar; + if (!WaitForSingleObject( handle, 0 )) break; + if (!ReadFile( handle, &inchar, 1, &res, NULL )) break; buf = HeapReAlloc(GetProcessHeap(),0,buf,len+1); buf[len++]=inchar; } - CONSOLE_string_to_IR(console,buf,len); + CONSOLE_string_to_IR(handle,buf,len); HeapFree(GetProcessHeap(),0,buf); } @@ -385,73 +306,6 @@ CONSOLE_drain_input(CONSOLE *console,int n) { } } -/*********************************************************************** - * CONSOLE_async_handler [internal] - */ -static void -CONSOLE_async_handler(int unixfd,void *private) { - CONSOLE *console = (CONSOLE*)private; - - SYNC_WakeUp(&console->wait_queue,INFINITE32); -} - -/*********************************************************************** - * CONSOLE_Signaled [internal] - * - * Checks if we can read something. (Hmm, what about writing ?) - */ -static BOOL32 -CONSOLE_Signaled(K32OBJ *ptr,DWORD tid) { - CONSOLE *console =(CONSOLE*)ptr; - - if (ptr->type!= K32OBJ_CONSOLE) - return FALSE; - CONSOLE_get_input(console); - if (console->nrofirs!=0) - return TRUE; - /* addref console */ - return FALSE; -} - -/*********************************************************************** - * CONSOLE_AddWait [internal] - * - * Add thread to our waitqueue (so we can signal it if we have input). - */ -static void CONSOLE_AddWait(K32OBJ *ptr, DWORD thread_id) -{ - CONSOLE *console = (CONSOLE *)ptr; - - /* register our unix filedescriptors for async IO */ - if (!console->wait_queue) - ASYNC_RegisterFD(console->infd,CONSOLE_async_handler,console); - THREAD_AddQueue( &console->wait_queue, THREAD_ID_TO_THDB(thread_id) ); -} - -/*********************************************************************** - * CONSOLE_RemoveWait [internal] - * - * Remove thread from our waitqueue. - */ -static void CONSOLE_RemoveWait(K32OBJ *ptr, DWORD thread_id) -{ - CONSOLE *console = (CONSOLE *)ptr; - - THREAD_RemoveQueue( &console->wait_queue, THREAD_ID_TO_THDB(thread_id) ); - if (!console->wait_queue) - ASYNC_UnregisterFD(console->infd,CONSOLE_async_handler); -} - -/*********************************************************************** - * CONSOLE_Satisfied [internal] - * - * Condition from last Signaled is satisfied and will be used now. - */ -static BOOL32 CONSOLE_Satisfied(K32OBJ *ptr, DWORD thread_id) -{ - return FALSE; -} - /****************************************************************************** * SetConsoleCtrlHandler [KERNEL32.459] Adds function to calling process list @@ -711,7 +565,7 @@ static int CONSOLE_openpty(CONSOLE *console, char *name, * * To test for complex console: pid == -1 -> simple, otherwise complex. */ -static BOOL32 CONSOLE_make_complex(CONSOLE *console) +static BOOL32 CONSOLE_make_complex(HANDLE32 handle,CONSOLE *console) { struct termios term; char buf[30]; @@ -757,7 +611,7 @@ static BOOL32 CONSOLE_make_complex(CONSOLE *console) } /* enable mouseclicks */ sprintf(buf,"%c[?1001s%c[?1000h",27,27); - CONSOLE_Write(&console->header,buf,strlen(buf),&xlen,NULL); + WriteFile(handle,buf,strlen(buf),&xlen,NULL); return TRUE; } @@ -1033,7 +887,7 @@ BOOL32 WINAPI WriteConsoleOutput32A( HANDLE32 hConsoleOutput, FIXME(console,"(%d,...): no console handle!\n",hConsoleOutput); return FALSE; } - CONSOLE_make_complex(console); + CONSOLE_make_complex(hConsoleOutput,console); buffer = HeapAlloc(GetProcessHeap(),0,100);; curbufsize = 100; @@ -1114,7 +968,7 @@ BOOL32 WINAPI ReadConsole32A( HANDLE32 hConsoleInput, hConsoleInput,lpBuffer,nNumberOfCharsToRead, lpNumberOfCharsRead,lpReserved ); - CONSOLE_get_input(console); + CONSOLE_get_input(hConsoleInput); /* FIXME: should this drain everything from the input queue and just * put the keypresses in the buffer? Needs further thought. @@ -1186,7 +1040,7 @@ BOOL32 WINAPI ReadConsoleInput32A(HANDLE32 hConsoleInput, lpBuffer, nLength, lpNumberOfEventsRead); return FALSE; } - CONSOLE_get_input(console); + CONSOLE_get_input(hConsoleInput); if (nLength>console->nrofirs) nLength = console->nrofirs; memcpy(lpBuffer,console->irs,sizeof(INPUT_RECORD)*nLength); @@ -1232,7 +1086,8 @@ BOOL32 WINAPI SetConsoleTitle32A(LPCSTR title) sprintf(titlestring,titleformat,title); /* FIXME: hmm, should use WriteFile probably... */ - CONSOLE_Write(&console->header,titlestring,strlen(titlestring),&written,NULL); + /*CONSOLE_Write(&console->header,titlestring,strlen(titlestring),&written,NULL);*/ + WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),titlestring,strlen(titlestring),&written,NULL); if (written == strlen(titlestring)) ret =TRUE; HeapFree( GetProcessHeap(), 0, titlestring ); @@ -1311,7 +1166,7 @@ BOOL32 WINAPI SetConsoleCursorPosition( HANDLE32 hcon, COORD pos ) FIXME(console,"(%d,...), no console handle!\n",hcon); return FALSE; } - CONSOLE_make_complex(console); + CONSOLE_make_complex(hcon,console); TRACE(console, "%d (%dx%d)\n", hcon, pos.x , pos.y ); /* x are columns, y rows */ sprintf(xbuf,"%c[%d;%dH", 0x1B, pos.y+1, pos.x+1); @@ -1332,7 +1187,7 @@ BOOL32 WINAPI GetNumberOfConsoleInputEvents(HANDLE32 hcon,LPDWORD nrofevents) FIXME(console,"(%d,%p), no console handle!\n",hcon,nrofevents); return FALSE; } - CONSOLE_get_input(console); + CONSOLE_get_input(hcon); *nrofevents = console->nrofirs; K32OBJ_DecCount(&console->header); return TRUE; @@ -1367,7 +1222,7 @@ BOOL32 WINAPI PeekConsoleInput32A(HANDLE32 hConsoleInput, return FALSE; } TRACE(console,"(%d,%p,%ld,%p)\n",hConsoleInput, pirBuffer, cInRecords, lpcRead); - CONSOLE_get_input(console); + CONSOLE_get_input(hConsoleInput); if (cInRecords>console->nrofirs) cInRecords = console->nrofirs; if (pirBuffer) @@ -1438,7 +1293,7 @@ BOOL32 WINAPI SetConsoleCursorInfo32( TRACE(console, "(%x,%ld,%i): stub\n", hcon,cinfo->dwSize,cinfo->bVisible); if (!console) return FALSE; - CONSOLE_make_complex(console); + CONSOLE_make_complex(hcon,console); sprintf(buf,"%c[?25%c",27,cinfo->bVisible?'h':'l'); WriteFile(hcon,buf,strlen(buf),&xlen,NULL); console->cinfo = *cinfo; diff --git a/win32/device.c b/win32/device.c index 3131b218ddb..75bab3a5d72 100644 --- a/win32/device.c +++ b/win32/device.c @@ -32,14 +32,9 @@ #include "miscemu.h" static void DEVICE_Destroy(K32OBJ *dev); + const K32OBJ_OPS DEVICE_Ops = { - NULL, /* signaled */ - NULL, /* satisfied */ - NULL, /* add_wait */ - NULL, /* remove_wait */ - NULL, /* read */ - NULL, /* write */ DEVICE_Destroy /* destroy */ }; diff --git a/windows/queue.c b/windows/queue.c index eee5c8a6f2c..da782e971fe 100644 --- a/windows/queue.c +++ b/windows/queue.c @@ -235,6 +235,8 @@ void QUEUE_Signal( HTASK16 hTask ) /* NOTE: This should really wake up *the* thread that owns the queue. Since we dont't have thread-local message queues yet, we wake up all waiting threads ... */ +#if 0 + /* FIXME: should be replaced by a server event */ SYSTEM_LOCK(); pdb = pTask->thdb->process; entry = pdb? pdb->thread_list->next : NULL; @@ -251,6 +253,7 @@ void QUEUE_Signal( HTASK16 hTask ) entry = entry->next; } SYSTEM_UNLOCK(); +#endif /* if ( !wakeup )*/ PostEvent( hTask ); -- GitLab