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 );
extern void QUEUE_SetExitingQueue( HQUEUE16 hQueue );
extern MESSAGEQUEUE *QUEUE_GetSysQueue(void);
extern void QUEUE_Signal( HTASK16 hTask );
extern void QUEUE_Wait(void);
extern void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit );
extern void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit );
extern void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue );
......
......@@ -63,7 +63,6 @@ typedef struct
DWORD count; /* Count of valid objects */
DWORD signaled; /* Index of signaled object (or WAIT_FAILED)*/
BOOL32 wait_all; /* Wait for all objects flag */
BOOL32 wait_msg; /* Wait for message flag */
K32OBJ *objs[MAXIMUM_WAIT_OBJECTS]; /* Object pointers */
int server[MAXIMUM_WAIT_OBJECTS]; /* Server handles */
} WAIT_STRUCT;
......@@ -73,7 +72,7 @@ typedef struct _THDB
{
K32OBJ header; /* 00 Kernel object header */
struct _PDB32 *process; /* 08 Process owning this thread */
K32OBJ *event; /* 0c Thread event */
HANDLE32 event; /* 0c Thread event */
TEB teb; /* 10 Thread exception block */
DWORD flags; /* 44 Flags */
DWORD exit_code; /* 48 Termination status */
......@@ -118,6 +117,7 @@ typedef struct _THDB
void *server_tid; /* Server id for this thread */
} THDB;
/* Thread queue entry */
typedef struct _THREAD_ENTRY
{
......@@ -160,12 +160,6 @@ extern void THREAD_AddQueue( THREAD_QUEUE *queue, THDB *thread );
extern void THREAD_RemoveQueue( THREAD_QUEUE *queue, THDB *thread );
extern DWORD THREAD_TlsAlloc( THDB *thread );
/* scheduler/synchro.c */
extern DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, DWORD timeout,
BOOL32 alertable, BOOL32 wait_msg );
/* scheduler/sysdeps.c */
extern int SYSDEPS_SpawnThread( THDB *thread );
extern void SYSDEPS_ExitThread(void);
......
......@@ -21,8 +21,7 @@
* SYNC_BuildWaitStruct
*/
static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, BOOL32 wait_msg,
WAIT_STRUCT *wait )
BOOL32 wait_all, WAIT_STRUCT *wait )
{
DWORD i;
K32OBJ **ptr;
......@@ -31,7 +30,6 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
wait->count = count;
wait->signaled = WAIT_FAILED;
wait->wait_all = wait_all;
wait->wait_msg = wait_msg;
for (i = 0, ptr = wait->objs; i < count; i++, ptr++)
{
if (!(*ptr = HANDLE_GetObjPtr( PROCESS_Current(), handles[i],
......@@ -49,7 +47,6 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
if (i != count)
{
/* There was an error */
wait->wait_msg = FALSE;
while (i--) K32OBJ_DecCount( wait->objs[i] );
}
SYSTEM_UNLOCK();
......@@ -65,7 +62,6 @@ static void SYNC_FreeWaitStruct( WAIT_STRUCT *wait )
DWORD i;
K32OBJ **ptr;
SYSTEM_LOCK();
wait->wait_msg = FALSE;
for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++)
K32OBJ_DecCount( *ptr );
SYSTEM_UNLOCK();
......@@ -75,9 +71,8 @@ static void SYNC_FreeWaitStruct( WAIT_STRUCT *wait )
/***********************************************************************
* SYNC_DoWait
*/
DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, DWORD timeout,
BOOL32 alertable, BOOL32 wait_msg )
static DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, DWORD timeout, BOOL32 alertable )
{
WAIT_STRUCT *wait = &THREAD_Current()->wait_struct;
......@@ -90,14 +85,13 @@ DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
if (alertable)
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;
else
{
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 );
......@@ -110,7 +104,7 @@ DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
*/
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 )
*/
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;
return ret;
}
......@@ -129,7 +123,7 @@ DWORD WINAPI SleepEx( DWORD timeout, BOOL32 alertable )
*/
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 )
DWORD WINAPI WaitForSingleObjectEx( HANDLE32 handle, DWORD timeout,
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,
DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE32 *handles,
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,
BOOL32 wait_all, DWORD timeout,
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,
return retval;
}
......@@ -100,7 +100,6 @@ THDB *THREAD_IdToTHDB( DWORD id )
}
/***********************************************************************
* THREAD_AddQueue
*
......@@ -232,6 +231,11 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16,
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 */
GET_CS(cs);
......@@ -250,7 +254,7 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16,
error:
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_sel) SELECTOR_FreeBlock( thdb->teb_sel, 1 );
if (thdb->stack_base) VirtualFree( thdb->stack_base, 0, MEM_RELEASE );
......@@ -283,6 +287,7 @@ static void THREAD_Destroy( K32OBJ *ptr )
}
}
#endif
CloseHandle( thdb->event );
close( thdb->socket );
SELECTOR_FreeBlock( thdb->teb_sel, 1 );
if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 );
......@@ -683,11 +688,12 @@ BOOL32 WINAPI GetExitCodeThread(
HANDLE32 hthread, /* [in] Handle to thread */
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,
K32OBJ_THREAD, THREAD_QUERY_INFORMATION );
if (CLIENT_GetThreadInfo( handle, &info )) return FALSE;
if (exitcode) *exitcode = info.exit_code;
CLIENT_SendRequest( REQ_GET_THREAD_INFO, -1, 1, &handle, sizeof(handle) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
if (exitcode) *exitcode = reply.exit_code;
return TRUE;
}
......
......@@ -11,6 +11,7 @@
#include <sys/types.h>
#include "message.h"
#include "winerror.h"
#include "win.h"
#include "gdi.h"
#include "sysmetrics.h"
......@@ -1475,19 +1476,27 @@ DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE32 *pHandles,
BOOL32 fWaitAll, DWORD dwMilliseconds,
DWORD dwWakeMask )
{
DWORD retv;
DWORD i;
HANDLE32 handles[MAXIMUM_WAIT_OBJECTS];
TDB *currTask = (TDB *)GlobalLock16( GetCurrentTask() );
HQUEUE16 hQueue = currTask? currTask->hQueue : 0;
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->wakeMask = dwWakeMask;
retv = SYNC_DoWait( nCount, pHandles, fWaitAll, dwMilliseconds, FALSE, TRUE );
return retv;
/* Add the thread event to the handle list */
for (i = 0; i < nCount; i++) handles[i] = pHandles[i];
handles[nCount] = currTask->thdb->event;
return WaitForMultipleObjects( nCount+1, handles, fWaitAll, dwMilliseconds );
}
......
......@@ -224,52 +224,27 @@ void QUEUE_Signal( HTASK16 hTask )
{
PDB32 *pdb;
THREAD_ENTRY *entry;
int wakeup = FALSE;
TDB *pTask = (TDB *)GlobalLock16( hTask );
if ( !pTask ) return;
TRACE(msg, "calling SYNC_MsgWakeUp\n");
/* Wake up thread waiting for message */
/* 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;
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
SetEvent( pTask->thdb->event );
/* if ( !wakeup )*/
PostEvent( hTask );
PostEvent( hTask );
}
/***********************************************************************
* QUEUE_Wait
*/
void QUEUE_Wait( void )
static void QUEUE_Wait( DWORD wait_mask )
{
if ( THREAD_IsWin16( THREAD_Current() ) )
WaitEvent( 0 );
else
{
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 )
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