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