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