Commit 55443878 authored by Alexandre Julliard's avatar Alexandre Julliard

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

the server.
parent 63cb0f8b
...@@ -15,22 +15,13 @@ ...@@ -15,22 +15,13 @@
#include "process.h" #include "process.h"
#include "thread.h" #include "thread.h"
#include "heap.h" #include "heap.h"
#include "server.h"
#include "debug.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 ); static void CHANGE_Destroy( K32OBJ *obj );
const K32OBJ_OPS CHANGE_Ops = 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 */ CHANGE_Destroy /* destroy */
}; };
...@@ -48,51 +39,6 @@ typedef struct ...@@ -48,51 +39,6 @@ typedef struct
} CHANGE_OBJECT; } 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 * CHANGE_Destroy
*/ */
...@@ -118,11 +64,24 @@ HANDLE32 WINAPI FindFirstChangeNotification32A( LPCSTR lpPathName, ...@@ -118,11 +64,24 @@ HANDLE32 WINAPI FindFirstChangeNotification32A( LPCSTR lpPathName,
BOOL32 bWatchSubtree, BOOL32 bWatchSubtree,
DWORD dwNotifyFilter ) DWORD dwNotifyFilter )
{ {
HANDLE32 handle;
CHANGE_OBJECT *change; 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) ); 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.type = K32OBJ_CHANGE;
change->header.refcount = 1; change->header.refcount = 1;
...@@ -134,11 +93,9 @@ HANDLE32 WINAPI FindFirstChangeNotification32A( LPCSTR lpPathName, ...@@ -134,11 +93,9 @@ HANDLE32 WINAPI FindFirstChangeNotification32A( LPCSTR lpPathName,
change->wait_queue = NULL; change->wait_queue = NULL;
change->notify = FALSE; change->notify = FALSE;
handle = HANDLE_Alloc( PROCESS_Current(), &change->header, return HANDLE_Alloc( PROCESS_Current(), &change->header,
FILE_ALL_ACCESS /*FIXME*/, TRUE, -1 ); STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE /*FIXME*/,
/* If the allocation failed, the object is already destroyed */ FALSE, reply.handle );
if (handle == INVALID_HANDLE_VALUE32) change = NULL;
return handle;
} }
/**************************************************************************** /****************************************************************************
......
...@@ -45,29 +45,10 @@ ...@@ -45,29 +45,10 @@
#define MAP_ANON MAP_ANONYMOUS #define MAP_ANON MAP_ANONYMOUS
#endif #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 ); static void FILE_Destroy( K32OBJ *obj );
const K32OBJ_OPS FILE_Ops = 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 */ FILE_Destroy /* destroy */
}; };
...@@ -126,58 +107,6 @@ HFILE32 FILE_Alloc( FILE_OBJECT **file, int unix_handle ) ...@@ -126,58 +107,6 @@ HFILE32 FILE_Alloc( FILE_OBJECT **file, int unix_handle )
return 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 * FILE_Destroy
...@@ -1248,6 +1177,7 @@ BOOL32 WINAPI ReadFile( HANDLE32 hFile, LPVOID buffer, DWORD bytesToRead, ...@@ -1248,6 +1177,7 @@ BOOL32 WINAPI ReadFile( HANDLE32 hFile, LPVOID buffer, DWORD bytesToRead,
{ {
K32OBJ *ptr; K32OBJ *ptr;
struct get_read_fd_request req; struct get_read_fd_request req;
int unix_handle, result;
TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToRead ); TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToRead );
...@@ -1258,29 +1188,25 @@ BOOL32 WINAPI ReadFile( HANDLE32 hFile, LPVOID buffer, DWORD bytesToRead, ...@@ -1258,29 +1188,25 @@ BOOL32 WINAPI ReadFile( HANDLE32 hFile, LPVOID buffer, DWORD bytesToRead,
K32OBJ_UNKNOWN, GENERIC_READ, &req.handle ))) K32OBJ_UNKNOWN, GENERIC_READ, &req.handle )))
return FALSE; 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 ); K32OBJ_DecCount( ptr );
if (result == -1) return FALSE; return FALSE;
if (bytesRead) *bytesRead = result;
return TRUE;
} }
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 ((errno == EAGAIN) || (errno == EINTR)) continue;
if (K32OBJ_OPS(ptr)->read) FILE_SetDosError();
status = K32OBJ_OPS(ptr)->read(ptr, buffer, bytesToRead, bytesRead, overlapped ); break;
K32OBJ_DecCount( ptr );
return status;
} }
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, ...@@ -1292,6 +1218,7 @@ BOOL32 WINAPI WriteFile( HANDLE32 hFile, LPCVOID buffer, DWORD bytesToWrite,
{ {
K32OBJ *ptr; K32OBJ *ptr;
struct get_write_fd_request req; struct get_write_fd_request req;
int unix_handle, result;
TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToWrite ); TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToWrite );
...@@ -1302,31 +1229,25 @@ BOOL32 WINAPI WriteFile( HANDLE32 hFile, LPCVOID buffer, DWORD bytesToWrite, ...@@ -1302,31 +1229,25 @@ BOOL32 WINAPI WriteFile( HANDLE32 hFile, LPCVOID buffer, DWORD bytesToWrite,
K32OBJ_UNKNOWN, GENERIC_WRITE, &req.handle ))) K32OBJ_UNKNOWN, GENERIC_WRITE, &req.handle )))
return FALSE; 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 ); K32OBJ_DecCount( ptr );
if (result == -1) return FALSE; return FALSE;
if (bytesWritten) *bytesWritten = result;
return TRUE;
} }
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 ((errno == EAGAIN) || (errno == EINTR)) continue;
if (K32OBJ_OPS(ptr)->write) FILE_SetDosError();
status = K32OBJ_OPS(ptr)->write( ptr, buffer, bytesToWrite, break;
bytesWritten, overlapped );
K32OBJ_DecCount( ptr );
return status;
} }
close( unix_handle );
if (result == -1) return FALSE;
if (bytesWritten) *bytesWritten = result;
return TRUE;
} }
......
...@@ -44,12 +44,6 @@ typedef struct ...@@ -44,12 +44,6 @@ typedef struct
/* Kernel object operations */ /* Kernel object operations */
typedef struct 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 */ void (*destroy)(K32OBJ *); /* Destroy object on refcount==0 */
} K32OBJ_OPS; } K32OBJ_OPS;
......
...@@ -63,7 +63,7 @@ typedef struct _PDB32 ...@@ -63,7 +63,7 @@ typedef struct _PDB32
{ {
K32OBJ header; /* 00 Kernel object header */ K32OBJ header; /* 00 Kernel object header */
DWORD unknown1; /* 08 Unknown */ 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 exit_code; /* 10 Process exit code */
DWORD unknown2; /* 14 Unknown */ DWORD unknown2; /* 14 Unknown */
HANDLE32 heap; /* 18 Default process heap */ HANDLE32 heap; /* 18 Default process heap */
...@@ -102,7 +102,7 @@ typedef struct _PDB32 ...@@ -102,7 +102,7 @@ typedef struct _PDB32
K32OBJ *console_provider; /* b0 Console provider (??) */ K32OBJ *console_provider; /* b0 Console provider (??) */
WORD env_selector; /* b4 Selector to process environment */ WORD env_selector; /* b4 Selector to process environment */
WORD error_mode; /* b6 Error mode */ 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 unknown7; /* bc Unknown */
DWORD unknown8; /* c0 Unknown (NT) */ DWORD unknown8; /* c0 Unknown (NT) */
LCID locale; /* c4 Locale to be queried by GetThreadLocale (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, ...@@ -136,6 +136,8 @@ extern HANDLE32 HANDLE_Alloc( PDB32 *pdb, K32OBJ *ptr, DWORD access,
extern K32OBJ *HANDLE_GetObjPtr( PDB32 *pdb, HANDLE32 handle, extern K32OBJ *HANDLE_GetObjPtr( PDB32 *pdb, HANDLE32 handle,
K32OBJ_TYPE type, DWORD access, K32OBJ_TYPE type, DWORD access,
int *server_handle ); int *server_handle );
extern int HANDLE_GetServerHandle( PDB32 *pdb, HANDLE32 handle,
K32OBJ_TYPE type, DWORD access );
extern BOOL32 HANDLE_SetObjPtr( PDB32 *pdb, HANDLE32 handle, extern BOOL32 HANDLE_SetObjPtr( PDB32 *pdb, HANDLE32 handle,
K32OBJ *ptr, DWORD access ); K32OBJ *ptr, DWORD access );
extern void HANDLE_CloseAll( PDB32 *pdb, K32OBJ *ptr ); extern void HANDLE_CloseAll( PDB32 *pdb, K32OBJ *ptr );
......
...@@ -64,7 +64,6 @@ typedef struct ...@@ -64,7 +64,6 @@ typedef struct
DWORD signaled; /* Index of signaled object (or WAIT_FAILED)*/ DWORD signaled; /* Index of signaled object (or WAIT_FAILED)*/
BOOL32 wait_all; /* Wait for all objects flag */ BOOL32 wait_all; /* Wait for all objects flag */
BOOL32 wait_msg; /* Wait for message flag */ BOOL32 wait_msg; /* Wait for message flag */
BOOL32 use_server; /* Use server call for waiting */
K32OBJ *objs[MAXIMUM_WAIT_OBJECTS]; /* Object pointers */ K32OBJ *objs[MAXIMUM_WAIT_OBJECTS]; /* Object pointers */
int server[MAXIMUM_WAIT_OBJECTS]; /* Server handles */ int server[MAXIMUM_WAIT_OBJECTS]; /* Server handles */
} WAIT_STRUCT; } WAIT_STRUCT;
...@@ -107,8 +106,7 @@ typedef struct _THDB ...@@ -107,8 +106,7 @@ typedef struct _THDB
void *entry_point; /* 1c0 Thread entry point (was: unknown) */ void *entry_point; /* 1c0 Thread entry point (was: unknown) */
void *entry_arg; /* 1c4 Entry point arg (was: unknown) */ void *entry_arg; /* 1c4 Entry point arg (was: unknown) */
int unix_pid; /* 1c8 Unix thread pid (was: unknown) */ int unix_pid; /* 1c8 Unix thread pid (was: unknown) */
K32OBJ *mutex_list; /* 1cc List of owned mutex (was: unknown)*/ DWORD unknown5[3]; /* 1cc Unknown */
DWORD unknown5[2]; /* 1d0 Unknown */
DWORD sys_count[4]; /* 1d8 Syslevel mutex entry counters */ DWORD sys_count[4]; /* 1d8 Syslevel mutex entry counters */
CRITICAL_SECTION *sys_mutex[4];/* 1e8 Syslevel mutex pointers */ CRITICAL_SECTION *sys_mutex[4];/* 1e8 Syslevel mutex pointers */
DWORD unknown6[2]; /* 1f8 Unknown */ DWORD unknown6[2]; /* 1f8 Unknown */
...@@ -162,18 +160,7 @@ extern void THREAD_AddQueue( THREAD_QUEUE *queue, THDB *thread ); ...@@ -162,18 +160,7 @@ extern void THREAD_AddQueue( THREAD_QUEUE *queue, THDB *thread );
extern void THREAD_RemoveQueue( THREAD_QUEUE *queue, THDB *thread ); extern void THREAD_RemoveQueue( THREAD_QUEUE *queue, THDB *thread );
extern DWORD THREAD_TlsAlloc( 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 */ /* 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, extern DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, DWORD timeout, BOOL32 wait_all, DWORD timeout,
BOOL32 alertable, BOOL32 wait_msg ); BOOL32 alertable, BOOL32 wait_msg );
......
...@@ -156,8 +156,6 @@ extern void ASYNC_sigio(int a); ...@@ -156,8 +156,6 @@ extern void ASYNC_sigio(int a);
*/ */
BOOL32 SIGNAL_Init(void) BOOL32 SIGNAL_Init(void)
{ {
extern void SYNC_SetupSignals(void);
#ifdef HAVE_WORKING_SIGALTSTACK #ifdef HAVE_WORKING_SIGALTSTACK
struct sigaltstack ss; struct sigaltstack ss;
ss.ss_sp = SIGNAL_Stack; ss.ss_sp = SIGNAL_Stack;
...@@ -187,8 +185,6 @@ BOOL32 SIGNAL_Init(void) ...@@ -187,8 +185,6 @@ BOOL32 SIGNAL_Init(void)
/* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead */ /* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead */
signal (SIGPIPE, SIG_IGN); signal (SIGPIPE, SIG_IGN);
SYNC_SetupSignals();
return TRUE; return TRUE;
} }
......
...@@ -110,13 +110,6 @@ static void VIRTUAL_DestroyMapping( K32OBJ *obj ); ...@@ -110,13 +110,6 @@ static void VIRTUAL_DestroyMapping( K32OBJ *obj );
const K32OBJ_OPS MEM_MAPPED_FILE_Ops = 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 */ VIRTUAL_DestroyMapping /* destroy */
}; };
......
...@@ -29,12 +29,6 @@ static void SNAPSHOT_Destroy( K32OBJ *obj ); ...@@ -29,12 +29,6 @@ static void SNAPSHOT_Destroy( K32OBJ *obj );
const K32OBJ_OPS SNAPSHOT_Ops = const K32OBJ_OPS SNAPSHOT_Ops =
{ {
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* add_wait */
NULL, /* remove_wait */
NULL, /* read */
NULL, /* write */
SNAPSHOT_Destroy /* destroy */ SNAPSHOT_Destroy /* destroy */
}; };
......
...@@ -328,32 +328,6 @@ int CLIENT_SetDebug( int level ) ...@@ -328,32 +328,6 @@ int CLIENT_SetDebug( int level )
} }
/*********************************************************************** /***********************************************************************
* 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 * CLIENT_CloseHandle
* *
* Send a close handle request. Return 0 if OK. * Send a close handle request. Return 0 if OK.
......
...@@ -18,69 +18,17 @@ ...@@ -18,69 +18,17 @@
typedef struct typedef struct
{ {
K32OBJ header; K32OBJ header;
THREAD_QUEUE wait_queue;
BOOL32 manual_reset;
BOOL32 signaled;
} EVENT; } 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 ); static void EVENT_Destroy( K32OBJ *obj );
const K32OBJ_OPS EVENT_Ops = 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_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) * CreateEvent32A (KERNEL32.156)
*/ */
HANDLE32 WINAPI CreateEvent32A( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset, HANDLE32 WINAPI CreateEvent32A( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset,
...@@ -99,20 +47,15 @@ HANDLE32 WINAPI CreateEvent32A( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset, ...@@ -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_SendRequest( REQ_CREATE_EVENT, -1, 2, &req, sizeof(req), name, len );
CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) ); CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
CHECK_LEN( len, sizeof(reply) ); CHECK_LEN( len, sizeof(reply) );
if (reply.handle == -1) return NULL; if (reply.handle == -1) return 0;
SYSTEM_LOCK(); SYSTEM_LOCK();
event = (EVENT *)K32OBJ_Create( K32OBJ_EVENT, sizeof(*event), name, event = (EVENT *)K32OBJ_Create( K32OBJ_EVENT, sizeof(*event), name,
reply.handle, EVENT_ALL_ACCESS, sa, &handle ); reply.handle, EVENT_ALL_ACCESS, sa, &handle );
if (event) if (event)
{
/* Finish initializing it */
event->wait_queue = NULL;
event->manual_reset = manual_reset;
event->signaled = initial_state;
K32OBJ_DecCount( &event->header ); K32OBJ_DecCount( &event->header );
}
SYSTEM_UNLOCK(); SYSTEM_UNLOCK();
if (handle == INVALID_HANDLE_VALUE32) handle = 0;
return handle; return handle;
} }
...@@ -145,13 +88,29 @@ HANDLE32 WINAPI OpenEvent32A( DWORD access, BOOL32 inherit, LPCSTR name ) ...@@ -145,13 +88,29 @@ HANDLE32 WINAPI OpenEvent32A( DWORD access, BOOL32 inherit, LPCSTR name )
{ {
HANDLE32 handle = 0; HANDLE32 handle = 0;
K32OBJ *obj; K32OBJ *obj;
SYSTEM_LOCK(); struct open_named_obj_request req;
if ((obj = K32OBJ_FindNameType( name, K32OBJ_EVENT )) != NULL) 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 ); SYSTEM_LOCK();
K32OBJ_DecCount( obj ); 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; return handle;
} }
...@@ -169,144 +128,47 @@ HANDLE32 WINAPI OpenEvent32W( DWORD access, BOOL32 inherit, LPCWSTR name ) ...@@ -169,144 +128,47 @@ HANDLE32 WINAPI OpenEvent32W( DWORD access, BOOL32 inherit, LPCWSTR name )
/*********************************************************************** /***********************************************************************
* PulseEvent (KERNEL32.557) * EVENT_Operation
*/ *
BOOL32 WINAPI PulseEvent( HANDLE32 handle ) * Execute an event operation (set,reset,pulse).
{
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)
*/ */
BOOL32 WINAPI ResetEvent( HANDLE32 handle ) static BOOL32 EVENT_Operation( HANDLE32 handle, enum event_op op )
{ {
struct event_op_request req; 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;
}
req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
/*********************************************************************** K32OBJ_EVENT, EVENT_MODIFY_STATE );
* EVENT_Signaled if (req.handle == -1) return FALSE;
*/ req.op = op;
static BOOL32 EVENT_Signaled( K32OBJ *obj, DWORD thread_id ) CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
{ return !CLIENT_WaitReply( NULL, NULL, 0 );
EVENT *event = (EVENT *)obj;
assert( obj->type == K32OBJ_EVENT );
return event->signaled;
} }
/*********************************************************************** /***********************************************************************
* EVENT_Satisfied * PulseEvent (KERNEL32.557)
*
* Wait on this object has been satisfied.
*/ */
static BOOL32 EVENT_Satisfied( K32OBJ *obj, DWORD thread_id ) BOOL32 WINAPI PulseEvent( HANDLE32 handle )
{ {
EVENT *event = (EVENT *)obj; return EVENT_Operation( handle, PULSE_EVENT );
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 * SetEvent (KERNEL32.644)
*
* Add thread to object wait queue.
*/ */
static void EVENT_AddWait( K32OBJ *obj, DWORD thread_id ) BOOL32 WINAPI SetEvent( HANDLE32 handle )
{ {
EVENT *event = (EVENT *)obj; return EVENT_Operation( handle, SET_EVENT );
assert( obj->type == K32OBJ_EVENT );
THREAD_AddQueue( &event->wait_queue, THREAD_ID_TO_THDB(thread_id) );
} }
/*********************************************************************** /***********************************************************************
* EVENT_RemoveWait * ResetEvent (KERNEL32.586)
*
* Remove thread from object wait queue.
*/ */
static void EVENT_RemoveWait( K32OBJ *obj, DWORD thread_id ) BOOL32 WINAPI ResetEvent( HANDLE32 handle )
{ {
EVENT *event = (EVENT *)obj; return EVENT_Operation( handle, RESET_EVENT );
assert( obj->type == K32OBJ_EVENT );
THREAD_RemoveQueue( &event->wait_queue, THREAD_ID_TO_THDB(thread_id) );
} }
...@@ -317,8 +179,6 @@ static void EVENT_Destroy( K32OBJ *obj ) ...@@ -317,8 +179,6 @@ static void EVENT_Destroy( K32OBJ *obj )
{ {
EVENT *event = (EVENT *)obj; EVENT *event = (EVENT *)obj;
assert( obj->type == K32OBJ_EVENT ); 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; obj->type = K32OBJ_UNKNOWN;
HeapFree( SystemHeap, 0, event ); HeapFree( SystemHeap, 0, event );
} }
......
...@@ -192,6 +192,27 @@ K32OBJ *HANDLE_GetObjPtr( PDB32 *pdb, HANDLE32 handle, ...@@ -192,6 +192,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 * HANDLE_SetObjPtr
* *
* Change the object pointer of a handle, and increment the refcount. * Change the object pointer of a handle, and increment the refcount.
...@@ -413,3 +434,38 @@ done: ...@@ -413,3 +434,38 @@ done:
SYSTEM_UNLOCK(); SYSTEM_UNLOCK();
return ret; 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;
}
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
/* The declarations are here to avoid including a lot of unnecessary files */ /* 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 PROCESS_Ops;
extern const K32OBJ_OPS THREAD_Ops; extern const K32OBJ_OPS THREAD_Ops;
extern const K32OBJ_OPS FILE_Ops; extern const K32OBJ_OPS FILE_Ops;
...@@ -30,12 +29,6 @@ extern const K32OBJ_OPS PIPE_Ops; ...@@ -30,12 +29,6 @@ extern const K32OBJ_OPS PIPE_Ops;
static const K32OBJ_OPS K32OBJ_NullOps = static const K32OBJ_OPS K32OBJ_NullOps =
{ {
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* add_wait */
NULL, /* remove_wait */
NULL, /* read */
NULL, /* write */
NULL /* destroy */ NULL /* destroy */
}; };
...@@ -45,7 +38,7 @@ const K32OBJ_OPS * const K32OBJ_Ops[K32OBJ_NBOBJECTS] = ...@@ -45,7 +38,7 @@ const K32OBJ_OPS * const K32OBJ_Ops[K32OBJ_NBOBJECTS] =
&SEMAPHORE_Ops, /* K32OBJ_SEMAPHORE */ &SEMAPHORE_Ops, /* K32OBJ_SEMAPHORE */
&EVENT_Ops, /* K32OBJ_EVENT */ &EVENT_Ops, /* K32OBJ_EVENT */
&MUTEX_Ops, /* K32OBJ_MUTEX */ &MUTEX_Ops, /* K32OBJ_MUTEX */
&CRITICAL_SECTION_Ops, /* K32OBJ_CRITICAL_SECTION */ &K32OBJ_NullOps, /* K32OBJ_CRITICAL_SECTION */
&PROCESS_Ops, /* K32OBJ_PROCESS */ &PROCESS_Ops, /* K32OBJ_PROCESS */
&THREAD_Ops, /* K32OBJ_THREAD */ &THREAD_Ops, /* K32OBJ_THREAD */
&FILE_Ops, /* K32OBJ_FILE */ &FILE_Ops, /* K32OBJ_FILE */
......
...@@ -17,67 +17,17 @@ ...@@ -17,67 +17,17 @@
typedef struct _MUTEX typedef struct _MUTEX
{ {
K32OBJ header; K32OBJ header;
THREAD_QUEUE wait_queue;
DWORD owner;
DWORD count;
BOOL32 abandoned;
struct _MUTEX *next;
struct _MUTEX *prev;
} MUTEX; } 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 ); static void MUTEX_Destroy( K32OBJ *obj );
const K32OBJ_OPS MUTEX_Ops = 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_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) * CreateMutex32A (KERNEL32.166)
*/ */
HANDLE32 WINAPI CreateMutex32A( SECURITY_ATTRIBUTES *sa, BOOL32 owner, HANDLE32 WINAPI CreateMutex32A( SECURITY_ATTRIBUTES *sa, BOOL32 owner,
...@@ -95,37 +45,14 @@ HANDLE32 WINAPI CreateMutex32A( SECURITY_ATTRIBUTES *sa, BOOL32 owner, ...@@ -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_SendRequest( REQ_CREATE_MUTEX, -1, 2, &req, sizeof(req), name, len );
CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) ); CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
CHECK_LEN( len, sizeof(reply) ); CHECK_LEN( len, sizeof(reply) );
if (reply.handle == -1) return NULL; if (reply.handle == -1) return 0;
SYSTEM_LOCK(); SYSTEM_LOCK();
mutex = (MUTEX *)K32OBJ_Create( K32OBJ_MUTEX, sizeof(*mutex), mutex = (MUTEX *)K32OBJ_Create( K32OBJ_MUTEX, sizeof(*mutex),
name, reply.handle, MUTEX_ALL_ACCESS, name, reply.handle, MUTEX_ALL_ACCESS,
sa, &handle ); sa, &handle );
if (mutex) if (mutex) K32OBJ_DecCount( &mutex->header );
{ if (handle == INVALID_HANDLE_VALUE32) handle = 0;
/* 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 */
SYSTEM_UNLOCK(); SYSTEM_UNLOCK();
return handle; return handle;
} }
...@@ -151,13 +78,29 @@ HANDLE32 WINAPI OpenMutex32A( DWORD access, BOOL32 inherit, LPCSTR name ) ...@@ -151,13 +78,29 @@ HANDLE32 WINAPI OpenMutex32A( DWORD access, BOOL32 inherit, LPCSTR name )
{ {
HANDLE32 handle = 0; HANDLE32 handle = 0;
K32OBJ *obj; K32OBJ *obj;
SYSTEM_LOCK(); struct open_named_obj_request req;
if ((obj = K32OBJ_FindNameType( name, K32OBJ_MUTEX )) != NULL) 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 ); SYSTEM_LOCK();
K32OBJ_DecCount( obj ); 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; return handle;
} }
...@@ -180,95 +123,12 @@ HANDLE32 WINAPI OpenMutex32W( DWORD access, BOOL32 inherit, LPCWSTR name ) ...@@ -180,95 +123,12 @@ HANDLE32 WINAPI OpenMutex32W( DWORD access, BOOL32 inherit, LPCWSTR name )
BOOL32 WINAPI ReleaseMutex( HANDLE32 handle ) BOOL32 WINAPI ReleaseMutex( HANDLE32 handle )
{ {
struct release_mutex_request req; 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) );
}
req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
/*********************************************************************** K32OBJ_MUTEX, MUTEX_MODIFY_STATE );
* MUTEX_RemoveWait if (req.handle == -1) return FALSE;
* CLIENT_SendRequest( REQ_RELEASE_MUTEX, -1, 1, &req, sizeof(req) );
* Remove a thread from the object wait queue. return !CLIENT_WaitReply( NULL, NULL, 0 );
*/
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) );
} }
...@@ -279,8 +139,6 @@ static void MUTEX_Destroy( K32OBJ *obj ) ...@@ -279,8 +139,6 @@ static void MUTEX_Destroy( K32OBJ *obj )
{ {
MUTEX *mutex = (MUTEX *)obj; MUTEX *mutex = (MUTEX *)obj;
assert( obj->type == K32OBJ_MUTEX ); 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; obj->type = K32OBJ_UNKNOWN;
HeapFree( SystemHeap, 0, mutex ); HeapFree( SystemHeap, 0, mutex );
} }
...@@ -23,12 +23,6 @@ static void PIPE_Destroy( K32OBJ *obj ); ...@@ -23,12 +23,6 @@ static void PIPE_Destroy( K32OBJ *obj );
const K32OBJ_OPS PIPE_Ops = const K32OBJ_OPS PIPE_Ops =
{ {
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* add_wait */
NULL, /* remove_wait */
NULL, /* read */
NULL, /* write */
PIPE_Destroy /* destroy */ PIPE_Destroy /* destroy */
}; };
......
...@@ -23,20 +23,10 @@ ...@@ -23,20 +23,10 @@
#include "server.h" #include "server.h"
#include "debug.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 ); static void PROCESS_Destroy( K32OBJ *obj );
const K32OBJ_OPS PROCESS_Ops = 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 */ PROCESS_Destroy /* destroy */
}; };
...@@ -295,8 +285,6 @@ static void PROCESS_FreePDB( PDB32 *pdb ) ...@@ -295,8 +285,6 @@ static void PROCESS_FreePDB( PDB32 *pdb )
if (pdb->handle_table) HANDLE_CloseAll( pdb, NULL ); if (pdb->handle_table) HANDLE_CloseAll( pdb, NULL );
ENV_FreeEnvironment( pdb ); ENV_FreeEnvironment( pdb );
if (pdb->heap && (pdb->heap != pdb->system_heap)) HeapDestroy( pdb->heap ); 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 ); DeleteCriticalSection( &pdb->crit_section );
HeapFree( SystemHeap, 0, pdb ); HeapFree( SystemHeap, 0, pdb );
} }
...@@ -325,19 +313,11 @@ static PDB32 *PROCESS_CreatePDB( PDB32 *parent ) ...@@ -325,19 +313,11 @@ static PDB32 *PROCESS_CreatePDB( PDB32 *parent )
pdb->priority = 8; /* Normal */ pdb->priority = 8; /* Normal */
pdb->heap = pdb->system_heap; /* will be changed later on */ 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 */ /* Create the handle table */
if (!HANDLE_CreateTable( pdb, TRUE )) goto error; if (!HANDLE_CreateTable( pdb, TRUE )) goto error;
PROCESS_PDBList_Insert (pdb); PROCESS_PDBList_Insert (pdb);
return pdb; return pdb;
error: error:
...@@ -347,6 +327,21 @@ error: ...@@ -347,6 +327,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 * PROCESS_Init
*/ */
BOOL32 PROCESS_Init(void) BOOL32 PROCESS_Init(void)
...@@ -357,9 +352,8 @@ BOOL32 PROCESS_Init(void) ...@@ -357,9 +352,8 @@ BOOL32 PROCESS_Init(void)
/* Initialize virtual memory management */ /* Initialize virtual memory management */
if (!VIRTUAL_Init()) return FALSE; 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 (!(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 */ /* Create the initial process and thread structures */
if (!(pdb = PROCESS_CreatePDB( NULL ))) return FALSE; if (!(pdb = PROCESS_CreatePDB( NULL ))) return FALSE;
...@@ -376,6 +370,10 @@ BOOL32 PROCESS_Init(void) ...@@ -376,6 +370,10 @@ BOOL32 PROCESS_Init(void)
/* Initialize the first thread */ /* Initialize the first thread */
if (CLIENT_InitThread()) return FALSE; 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; return TRUE;
} }
...@@ -400,6 +398,7 @@ PDB32 *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, ...@@ -400,6 +398,7 @@ PDB32 *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
if (!pdb) return NULL; if (!pdb) return NULL;
info->hThread = info->hProcess = INVALID_HANDLE_VALUE32; info->hThread = info->hProcess = INVALID_HANDLE_VALUE32;
if (!PROCESS_FinishCreatePDB( pdb )) goto error;
/* Create the heap */ /* Create the heap */
...@@ -473,56 +472,6 @@ error: ...@@ -473,56 +472,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 * PROCESS_Destroy
*/ */
static void PROCESS_Destroy( K32OBJ *ptr ) static void PROCESS_Destroy( K32OBJ *ptr )
...@@ -552,7 +501,6 @@ void WINAPI ExitProcess( DWORD status ) ...@@ -552,7 +501,6 @@ void WINAPI ExitProcess( DWORD status )
SYSTEM_LOCK(); SYSTEM_LOCK();
/* FIXME: should kill all running threads of this process */ /* FIXME: should kill all running threads of this process */
pdb->exit_code = status; pdb->exit_code = status;
EVENT_Set( pdb->event );
if (pdb->console) FreeConsole(); if (pdb->console) FreeConsole();
SYSTEM_UNLOCK(); SYSTEM_UNLOCK();
...@@ -566,13 +514,13 @@ void WINAPI ExitProcess( DWORD status ) ...@@ -566,13 +514,13 @@ void WINAPI ExitProcess( DWORD status )
*/ */
BOOL32 WINAPI TerminateProcess( HANDLE32 handle, DWORD exit_code ) BOOL32 WINAPI TerminateProcess( HANDLE32 handle, DWORD exit_code )
{ {
int server_handle; struct terminate_process_request req;
BOOL32 ret;
PDB32 *pdb = PROCESS_GetPtr( handle, PROCESS_TERMINATE, &server_handle ); req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
if (!pdb) return FALSE; K32OBJ_PROCESS, PROCESS_TERMINATE );
ret = !CLIENT_TerminateProcess( server_handle, exit_code ); req.exit_code = exit_code;
K32OBJ_DecCount( &pdb->header ); CLIENT_SendRequest( REQ_TERMINATE_PROCESS, -1, 1, &req, sizeof(req) );
return ret; return !CLIENT_WaitReply( NULL, NULL, 0 );
} }
/*********************************************************************** /***********************************************************************
...@@ -832,8 +780,8 @@ BOOL32 WINAPI GetProcessWorkingSetSize(HANDLE32 hProcess,LPDWORD minset, ...@@ -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! * It really shouldn't be here, but I'll move it when it's been checked!
*/ */
#define SHUTDOWN_NORETRY 1 #define SHUTDOWN_NORETRY 1
extern unsigned int shutdown_noretry = 0; static unsigned int shutdown_noretry = 0;
extern unsigned int shutdown_priority = 0x280L; static unsigned int shutdown_priority = 0x280L;
BOOL32 WINAPI SetProcessShutdownParameters(DWORD level,DWORD flags) BOOL32 WINAPI SetProcessShutdownParameters(DWORD level,DWORD flags)
{ {
if (flags & SHUTDOWN_NORETRY) if (flags & SHUTDOWN_NORETRY)
...@@ -901,28 +849,6 @@ BOOL32 WINAPI WriteProcessMemory(HANDLE32 hProcess, LPVOID lpBaseAddress, ...@@ -901,28 +849,6 @@ BOOL32 WINAPI WriteProcessMemory(HANDLE32 hProcess, LPVOID lpBaseAddress,
} }
/*********************************************************************** /***********************************************************************
* 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) * RegisterServiceProcess (KERNEL, KERNEL32)
* *
* A service process calls this function to ensure that it continues to run * A service process calls this function to ensure that it continues to run
...@@ -942,28 +868,17 @@ DWORD WINAPI RegisterServiceProcess(DWORD dwProcessId, DWORD dwType) ...@@ -942,28 +868,17 @@ DWORD WINAPI RegisterServiceProcess(DWORD dwProcessId, DWORD dwType)
* RETURNS * RETURNS
* Success: TRUE * Success: TRUE
* Failure: FALSE * Failure: FALSE
*
* FIXME
* Should call SetLastError (but doesn't).
*/ */
BOOL32 WINAPI GetExitCodeProcess( BOOL32 WINAPI GetExitCodeProcess(
HANDLE32 hProcess, /* [I] handle to the process */ HANDLE32 hProcess, /* [I] handle to the process */
LPDWORD lpExitCode) /* [O] address to receive termination status */ LPDWORD lpExitCode) /* [O] address to receive termination status */
{ {
PDB32 *process;
int server_handle;
struct get_process_info_reply info; 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, if (CLIENT_GetProcessInfo( handle, &info )) return FALSE;
&server_handle ))) if (lpExitCode) *lpExitCode = info.exit_code;
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 );
return TRUE; return TRUE;
} }
......
...@@ -17,25 +17,12 @@ ...@@ -17,25 +17,12 @@
typedef struct typedef struct
{ {
K32OBJ header; K32OBJ header;
THREAD_QUEUE wait_queue;
LONG count;
LONG max;
} SEMAPHORE; } 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 ); static void SEMAPHORE_Destroy( K32OBJ *obj );
const K32OBJ_OPS SEMAPHORE_Ops = 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 */ SEMAPHORE_Destroy /* destroy */
}; };
...@@ -57,7 +44,7 @@ HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG initial, ...@@ -57,7 +44,7 @@ HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG initial,
if ((max <= 0) || (initial < 0) || (initial > max)) if ((max <= 0) || (initial < 0) || (initial > max))
{ {
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
return INVALID_HANDLE_VALUE32; return 0;
} }
req.initial = (unsigned int)initial; req.initial = (unsigned int)initial;
...@@ -67,21 +54,15 @@ HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG 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_SendRequest( REQ_CREATE_SEMAPHORE, -1, 2, &req, sizeof(req), name, len );
CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) ); CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
CHECK_LEN( len, sizeof(reply) ); CHECK_LEN( len, sizeof(reply) );
if (reply.handle == -1) return NULL; if (reply.handle == -1) return 0;
SYSTEM_LOCK(); SYSTEM_LOCK();
sem = (SEMAPHORE *)K32OBJ_Create( K32OBJ_SEMAPHORE, sizeof(*sem), sem = (SEMAPHORE *)K32OBJ_Create( K32OBJ_SEMAPHORE, sizeof(*sem),
name, reply.handle, SEMAPHORE_ALL_ACCESS, name, reply.handle, SEMAPHORE_ALL_ACCESS,
sa, &handle); sa, &handle);
if (sem) if (sem) K32OBJ_DecCount( &sem->header );
{
/* Finish initializing it */
sem->wait_queue = NULL;
sem->count = initial;
sem->max = max;
K32OBJ_DecCount( &sem->header );
}
SYSTEM_UNLOCK(); SYSTEM_UNLOCK();
if (handle == INVALID_HANDLE_VALUE32) handle = 0;
return handle; return handle;
} }
...@@ -106,13 +87,29 @@ HANDLE32 WINAPI OpenSemaphore32A( DWORD access, BOOL32 inherit, LPCSTR name ) ...@@ -106,13 +87,29 @@ HANDLE32 WINAPI OpenSemaphore32A( DWORD access, BOOL32 inherit, LPCSTR name )
{ {
HANDLE32 handle = 0; HANDLE32 handle = 0;
K32OBJ *obj; K32OBJ *obj;
SYSTEM_LOCK(); struct open_named_obj_request req;
if ((obj = K32OBJ_FindNameType( name, K32OBJ_SEMAPHORE )) != NULL) 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 ); SYSTEM_LOCK();
K32OBJ_DecCount( obj ); 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; return handle;
} }
...@@ -135,111 +132,27 @@ HANDLE32 WINAPI OpenSemaphore32W( DWORD access, BOOL32 inherit, LPCWSTR name ) ...@@ -135,111 +132,27 @@ HANDLE32 WINAPI OpenSemaphore32W( DWORD access, BOOL32 inherit, LPCWSTR name )
BOOL32 WINAPI ReleaseSemaphore( HANDLE32 handle, LONG count, LONG *previous ) BOOL32 WINAPI ReleaseSemaphore( HANDLE32 handle, LONG count, LONG *previous )
{ {
struct release_semaphore_request req; struct release_semaphore_request req;
SEMAPHORE *sem; struct release_semaphore_reply reply;
int len;
if (count < 0) if (count < 0)
{ {
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
return FALSE; return FALSE;
} }
SYSTEM_LOCK(); req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
if (!(sem = (SEMAPHORE *)HANDLE_GetObjPtr( PROCESS_Current(), handle, K32OBJ_SEMAPHORE, SEMAPHORE_MODIFY_STATE );
K32OBJ_SEMAPHORE, if (req.handle == -1) return FALSE;
SEMAPHORE_MODIFY_STATE, &req.handle ))) req.count = (unsigned int)count;
{ CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) );
SYSTEM_UNLOCK(); if (CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) )) return FALSE;
return FALSE; CHECK_LEN( len, sizeof(reply) );
} if (previous) *previous = reply.prev_count;
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();
return TRUE; 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 * SEMAPHORE_Destroy
*/ */
static void SEMAPHORE_Destroy( K32OBJ *obj ) static void SEMAPHORE_Destroy( K32OBJ *obj )
...@@ -247,7 +160,6 @@ static void SEMAPHORE_Destroy( K32OBJ *obj ) ...@@ -247,7 +160,6 @@ static void SEMAPHORE_Destroy( K32OBJ *obj )
SEMAPHORE *sem = (SEMAPHORE *)obj; SEMAPHORE *sem = (SEMAPHORE *)obj;
assert( obj->type == K32OBJ_SEMAPHORE ); assert( obj->type == K32OBJ_SEMAPHORE );
/* There cannot be any thread on the list since the ref count is 0 */ /* There cannot be any thread on the list since the ref count is 0 */
assert( sem->wait_queue == NULL );
obj->type = K32OBJ_UNKNOWN; obj->type = K32OBJ_UNKNOWN;
HeapFree( SystemHeap, 0, sem ); HeapFree( SystemHeap, 0, sem );
} }
...@@ -24,7 +24,7 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles, ...@@ -24,7 +24,7 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, BOOL32 wait_msg, BOOL32 wait_all, BOOL32 wait_msg,
WAIT_STRUCT *wait ) WAIT_STRUCT *wait )
{ {
DWORD i, j; DWORD i;
K32OBJ **ptr; K32OBJ **ptr;
SYSTEM_LOCK(); SYSTEM_LOCK();
...@@ -32,7 +32,6 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles, ...@@ -32,7 +32,6 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
wait->signaled = WAIT_FAILED; wait->signaled = WAIT_FAILED;
wait->wait_all = wait_all; wait->wait_all = wait_all;
wait->wait_msg = wait_msg; wait->wait_msg = wait_msg;
wait->use_server = TRUE;
for (i = 0, ptr = wait->objs; i < count; i++, ptr++) for (i = 0, ptr = wait->objs; i < count; i++, ptr++)
{ {
if (!(*ptr = HANDLE_GetObjPtr( PROCESS_Current(), handles[i], if (!(*ptr = HANDLE_GetObjPtr( PROCESS_Current(), handles[i],
...@@ -43,28 +42,11 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles, ...@@ -43,28 +42,11 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
break; break;
} }
if (wait->server[i] == -1) if (wait->server[i] == -1)
{
WARN(win32,"No server handle for %08x (type %d)\n", WARN(win32,"No server handle for %08x (type %d)\n",
handles[i], (*ptr)->type ); handles[i], (*ptr)->type );
wait->use_server = FALSE;
}
} }
if (!wait->use_server) if (i != count)
{
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))
{ {
/* There was an error */ /* There was an error */
wait->wait_msg = FALSE; wait->wait_msg = FALSE;
...@@ -91,224 +73,6 @@ static void SYNC_FreeWaitStruct( WAIT_STRUCT *wait ) ...@@ -91,224 +73,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 * SYNC_DoWait
*/ */
DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles, DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
...@@ -326,30 +90,18 @@ DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles, ...@@ -326,30 +90,18 @@ DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
if (alertable) if (alertable)
FIXME(win32, "alertable not implemented\n" ); FIXME(win32, "alertable not implemented\n" );
SYSTEM_LOCK();
if (!SYNC_BuildWaitStruct( count, handles, wait_all, wait_msg, wait )) if (!SYNC_BuildWaitStruct( count, handles, wait_all, wait_msg, wait ))
wait->signaled = WAIT_FAILED; wait->signaled = WAIT_FAILED;
else else
{ {
/* Check if we can use a server wait */ int flags = 0;
if (wait->use_server) if (wait_all) flags |= SELECT_ALL;
{ if (alertable) flags |= SELECT_ALERTABLE;
int flags = 0; if (wait_msg) flags |= SELECT_MSG;
SYSTEM_UNLOCK(); if (timeout != INFINITE32) flags |= SELECT_TIMEOUT;
if (wait_all) flags |= SELECT_ALL; wait->signaled = CLIENT_Select( count, wait->server, flags, timeout );
if (alertable) flags |= SELECT_ALERTABLE; SYNC_FreeWaitStruct( wait );
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 );
}
} }
SYSTEM_UNLOCK();
return wait->signaled; return wait->signaled;
} }
......
...@@ -25,20 +25,10 @@ ...@@ -25,20 +25,10 @@
THDB *pCurrentThread; THDB *pCurrentThread;
#endif #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 ); static void THREAD_Destroy( K32OBJ *obj );
const K32OBJ_OPS THREAD_Ops = 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 */ THREAD_Destroy /* destroy */
}; };
...@@ -234,10 +224,6 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16, ...@@ -234,10 +224,6 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16,
0x10000 - sizeof(STACK16FRAME) ); 0x10000 - sizeof(STACK16FRAME) );
} }
/* Allocate the event */
if (!(thdb->event = EVENT_Create( TRUE, FALSE ))) goto error;
/* Create the thread socket */ /* Create the thread socket */
if (CLIENT_NewThread( thdb, server_thandle, server_phandle )) goto error; if (CLIENT_NewThread( thdb, server_thandle, server_phandle )) goto error;
...@@ -274,56 +260,6 @@ error: ...@@ -274,56 +260,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 * THREAD_Destroy
*/ */
static void THREAD_Destroy( K32OBJ *ptr ) static void THREAD_Destroy( K32OBJ *ptr )
...@@ -348,7 +284,6 @@ static void THREAD_Destroy( K32OBJ *ptr ) ...@@ -348,7 +284,6 @@ static void THREAD_Destroy( K32OBJ *ptr )
} }
#endif #endif
close( thdb->socket ); close( thdb->socket );
K32OBJ_DecCount( thdb->event );
SELECTOR_FreeBlock( thdb->teb_sel, 1 ); SELECTOR_FreeBlock( thdb->teb_sel, 1 );
if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 ); if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 );
HeapFree( SystemHeap, 0, thdb ); HeapFree( SystemHeap, 0, thdb );
...@@ -418,10 +353,6 @@ void WINAPI ExitThread( ...@@ -418,10 +353,6 @@ void WINAPI ExitThread(
SYSTEM_LOCK(); SYSTEM_LOCK();
thdb->exit_code = code; 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 */ /* FIXME: should free the stack somehow */
#if 0 #if 0
...@@ -731,15 +662,13 @@ BOOL32 WINAPI TerminateThread( ...@@ -731,15 +662,13 @@ BOOL32 WINAPI TerminateThread(
HANDLE32 handle, /* [in] Handle to thread */ HANDLE32 handle, /* [in] Handle to thread */
DWORD exitcode) /* [in] Exit code for thread */ DWORD exitcode) /* [in] Exit code for thread */
{ {
int server_handle; struct terminate_thread_request req;
BOOL32 ret;
THDB *thread; req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
K32OBJ_THREAD, THREAD_TERMINATE );
if (!(thread = THREAD_GetPtr( handle, THREAD_TERMINATE, &server_handle ))) req.exit_code = exitcode;
return FALSE; CLIENT_SendRequest( REQ_TERMINATE_THREAD, -1, 1, &req, sizeof(req) );
ret = !CLIENT_TerminateThread( server_handle, exitcode ); return !CLIENT_WaitReply( NULL, NULL, 0 );
K32OBJ_DecCount( &thread->header );
return ret;
} }
...@@ -754,19 +683,11 @@ BOOL32 WINAPI GetExitCodeThread( ...@@ -754,19 +683,11 @@ BOOL32 WINAPI GetExitCodeThread(
HANDLE32 hthread, /* [in] Handle to thread */ HANDLE32 hthread, /* [in] Handle to thread */
LPDWORD exitcode) /* [out] Address to receive termination status */ LPDWORD exitcode) /* [out] Address to receive termination status */
{ {
THDB *thread; struct get_thread_info_reply info;
int server_handle; int handle = HANDLE_GetServerHandle( PROCESS_Current(), hthread,
K32OBJ_THREAD, THREAD_QUERY_INFORMATION );
if (!(thread = THREAD_GetPtr( hthread, THREAD_QUERY_INFORMATION, &server_handle ))) if (CLIENT_GetThreadInfo( handle, &info )) return FALSE;
return FALSE; if (exitcode) *exitcode = info.exit_code;
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 );
return TRUE; return TRUE;
} }
......
...@@ -32,14 +32,9 @@ ...@@ -32,14 +32,9 @@
#include "miscemu.h" #include "miscemu.h"
static void DEVICE_Destroy(K32OBJ *dev); static void DEVICE_Destroy(K32OBJ *dev);
const K32OBJ_OPS DEVICE_Ops = const K32OBJ_OPS DEVICE_Ops =
{ {
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* add_wait */
NULL, /* remove_wait */
NULL, /* read */
NULL, /* write */
DEVICE_Destroy /* destroy */ DEVICE_Destroy /* destroy */
}; };
......
...@@ -235,6 +235,8 @@ void QUEUE_Signal( HTASK16 hTask ) ...@@ -235,6 +235,8 @@ void QUEUE_Signal( HTASK16 hTask )
/* NOTE: This should really wake up *the* thread that owns /* NOTE: This should really wake up *the* thread that owns
the queue. Since we dont't have thread-local message the queue. Since we dont't have thread-local message
queues yet, we wake up all waiting threads ... */ queues yet, we wake up all waiting threads ... */
#if 0
/* FIXME: should be replaced by a server event */
SYSTEM_LOCK(); SYSTEM_LOCK();
pdb = pTask->thdb->process; pdb = pTask->thdb->process;
entry = pdb? pdb->thread_list->next : NULL; entry = pdb? pdb->thread_list->next : NULL;
...@@ -251,6 +253,7 @@ void QUEUE_Signal( HTASK16 hTask ) ...@@ -251,6 +253,7 @@ void QUEUE_Signal( HTASK16 hTask )
entry = entry->next; entry = entry->next;
} }
SYSTEM_UNLOCK(); SYSTEM_UNLOCK();
#endif
/* if ( !wakeup )*/ /* if ( !wakeup )*/
PostEvent( hTask ); PostEvent( hTask );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment