ntdll/kernel32: #15
Eric Pouech
pouech-eric at wanadoo.fr
Fri Mar 28 14:20:27 CST 2003
- implemented NtWaitForSingleObject and NtWaitForMultipleObjects
- made WaitForSingleObject and WaitForMultipleObjects use their NTDLL's
counterparts
A+
--
Eric Pouech
-------------- next part --------------
Common subdirectories: dlls/ntdll14/CVS and dlls/ntdll/CVS
diff -u -x '*~' -x '.#*' dlls/ntdll14/ntdll.spec dlls/ntdll/ntdll.spec
--- dlls/ntdll14/ntdll.spec 2003-03-22 08:27:22.000000000 +0100
+++ dlls/ntdll/ntdll.spec 2003-03-24 22:31:52.000000000 +0100
@@ -249,7 +249,7 @@
@ stdcall NtUnmapViewOfSection(long ptr)
@ stub NtVdmControl
@ stub NtW32Call
-@ stub NtWaitForMultipleObjects
+@ stdcall NtWaitForMultipleObjects(long ptr long long ptr)
@ stub NtWaitForProcessMutant
@ stdcall NtWaitForSingleObject(long long long)
@ stub NtWaitHighEventPair
@@ -773,7 +773,7 @@
@ stdcall ZwUnmapViewOfSection(long ptr) NtUnmapViewOfSection
@ stub ZwVdmControl
@ stub ZwW32Call
-@ stub ZwWaitForMultipleObjects
+@ stdcall ZwWaitForMultipleObjects(long ptr long long ptr) NtWaitForMultipleObjects
@ stub ZwWaitForProcessMutant
@ stdcall ZwWaitForSingleObject(long long long) NtWaitForSingleObject
@ stub ZwWaitHighEventPair
diff -u -x '*~' -x '.#*' dlls/ntdll14/om.c dlls/ntdll/om.c
--- dlls/ntdll14/om.c 2003-03-21 18:30:05.000000000 +0100
+++ dlls/ntdll/om.c 2003-03-24 21:46:35.000000000 +0100
@@ -268,19 +268,6 @@
return ret;
}
-/******************************************************************************
- * NtWaitForSingleObject [NTDLL.@]
- * ZwWaitForSingleObject [NTDLL.@]
- */
-NTSTATUS WINAPI NtWaitForSingleObject(
- IN HANDLE Object,
- IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Time)
-{
- FIXME("(%p,0x%08x,%p),stub!\n",Object,Alertable,Time);
- return 0;
-}
-
/*
* Directory functions
*/
diff -u -x '*~' -x '.#*' dlls/ntdll14/sync.c dlls/ntdll/sync.c
--- dlls/ntdll14/sync.c 2002-12-05 21:20:12.000000000 +0100
+++ dlls/ntdll/sync.c 2003-03-24 22:33:38.000000000 +0100
@@ -1,6 +1,7 @@
/*
* Process synchronisation
*
+ * Copyright 1997 Alexandre Julliard
* Copyright 1999, 2000 Juergen Schmied
*
* This library is free software; you can redistribute it and/or
@@ -18,15 +19,32 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "config.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_POLL_H
+# include <sys/poll.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <string.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <time.h>
-#include "wine/debug.h"
+#include "file.h" /* for DOSFS_UnixTimeToFileTime */
+#include "thread.h"
#include "winerror.h"
-#include "wine/unicode.h"
#include "wine/server.h"
+#include "async.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
#include "winternl.h"
#include "ntdll_misc.h"
@@ -261,3 +279,204 @@
FIXME("(%p)\n", EventHandle);
return STATUS_SUCCESS;
}
+
+/***********************************************************************
+ * get_timeout
+ */
+inline static void get_timeout( struct timeval *when, int timeout )
+{
+ gettimeofday( when, 0 );
+ if (timeout)
+ {
+ long sec = timeout / 1000;
+ if ((when->tv_usec += (timeout - 1000*sec) * 1000) >= 1000000)
+ {
+ when->tv_usec -= 1000000;
+ when->tv_sec++;
+ }
+ when->tv_sec += sec;
+ }
+}
+
+/***********************************************************************
+ * check_async_list
+ *
+ * Process a status event from the server.
+ */
+static void WINAPI check_async_list(async_private *asp, DWORD status)
+{
+ async_private *ovp;
+ DWORD ovp_status;
+
+ for( ovp = NtCurrentTeb()->pending_list; ovp && ovp != asp; ovp = ovp->next );
+
+ if(!ovp)
+ return;
+
+ if( status != STATUS_ALERTED )
+ {
+ ovp_status = status;
+ ovp->ops->set_status (ovp, status);
+ }
+ else ovp_status = ovp->ops->get_status (ovp);
+
+ if( ovp_status == STATUS_PENDING ) ovp->func( ovp );
+
+ /* This will destroy all but PENDING requests */
+ register_old_async( ovp );
+}
+
+
+/***********************************************************************
+ * wait_reply
+ *
+ * Wait for a reply on the waiting pipe of the current thread.
+ */
+static int wait_reply( void *cookie )
+{
+ int signaled;
+ struct wake_up_reply reply;
+ for (;;)
+ {
+ int ret;
+ ret = read( NtCurrentTeb()->wait_fd[0], &reply, sizeof(reply) );
+ if (ret == sizeof(reply))
+ {
+ if (!reply.cookie) break; /* thread got killed */
+ if (reply.cookie == cookie) return reply.signaled;
+ /* we stole another reply, wait for the real one */
+ signaled = wait_reply( cookie );
+ /* and now put the wrong one back in the pipe */
+ for (;;)
+ {
+ ret = write( NtCurrentTeb()->wait_fd[1], &reply, sizeof(reply) );
+ if (ret == sizeof(reply)) break;
+ if (ret >= 0) server_protocol_error( "partial wakeup write %d\n", ret );
+ if (errno == EINTR) continue;
+ server_protocol_perror("wakeup write");
+ }
+ return signaled;
+ }
+ if (ret >= 0) server_protocol_error( "partial wakeup read %d\n", ret );
+ if (errno == EINTR) continue;
+ server_protocol_perror("wakeup read");
+ }
+ /* the server closed the connection; time to die... */
+ SYSDEPS_AbortThread(0);
+}
+
+
+/***********************************************************************
+ * call_apcs
+ *
+ * Call outstanding APCs.
+ */
+static void call_apcs( BOOL alertable )
+{
+ FARPROC proc = NULL;
+ FILETIME ft;
+ void *args[4];
+
+ for (;;)
+ {
+ int type = APC_NONE;
+ SERVER_START_REQ( get_apc )
+ {
+ req->alertable = alertable;
+ wine_server_set_reply( req, args, sizeof(args) );
+ if (!wine_server_call( req ))
+ {
+ type = reply->type;
+ proc = reply->func;
+ }
+ }
+ SERVER_END_REQ;
+
+ switch(type)
+ {
+ case APC_NONE:
+ return; /* no more APCs */
+ case APC_ASYNC:
+ proc( args[0], args[1]);
+ break;
+ case APC_USER:
+ proc( args[0] );
+ break;
+ case APC_TIMER:
+ /* convert sec/usec to NT time */
+ DOSFS_UnixTimeToFileTime( (time_t)args[0], &ft, (DWORD)args[1] * 10 );
+ proc( args[2], ft.dwLowDateTime, ft.dwHighDateTime );
+ break;
+ case APC_ASYNC_IO:
+ check_async_list ( args[0], (DWORD) args[1]);
+ break;
+ default:
+ server_protocol_error( "get_apc_request: bad type %d\n", type );
+ break;
+ }
+ }
+}
+
+/* wait operations */
+
+/******************************************************************
+ * NtWaitForMultipleObjects (NTDLL.@)
+ *
+ */
+NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles,
+ BOOLEAN wait_all, BOOLEAN alertable,
+ PLARGE_INTEGER timeout)
+{
+ int ret, cookie;
+ struct timeval tv;
+
+ if (count > MAXIMUM_WAIT_OBJECTS) return STATUS_INVALID_PARAMETER_1;
+
+ if (timeout->QuadPart == (LONG)INFINITE) tv.tv_sec = tv.tv_usec = 0;
+ else
+ {
+ if (timeout->HighPart != 0) FIXME("Unsupported yet\n");
+ get_timeout( &tv, timeout->LowPart );
+ }
+
+ for (;;)
+ {
+ SERVER_START_REQ( select )
+ {
+ req->flags = SELECT_INTERRUPTIBLE;
+ req->cookie = &cookie;
+ req->sec = tv.tv_sec;
+ req->usec = tv.tv_usec;
+ wine_server_add_data( req, handles, count * sizeof(HANDLE) );
+
+ if (wait_all) req->flags |= SELECT_ALL;
+ if (alertable) req->flags |= SELECT_ALERTABLE;
+ if (timeout->QuadPart != (LONG)INFINITE) req->flags |= SELECT_TIMEOUT;
+
+ ret = wine_server_call( req );
+ }
+ SERVER_END_REQ;
+ if (ret == STATUS_PENDING) ret = wait_reply( &cookie );
+ if (ret != STATUS_USER_APC) break;
+ call_apcs( alertable );
+ if (alertable) break;
+ }
+ return ret;
+
+ if (HIWORD(ret)) /* is it an error code? */
+ {
+ SetLastError( RtlNtStatusToDosError(ret) );
+ ret = WAIT_FAILED;
+ }
+ return ret;
+}
+
+
+/******************************************************************
+ * NtWaitForSingleObject (NTDLL.@)
+ *
+ */
+NTSTATUS WINAPI NtWaitForSingleObject(HANDLE handle, BOOLEAN alertable, PLARGE_INTEGER timeout )
+{
+ return NtWaitForMultipleObjects( 1, &handle, FALSE, alertable, timeout);
+}
Common subdirectories: dlls/ntdll14/tests and dlls/ntdll/tests
Common subdirectories: if163214/CVS and if1632/CVS
Common subdirectories: include14/bitmaps and include/bitmaps
Common subdirectories: include14/CVS and include/CVS
Common subdirectories: include14/msvcrt and include/msvcrt
Common subdirectories: include14/wine and include/wine
diff -u -x '*~' -x '.#*' include14/winternl.h include/winternl.h
--- include14/winternl.h 2003-03-22 08:27:31.000000000 +0100
+++ include/winternl.h 2003-03-24 21:30:06.000000000 +0100
@@ -872,6 +872,7 @@
NTSTATUS WINAPI NtUnlockVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG);
NTSTATUS WINAPI NtUnmapViewOfSection(HANDLE,PVOID);
NTSTATUS WINAPI NtWaitForSingleObject(HANDLE,BOOLEAN,PLARGE_INTEGER);
+NTSTATUS WINAPI NtWaitForMultipleObjects(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,PLARGE_INTEGER);
void WINAPI RtlAcquirePebLock(void);
BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK,BYTE);
Common subdirectories: loader14/CVS and loader/CVS
Common subdirectories: loader14/ne and loader/ne
Common subdirectories: misc14/CVS and misc/CVS
Common subdirectories: relay3214/CVS and relay32/CVS
Common subdirectories: scheduler14/CVS and scheduler/CVS
diff -u -x '*~' -x '.#*' scheduler14/synchro.c scheduler/synchro.c
--- scheduler14/synchro.c 2002-08-27 18:05:49.000000000 +0200
+++ scheduler/synchro.c 2003-03-24 21:44:46.000000000 +0100
@@ -20,165 +20,11 @@
#include "config.h"
-#include <assert.h>
-#include <errno.h>
-#include <signal.h>
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_POLL_H
-# include <sys/poll.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#include <string.h>
-
-#include "file.h" /* for DOSFS_UnixTimeToFileTime */
-#include "thread.h"
-#include "winerror.h"
-#include "wine/server.h"
-#include "async.h"
+#include "winbase.h"
+#include "winternl.h"
/***********************************************************************
- * get_timeout
- */
-inline static void get_timeout( struct timeval *when, int timeout )
-{
- gettimeofday( when, 0 );
- if (timeout)
- {
- long sec = timeout / 1000;
- if ((when->tv_usec += (timeout - 1000*sec) * 1000) >= 1000000)
- {
- when->tv_usec -= 1000000;
- when->tv_sec++;
- }
- when->tv_sec += sec;
- }
-}
-
-/***********************************************************************
- * check_async_list
- *
- * Process a status event from the server.
- */
-static void WINAPI check_async_list(async_private *asp, DWORD status)
-{
- async_private *ovp;
- DWORD ovp_status;
-
- for( ovp = NtCurrentTeb()->pending_list; ovp && ovp != asp; ovp = ovp->next );
-
- if(!ovp)
- return;
-
- if( status != STATUS_ALERTED )
- {
- ovp_status = status;
- ovp->ops->set_status (ovp, status);
- }
- else ovp_status = ovp->ops->get_status (ovp);
-
- if( ovp_status == STATUS_PENDING ) ovp->func( ovp );
-
- /* This will destroy all but PENDING requests */
- register_old_async( ovp );
-}
-
-
-/***********************************************************************
- * wait_reply
- *
- * Wait for a reply on the waiting pipe of the current thread.
- */
-static int wait_reply( void *cookie )
-{
- int signaled;
- struct wake_up_reply reply;
- for (;;)
- {
- int ret;
- ret = read( NtCurrentTeb()->wait_fd[0], &reply, sizeof(reply) );
- if (ret == sizeof(reply))
- {
- if (!reply.cookie) break; /* thread got killed */
- if (reply.cookie == cookie) return reply.signaled;
- /* we stole another reply, wait for the real one */
- signaled = wait_reply( cookie );
- /* and now put the wrong one back in the pipe */
- for (;;)
- {
- ret = write( NtCurrentTeb()->wait_fd[1], &reply, sizeof(reply) );
- if (ret == sizeof(reply)) break;
- if (ret >= 0) server_protocol_error( "partial wakeup write %d\n", ret );
- if (errno == EINTR) continue;
- server_protocol_perror("wakeup write");
- }
- return signaled;
- }
- if (ret >= 0) server_protocol_error( "partial wakeup read %d\n", ret );
- if (errno == EINTR) continue;
- server_protocol_perror("wakeup read");
- }
- /* the server closed the connection; time to die... */
- SYSDEPS_AbortThread(0);
-}
-
-
-/***********************************************************************
- * call_apcs
- *
- * Call outstanding APCs.
- */
-static void call_apcs( BOOL alertable )
-{
- FARPROC proc = NULL;
- FILETIME ft;
- void *args[4];
-
- for (;;)
- {
- int type = APC_NONE;
- SERVER_START_REQ( get_apc )
- {
- req->alertable = alertable;
- wine_server_set_reply( req, args, sizeof(args) );
- if (!wine_server_call( req ))
- {
- type = reply->type;
- proc = reply->func;
- }
- }
- SERVER_END_REQ;
-
- switch(type)
- {
- case APC_NONE:
- return; /* no more APCs */
- case APC_ASYNC:
- proc( args[0], args[1]);
- break;
- case APC_USER:
- proc( args[0] );
- break;
- case APC_TIMER:
- /* convert sec/usec to NT time */
- DOSFS_UnixTimeToFileTime( (time_t)args[0], &ft, (DWORD)args[1] * 10 );
- proc( args[2], ft.dwLowDateTime, ft.dwHighDateTime );
- break;
- case APC_ASYNC_IO:
- check_async_list ( args[0], (DWORD) args[1]);
- break;
- default:
- server_protocol_error( "get_apc_request: bad type %d\n", type );
- break;
- }
- }
-}
-
-/***********************************************************************
* Sleep (KERNEL32.@)
*/
VOID WINAPI Sleep( DWORD timeout )
@@ -233,46 +79,17 @@
BOOL wait_all, DWORD timeout,
BOOL alertable )
{
- int ret, cookie;
- struct timeval tv;
-
- if (count > MAXIMUM_WAIT_OBJECTS)
- {
- SetLastError( ERROR_INVALID_PARAMETER );
- return WAIT_FAILED;
- }
-
- if (timeout == INFINITE) tv.tv_sec = tv.tv_usec = 0;
- else get_timeout( &tv, timeout );
+ NTSTATUS nts;
+ LARGE_INTEGER li;
- for (;;)
+ li.QuadPart = (LONG)timeout;
+ nts = NtWaitForMultipleObjects( count, handles, wait_all, alertable, &li );
+ if (HIWORD(nts)) /* is it an error code? */
{
- SERVER_START_REQ( select )
- {
- req->flags = SELECT_INTERRUPTIBLE;
- req->cookie = &cookie;
- req->sec = tv.tv_sec;
- req->usec = tv.tv_usec;
- wine_server_add_data( req, handles, count * sizeof(HANDLE) );
-
- if (wait_all) req->flags |= SELECT_ALL;
- if (alertable) req->flags |= SELECT_ALERTABLE;
- if (timeout != INFINITE) req->flags |= SELECT_TIMEOUT;
-
- ret = wine_server_call( req );
- }
- SERVER_END_REQ;
- if (ret == STATUS_PENDING) ret = wait_reply( &cookie );
- if (ret != STATUS_USER_APC) break;
- call_apcs( alertable );
- if (alertable) break;
+ SetLastError( RtlNtStatusToDosError(nts) );
+ nts = WAIT_FAILED;
}
- if (HIWORD(ret)) /* is it an error code? */
- {
- SetLastError( RtlNtStatusToDosError(ret) );
- ret = WAIT_FAILED;
- }
- return ret;
+ return nts;
}
More information about the wine-patches
mailing list