Commit dbf2bf00 authored by Alexandre Julliard's avatar Alexandre Julliard

Moved MsgWaitForMultipleObject implementation to USER routines, using

a normal Win32 event.
parent 502055ff
...@@ -80,7 +80,6 @@ extern BOOL32 QUEUE_IsExitingQueue( HQUEUE16 hQueue ); ...@@ -80,7 +80,6 @@ extern BOOL32 QUEUE_IsExitingQueue( HQUEUE16 hQueue );
extern void QUEUE_SetExitingQueue( HQUEUE16 hQueue ); extern void QUEUE_SetExitingQueue( HQUEUE16 hQueue );
extern MESSAGEQUEUE *QUEUE_GetSysQueue(void); extern MESSAGEQUEUE *QUEUE_GetSysQueue(void);
extern void QUEUE_Signal( HTASK16 hTask ); extern void QUEUE_Signal( HTASK16 hTask );
extern void QUEUE_Wait(void);
extern void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit ); extern void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit );
extern void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit ); extern void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit );
extern void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue ); extern void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue );
......
...@@ -63,7 +63,6 @@ typedef struct ...@@ -63,7 +63,6 @@ typedef struct
DWORD count; /* Count of valid objects */ DWORD count; /* Count of valid objects */
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 */
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;
...@@ -73,7 +72,7 @@ typedef struct _THDB ...@@ -73,7 +72,7 @@ typedef struct _THDB
{ {
K32OBJ header; /* 00 Kernel object header */ K32OBJ header; /* 00 Kernel object header */
struct _PDB32 *process; /* 08 Process owning this thread */ struct _PDB32 *process; /* 08 Process owning this thread */
K32OBJ *event; /* 0c Thread event */ HANDLE32 event; /* 0c Thread event */
TEB teb; /* 10 Thread exception block */ TEB teb; /* 10 Thread exception block */
DWORD flags; /* 44 Flags */ DWORD flags; /* 44 Flags */
DWORD exit_code; /* 48 Termination status */ DWORD exit_code; /* 48 Termination status */
...@@ -118,6 +117,7 @@ typedef struct _THDB ...@@ -118,6 +117,7 @@ typedef struct _THDB
void *server_tid; /* Server id for this thread */ void *server_tid; /* Server id for this thread */
} THDB; } THDB;
/* Thread queue entry */ /* Thread queue entry */
typedef struct _THREAD_ENTRY typedef struct _THREAD_ENTRY
{ {
...@@ -160,12 +160,6 @@ extern void THREAD_AddQueue( THREAD_QUEUE *queue, THDB *thread ); ...@@ -160,12 +160,6 @@ 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/synchro.c */
extern DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, DWORD timeout,
BOOL32 alertable, BOOL32 wait_msg );
/* scheduler/sysdeps.c */ /* scheduler/sysdeps.c */
extern int SYSDEPS_SpawnThread( THDB *thread ); extern int SYSDEPS_SpawnThread( THDB *thread );
extern void SYSDEPS_ExitThread(void); extern void SYSDEPS_ExitThread(void);
......
...@@ -21,8 +21,7 @@ ...@@ -21,8 +21,7 @@
* SYNC_BuildWaitStruct * SYNC_BuildWaitStruct
*/ */
static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles, static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, BOOL32 wait_msg, BOOL32 wait_all, WAIT_STRUCT *wait )
WAIT_STRUCT *wait )
{ {
DWORD i; DWORD i;
K32OBJ **ptr; K32OBJ **ptr;
...@@ -31,7 +30,6 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles, ...@@ -31,7 +30,6 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
wait->count = count; wait->count = count;
wait->signaled = WAIT_FAILED; wait->signaled = WAIT_FAILED;
wait->wait_all = wait_all; wait->wait_all = wait_all;
wait->wait_msg = wait_msg;
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],
...@@ -49,7 +47,6 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles, ...@@ -49,7 +47,6 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
if (i != count) if (i != count)
{ {
/* There was an error */ /* There was an error */
wait->wait_msg = FALSE;
while (i--) K32OBJ_DecCount( wait->objs[i] ); while (i--) K32OBJ_DecCount( wait->objs[i] );
} }
SYSTEM_UNLOCK(); SYSTEM_UNLOCK();
...@@ -65,7 +62,6 @@ static void SYNC_FreeWaitStruct( WAIT_STRUCT *wait ) ...@@ -65,7 +62,6 @@ static void SYNC_FreeWaitStruct( WAIT_STRUCT *wait )
DWORD i; DWORD i;
K32OBJ **ptr; K32OBJ **ptr;
SYSTEM_LOCK(); SYSTEM_LOCK();
wait->wait_msg = FALSE;
for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++) for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++)
K32OBJ_DecCount( *ptr ); K32OBJ_DecCount( *ptr );
SYSTEM_UNLOCK(); SYSTEM_UNLOCK();
...@@ -75,9 +71,8 @@ static void SYNC_FreeWaitStruct( WAIT_STRUCT *wait ) ...@@ -75,9 +71,8 @@ static void SYNC_FreeWaitStruct( WAIT_STRUCT *wait )
/*********************************************************************** /***********************************************************************
* SYNC_DoWait * SYNC_DoWait
*/ */
DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles, static DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, DWORD timeout, BOOL32 wait_all, DWORD timeout, BOOL32 alertable )
BOOL32 alertable, BOOL32 wait_msg )
{ {
WAIT_STRUCT *wait = &THREAD_Current()->wait_struct; WAIT_STRUCT *wait = &THREAD_Current()->wait_struct;
...@@ -90,14 +85,13 @@ DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles, ...@@ -90,14 +85,13 @@ DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
if (alertable) if (alertable)
FIXME(win32, "alertable not implemented\n" ); FIXME(win32, "alertable not implemented\n" );
if (!SYNC_BuildWaitStruct( count, handles, wait_all, wait_msg, wait )) if (!SYNC_BuildWaitStruct( count, handles, wait_all, wait ))
wait->signaled = WAIT_FAILED; wait->signaled = WAIT_FAILED;
else else
{ {
int flags = 0; int flags = 0;
if (wait_all) flags |= SELECT_ALL; if (wait_all) flags |= SELECT_ALL;
if (alertable) flags |= SELECT_ALERTABLE; if (alertable) flags |= SELECT_ALERTABLE;
if (wait_msg) flags |= SELECT_MSG;
if (timeout != INFINITE32) flags |= SELECT_TIMEOUT; if (timeout != INFINITE32) flags |= SELECT_TIMEOUT;
wait->signaled = CLIENT_Select( count, wait->server, flags, timeout ); wait->signaled = CLIENT_Select( count, wait->server, flags, timeout );
SYNC_FreeWaitStruct( wait ); SYNC_FreeWaitStruct( wait );
...@@ -110,7 +104,7 @@ DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles, ...@@ -110,7 +104,7 @@ DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
*/ */
VOID WINAPI Sleep( DWORD timeout ) VOID WINAPI Sleep( DWORD timeout )
{ {
SYNC_DoWait( 0, NULL, FALSE, timeout, FALSE, FALSE ); SYNC_DoWait( 0, NULL, FALSE, timeout, FALSE );
} }
/****************************************************************************** /******************************************************************************
...@@ -118,7 +112,7 @@ VOID WINAPI Sleep( DWORD timeout ) ...@@ -118,7 +112,7 @@ VOID WINAPI Sleep( DWORD timeout )
*/ */
DWORD WINAPI SleepEx( DWORD timeout, BOOL32 alertable ) DWORD WINAPI SleepEx( DWORD timeout, BOOL32 alertable )
{ {
DWORD ret = SYNC_DoWait( 0, NULL, FALSE, timeout, alertable, FALSE ); DWORD ret = SYNC_DoWait( 0, NULL, FALSE, timeout, alertable );
if (ret != WAIT_IO_COMPLETION) ret = 0; if (ret != WAIT_IO_COMPLETION) ret = 0;
return ret; return ret;
} }
...@@ -129,7 +123,7 @@ DWORD WINAPI SleepEx( DWORD timeout, BOOL32 alertable ) ...@@ -129,7 +123,7 @@ DWORD WINAPI SleepEx( DWORD timeout, BOOL32 alertable )
*/ */
DWORD WINAPI WaitForSingleObject( HANDLE32 handle, DWORD timeout ) DWORD WINAPI WaitForSingleObject( HANDLE32 handle, DWORD timeout )
{ {
return SYNC_DoWait( 1, &handle, FALSE, timeout, FALSE, FALSE ); return SYNC_DoWait( 1, &handle, FALSE, timeout, FALSE );
} }
...@@ -139,7 +133,7 @@ DWORD WINAPI WaitForSingleObject( HANDLE32 handle, DWORD timeout ) ...@@ -139,7 +133,7 @@ DWORD WINAPI WaitForSingleObject( HANDLE32 handle, DWORD timeout )
DWORD WINAPI WaitForSingleObjectEx( HANDLE32 handle, DWORD timeout, DWORD WINAPI WaitForSingleObjectEx( HANDLE32 handle, DWORD timeout,
BOOL32 alertable ) BOOL32 alertable )
{ {
return SYNC_DoWait( 1, &handle, FALSE, timeout, alertable, FALSE ); return SYNC_DoWait( 1, &handle, FALSE, timeout, alertable );
} }
...@@ -149,7 +143,7 @@ DWORD WINAPI WaitForSingleObjectEx( HANDLE32 handle, DWORD timeout, ...@@ -149,7 +143,7 @@ DWORD WINAPI WaitForSingleObjectEx( HANDLE32 handle, DWORD timeout,
DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE32 *handles, DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, DWORD timeout ) BOOL32 wait_all, DWORD timeout )
{ {
return SYNC_DoWait( count, handles, wait_all, timeout, FALSE, FALSE ); return SYNC_DoWait( count, handles, wait_all, timeout, FALSE );
} }
...@@ -160,7 +154,7 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE32 *handles, ...@@ -160,7 +154,7 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, DWORD timeout, BOOL32 wait_all, DWORD timeout,
BOOL32 alertable ) BOOL32 alertable )
{ {
return SYNC_DoWait( count, handles, wait_all, timeout, alertable, FALSE ); return SYNC_DoWait( count, handles, wait_all, timeout, alertable );
} }
...@@ -192,4 +186,3 @@ DWORD WINAPI WIN16_WaitForMultipleObjects( DWORD count, const HANDLE32 *handles, ...@@ -192,4 +186,3 @@ DWORD WINAPI WIN16_WaitForMultipleObjects( DWORD count, const HANDLE32 *handles,
return retval; return retval;
} }
...@@ -100,7 +100,6 @@ THDB *THREAD_IdToTHDB( DWORD id ) ...@@ -100,7 +100,6 @@ THDB *THREAD_IdToTHDB( DWORD id )
} }
/*********************************************************************** /***********************************************************************
* THREAD_AddQueue * THREAD_AddQueue
* *
...@@ -232,6 +231,11 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16, ...@@ -232,6 +231,11 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16,
THREAD_AddQueue( &pdb->thread_list, thdb ); THREAD_AddQueue( &pdb->thread_list, thdb );
/* Create the thread event */
if (!(thdb->event = CreateEvent32A( NULL, FALSE, FALSE, NULL ))) goto error;
thdb->event = ConvertToGlobalHandle( thdb->event );
/* Initialize the thread context */ /* Initialize the thread context */
GET_CS(cs); GET_CS(cs);
...@@ -250,7 +254,7 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16, ...@@ -250,7 +254,7 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16,
error: error:
if (thdb->socket != -1) close( thdb->socket ); if (thdb->socket != -1) close( thdb->socket );
if (thdb->event) K32OBJ_DecCount( thdb->event ); if (thdb->event) CloseHandle( thdb->event );
if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 ); if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 );
if (thdb->teb_sel) SELECTOR_FreeBlock( thdb->teb_sel, 1 ); if (thdb->teb_sel) SELECTOR_FreeBlock( thdb->teb_sel, 1 );
if (thdb->stack_base) VirtualFree( thdb->stack_base, 0, MEM_RELEASE ); if (thdb->stack_base) VirtualFree( thdb->stack_base, 0, MEM_RELEASE );
...@@ -283,6 +287,7 @@ static void THREAD_Destroy( K32OBJ *ptr ) ...@@ -283,6 +287,7 @@ static void THREAD_Destroy( K32OBJ *ptr )
} }
} }
#endif #endif
CloseHandle( thdb->event );
close( thdb->socket ); close( thdb->socket );
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 );
...@@ -683,11 +688,12 @@ BOOL32 WINAPI GetExitCodeThread( ...@@ -683,11 +688,12 @@ 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 */
{ {
struct get_thread_info_reply info; struct get_thread_info_reply reply;
int handle = HANDLE_GetServerHandle( PROCESS_Current(), hthread, int handle = HANDLE_GetServerHandle( PROCESS_Current(), hthread,
K32OBJ_THREAD, THREAD_QUERY_INFORMATION ); K32OBJ_THREAD, THREAD_QUERY_INFORMATION );
if (CLIENT_GetThreadInfo( handle, &info )) return FALSE; CLIENT_SendRequest( REQ_GET_THREAD_INFO, -1, 1, &handle, sizeof(handle) );
if (exitcode) *exitcode = info.exit_code; if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
if (exitcode) *exitcode = reply.exit_code;
return TRUE; return TRUE;
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <sys/types.h> #include <sys/types.h>
#include "message.h" #include "message.h"
#include "winerror.h"
#include "win.h" #include "win.h"
#include "gdi.h" #include "gdi.h"
#include "sysmetrics.h" #include "sysmetrics.h"
...@@ -1475,19 +1476,27 @@ DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE32 *pHandles, ...@@ -1475,19 +1476,27 @@ DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE32 *pHandles,
BOOL32 fWaitAll, DWORD dwMilliseconds, BOOL32 fWaitAll, DWORD dwMilliseconds,
DWORD dwWakeMask ) DWORD dwWakeMask )
{ {
DWORD retv; DWORD i;
HANDLE32 handles[MAXIMUM_WAIT_OBJECTS];
TDB *currTask = (TDB *)GlobalLock16( GetCurrentTask() ); TDB *currTask = (TDB *)GlobalLock16( GetCurrentTask() );
HQUEUE16 hQueue = currTask? currTask->hQueue : 0; HQUEUE16 hQueue = currTask? currTask->hQueue : 0;
MESSAGEQUEUE *msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue ); MESSAGEQUEUE *msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
if (!msgQueue) return 0xFFFFFFFF; if (!msgQueue) return WAIT_FAILED;
if (nCount > MAXIMUM_WAIT_OBJECTS-1)
{
SetLastError( ERROR_INVALID_PARAMETER );
return WAIT_FAILED;
}
msgQueue->changeBits = 0; msgQueue->changeBits = 0;
msgQueue->wakeMask = dwWakeMask; msgQueue->wakeMask = dwWakeMask;
retv = SYNC_DoWait( nCount, pHandles, fWaitAll, dwMilliseconds, FALSE, TRUE ); /* Add the thread event to the handle list */
for (i = 0; i < nCount; i++) handles[i] = pHandles[i];
return retv; handles[nCount] = currTask->thdb->event;
return WaitForMultipleObjects( nCount+1, handles, fWaitAll, dwMilliseconds );
} }
......
...@@ -224,52 +224,27 @@ void QUEUE_Signal( HTASK16 hTask ) ...@@ -224,52 +224,27 @@ void QUEUE_Signal( HTASK16 hTask )
{ {
PDB32 *pdb; PDB32 *pdb;
THREAD_ENTRY *entry; THREAD_ENTRY *entry;
int wakeup = FALSE;
TDB *pTask = (TDB *)GlobalLock16( hTask ); TDB *pTask = (TDB *)GlobalLock16( hTask );
if ( !pTask ) return; if ( !pTask ) return;
TRACE(msg, "calling SYNC_MsgWakeUp\n");
/* Wake up thread waiting for message */ /* Wake up thread waiting for message */
/* NOTE: This should really wake up *the* thread that owns SetEvent( pTask->thdb->event );
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;
if (entry)
for (;;)
{
if (entry->thread->wait_struct.wait_msg)
{
SYNC_MsgWakeUp( entry->thread );
wakeup = TRUE;
}
if (entry == pdb->thread_list) break;
entry = entry->next;
}
SYSTEM_UNLOCK();
#endif
/* if ( !wakeup )*/ PostEvent( hTask );
PostEvent( hTask );
} }
/*********************************************************************** /***********************************************************************
* QUEUE_Wait * QUEUE_Wait
*/ */
void QUEUE_Wait( void ) static void QUEUE_Wait( DWORD wait_mask )
{ {
if ( THREAD_IsWin16( THREAD_Current() ) ) if ( THREAD_IsWin16( THREAD_Current() ) )
WaitEvent( 0 ); WaitEvent( 0 );
else else
{ {
TRACE(msg, "current task is 32-bit, calling SYNC_DoWait\n"); TRACE(msg, "current task is 32-bit, calling SYNC_DoWait\n");
SYNC_DoWait( 0, NULL, FALSE, INFINITE32, FALSE, TRUE ); MsgWaitForMultipleObjects( 0, NULL, FALSE, INFINITE32, wait_mask );
} }
} }
...@@ -341,7 +316,7 @@ void QUEUE_WaitBits( WORD bits ) ...@@ -341,7 +316,7 @@ void QUEUE_WaitBits( WORD bits )
TRACE(msg,"%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask); TRACE(msg,"%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask);
QUEUE_Wait(); QUEUE_Wait( queue->wakeMask );
} }
} }
......
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