[PATCH 3/7] ntdll: Move Rtl(Un)RegisterWait code below threadpool structs.

Rémi Bernon rbernon at codeweavers.com
Wed Dec 2 04:01:12 CST 2020


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/ntdll/threadpool.c | 432 ++++++++++++++++++++--------------------
 1 file changed, 216 insertions(+), 216 deletions(-)

diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 1d64bd82bf4..db645118059 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -553,222 +553,6 @@ static inline PLARGE_INTEGER get_nt_timeout( PLARGE_INTEGER pTime, ULONG timeout
     return pTime;
 }
 
-static void delete_wait_work_item(struct wait_work_item *wait_work_item)
-{
-    NtClose( wait_work_item->CancelEvent );
-    RtlFreeHeap( GetProcessHeap(), 0, wait_work_item );
-}
-
-static DWORD CALLBACK wait_thread_proc(LPVOID Arg)
-{
-    struct wait_work_item *wait_work_item = Arg;
-    NTSTATUS status;
-    BOOLEAN alertable = (wait_work_item->Flags & WT_EXECUTEINIOTHREAD) != 0;
-    HANDLE handles[2] = { wait_work_item->Object, wait_work_item->CancelEvent };
-    LARGE_INTEGER timeout;
-    HANDLE completion_event;
-
-    TRACE("\n");
-
-    while (TRUE)
-    {
-        status = NtWaitForMultipleObjects( 2, handles, TRUE, alertable,
-                                           get_nt_timeout( &timeout, wait_work_item->Milliseconds ) );
-        if (status == STATUS_WAIT_0 || status == STATUS_TIMEOUT)
-        {
-            BOOLEAN TimerOrWaitFired;
-
-            if (status == STATUS_WAIT_0)
-            {
-                TRACE( "object %p signaled, calling callback %p with context %p\n",
-                    wait_work_item->Object, wait_work_item->Callback,
-                    wait_work_item->Context );
-                TimerOrWaitFired = FALSE;
-            }
-            else
-            {
-                TRACE( "wait for object %p timed out, calling callback %p with context %p\n",
-                    wait_work_item->Object, wait_work_item->Callback,
-                    wait_work_item->Context );
-                TimerOrWaitFired = TRUE;
-            }
-            InterlockedExchange( &wait_work_item->CallbackInProgress, TRUE );
-            if (wait_work_item->CompletionEvent)
-            {
-                TRACE( "Work has been canceled.\n" );
-                break;
-            }
-            wait_work_item->Callback( wait_work_item->Context, TimerOrWaitFired );
-            InterlockedExchange( &wait_work_item->CallbackInProgress, FALSE );
-
-            if (wait_work_item->Flags & WT_EXECUTEONLYONCE)
-                break;
-        }
-        else if (status != STATUS_USER_APC)
-            break;
-    }
-
-
-    if (InterlockedIncrement( &wait_work_item->DeleteCount ) == 2 )
-    {
-        completion_event = wait_work_item->CompletionEvent;
-        delete_wait_work_item( wait_work_item );
-        if (completion_event && completion_event != INVALID_HANDLE_VALUE)
-            NtSetEvent( completion_event, NULL );
-    }
-
-    return 0;
-}
-
-/***********************************************************************
- *              RtlRegisterWait   (NTDLL.@)
- *
- * Registers a wait for a handle to become signaled.
- *
- * PARAMS
- *  NewWaitObject [I] Handle to the new wait object. Use RtlDeregisterWait() to free it.
- *  Object   [I] Object to wait to become signaled.
- *  Callback [I] Callback function to execute when the wait times out or the handle is signaled.
- *  Context  [I] Context to pass to the callback function when it is executed.
- *  Milliseconds [I] Number of milliseconds to wait before timing out.
- *  Flags    [I] Flags. See notes.
- *
- * RETURNS
- *  Success: STATUS_SUCCESS.
- *  Failure: Any NTSTATUS code.
- *
- * NOTES
- *  Flags can be one or more of the following:
- *|WT_EXECUTEDEFAULT - Executes the work item in a non-I/O worker thread.
- *|WT_EXECUTEINIOTHREAD - Executes the work item in an I/O worker thread.
- *|WT_EXECUTEINPERSISTENTTHREAD - Executes the work item in a thread that is persistent.
- *|WT_EXECUTELONGFUNCTION - Hints that the execution can take a long time.
- *|WT_TRANSFER_IMPERSONATION - Executes the function with the current access token.
- */
-NTSTATUS WINAPI RtlRegisterWait(PHANDLE NewWaitObject, HANDLE Object,
-                                RTL_WAITORTIMERCALLBACKFUNC Callback,
-                                PVOID Context, ULONG Milliseconds, ULONG Flags)
-{
-    struct wait_work_item *wait_work_item;
-    NTSTATUS status;
-
-    TRACE( "(%p, %p, %p, %p, %d, 0x%x)\n", NewWaitObject, Object, Callback, Context, Milliseconds, Flags );
-
-    wait_work_item = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*wait_work_item) );
-    if (!wait_work_item)
-        return STATUS_NO_MEMORY;
-
-    wait_work_item->Object = Object;
-    wait_work_item->Callback = Callback;
-    wait_work_item->Context = Context;
-    wait_work_item->Milliseconds = Milliseconds;
-    wait_work_item->Flags = Flags;
-    wait_work_item->CallbackInProgress = FALSE;
-    wait_work_item->DeleteCount = 0;
-    wait_work_item->CompletionEvent = NULL;
-
-    status = NtCreateEvent( &wait_work_item->CancelEvent, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE );
-    if (status != STATUS_SUCCESS)
-    {
-        RtlFreeHeap( GetProcessHeap(), 0, wait_work_item );
-        return status;
-    }
-
-    Flags = Flags & (WT_EXECUTEINIOTHREAD | WT_EXECUTEINPERSISTENTTHREAD |
-                     WT_EXECUTELONGFUNCTION | WT_TRANSFER_IMPERSONATION);
-    status = RtlQueueWorkItem( wait_thread_proc, wait_work_item, Flags );
-    if (status != STATUS_SUCCESS)
-    {
-        delete_wait_work_item( wait_work_item );
-        return status;
-    }
-
-    *NewWaitObject = wait_work_item;
-    return status;
-}
-
-/***********************************************************************
- *              RtlDeregisterWaitEx   (NTDLL.@)
- *
- * Cancels a wait operation and frees the resources associated with calling
- * RtlRegisterWait().
- *
- * PARAMS
- *  WaitObject [I] Handle to the wait object to free.
- *
- * RETURNS
- *  Success: STATUS_SUCCESS.
- *  Failure: Any NTSTATUS code.
- */
-NTSTATUS WINAPI RtlDeregisterWaitEx(HANDLE WaitHandle, HANDLE CompletionEvent)
-{
-    struct wait_work_item *wait_work_item = WaitHandle;
-    NTSTATUS status;
-    HANDLE LocalEvent = NULL;
-    int CallbackInProgress;
-
-    TRACE( "(%p %p)\n", WaitHandle, CompletionEvent );
-
-    if (WaitHandle == NULL)
-        return STATUS_INVALID_HANDLE;
-
-    InterlockedExchangePointer( &wait_work_item->CompletionEvent, INVALID_HANDLE_VALUE );
-    CallbackInProgress = wait_work_item->CallbackInProgress;
-    TRACE( "callback in progress %u\n", CallbackInProgress );
-    if (CompletionEvent == INVALID_HANDLE_VALUE || !CallbackInProgress)
-    {
-        status = NtCreateEvent( &LocalEvent, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE );
-        if (status != STATUS_SUCCESS)
-            return status;
-        InterlockedExchangePointer( &wait_work_item->CompletionEvent, LocalEvent );
-    }
-    else if (CompletionEvent != NULL)
-    {
-        InterlockedExchangePointer( &wait_work_item->CompletionEvent, CompletionEvent );
-    }
-
-    NtSetEvent( wait_work_item->CancelEvent, NULL );
-
-    if (InterlockedIncrement( &wait_work_item->DeleteCount ) == 2 )
-    {
-        status = STATUS_SUCCESS;
-        delete_wait_work_item( wait_work_item );
-    }
-    else if (LocalEvent)
-    {
-        TRACE( "Waiting for completion event\n" );
-        NtWaitForSingleObject( LocalEvent, FALSE, NULL );
-        status = STATUS_SUCCESS;
-    }
-    else
-    {
-        status = STATUS_PENDING;
-    }
-
-    if (LocalEvent)
-        NtClose( LocalEvent );
-
-    return status;
-}
-
-/***********************************************************************
- *              RtlDeregisterWait   (NTDLL.@)
- *
- * Cancels a wait operation and frees the resources associated with calling
- * RtlRegisterWait().
- *
- * PARAMS
- *  WaitObject [I] Handle to the wait object to free.
- *
- * RETURNS
- *  Success: STATUS_SUCCESS.
- *  Failure: Any NTSTATUS code.
- */
-NTSTATUS WINAPI RtlDeregisterWait(HANDLE WaitHandle)
-{
-    return RtlDeregisterWaitEx(WaitHandle, NULL);
-}
-
 
 /************************** Timer Queue Impl **************************/
 
@@ -3350,3 +3134,219 @@ NTSTATUS WINAPI TpQueryPoolStackInformation( TP_POOL *pool, TP_POOL_STACK_INFORM
 
     return STATUS_SUCCESS;
 }
+
+static void delete_wait_work_item(struct wait_work_item *wait_work_item)
+{
+    NtClose( wait_work_item->CancelEvent );
+    RtlFreeHeap( GetProcessHeap(), 0, wait_work_item );
+}
+
+static DWORD CALLBACK wait_thread_proc(LPVOID Arg)
+{
+    struct wait_work_item *wait_work_item = Arg;
+    NTSTATUS status;
+    BOOLEAN alertable = (wait_work_item->Flags & WT_EXECUTEINIOTHREAD) != 0;
+    HANDLE handles[2] = { wait_work_item->Object, wait_work_item->CancelEvent };
+    LARGE_INTEGER timeout;
+    HANDLE completion_event;
+
+    TRACE("\n");
+
+    while (TRUE)
+    {
+        status = NtWaitForMultipleObjects( 2, handles, TRUE, alertable,
+                                           get_nt_timeout( &timeout, wait_work_item->Milliseconds ) );
+        if (status == STATUS_WAIT_0 || status == STATUS_TIMEOUT)
+        {
+            BOOLEAN TimerOrWaitFired;
+
+            if (status == STATUS_WAIT_0)
+            {
+                TRACE( "object %p signaled, calling callback %p with context %p\n",
+                    wait_work_item->Object, wait_work_item->Callback,
+                    wait_work_item->Context );
+                TimerOrWaitFired = FALSE;
+            }
+            else
+            {
+                TRACE( "wait for object %p timed out, calling callback %p with context %p\n",
+                    wait_work_item->Object, wait_work_item->Callback,
+                    wait_work_item->Context );
+                TimerOrWaitFired = TRUE;
+            }
+            InterlockedExchange( &wait_work_item->CallbackInProgress, TRUE );
+            if (wait_work_item->CompletionEvent)
+            {
+                TRACE( "Work has been canceled.\n" );
+                break;
+            }
+            wait_work_item->Callback( wait_work_item->Context, TimerOrWaitFired );
+            InterlockedExchange( &wait_work_item->CallbackInProgress, FALSE );
+
+            if (wait_work_item->Flags & WT_EXECUTEONLYONCE)
+                break;
+        }
+        else if (status != STATUS_USER_APC)
+            break;
+    }
+
+
+    if (InterlockedIncrement( &wait_work_item->DeleteCount ) == 2 )
+    {
+        completion_event = wait_work_item->CompletionEvent;
+        delete_wait_work_item( wait_work_item );
+        if (completion_event && completion_event != INVALID_HANDLE_VALUE)
+            NtSetEvent( completion_event, NULL );
+    }
+
+    return 0;
+}
+
+/***********************************************************************
+ *              RtlRegisterWait   (NTDLL.@)
+ *
+ * Registers a wait for a handle to become signaled.
+ *
+ * PARAMS
+ *  NewWaitObject [I] Handle to the new wait object. Use RtlDeregisterWait() to free it.
+ *  Object   [I] Object to wait to become signaled.
+ *  Callback [I] Callback function to execute when the wait times out or the handle is signaled.
+ *  Context  [I] Context to pass to the callback function when it is executed.
+ *  Milliseconds [I] Number of milliseconds to wait before timing out.
+ *  Flags    [I] Flags. See notes.
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS.
+ *  Failure: Any NTSTATUS code.
+ *
+ * NOTES
+ *  Flags can be one or more of the following:
+ *|WT_EXECUTEDEFAULT - Executes the work item in a non-I/O worker thread.
+ *|WT_EXECUTEINIOTHREAD - Executes the work item in an I/O worker thread.
+ *|WT_EXECUTEINPERSISTENTTHREAD - Executes the work item in a thread that is persistent.
+ *|WT_EXECUTELONGFUNCTION - Hints that the execution can take a long time.
+ *|WT_TRANSFER_IMPERSONATION - Executes the function with the current access token.
+ */
+NTSTATUS WINAPI RtlRegisterWait(PHANDLE NewWaitObject, HANDLE Object,
+                                RTL_WAITORTIMERCALLBACKFUNC Callback,
+                                PVOID Context, ULONG Milliseconds, ULONG Flags)
+{
+    struct wait_work_item *wait_work_item;
+    NTSTATUS status;
+
+    TRACE( "(%p, %p, %p, %p, %d, 0x%x)\n", NewWaitObject, Object, Callback, Context, Milliseconds, Flags );
+
+    wait_work_item = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*wait_work_item) );
+    if (!wait_work_item)
+        return STATUS_NO_MEMORY;
+
+    wait_work_item->Object = Object;
+    wait_work_item->Callback = Callback;
+    wait_work_item->Context = Context;
+    wait_work_item->Milliseconds = Milliseconds;
+    wait_work_item->Flags = Flags;
+    wait_work_item->CallbackInProgress = FALSE;
+    wait_work_item->DeleteCount = 0;
+    wait_work_item->CompletionEvent = NULL;
+
+    status = NtCreateEvent( &wait_work_item->CancelEvent, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE );
+    if (status != STATUS_SUCCESS)
+    {
+        RtlFreeHeap( GetProcessHeap(), 0, wait_work_item );
+        return status;
+    }
+
+    Flags = Flags & (WT_EXECUTEINIOTHREAD | WT_EXECUTEINPERSISTENTTHREAD |
+                     WT_EXECUTELONGFUNCTION | WT_TRANSFER_IMPERSONATION);
+    status = RtlQueueWorkItem( wait_thread_proc, wait_work_item, Flags );
+    if (status != STATUS_SUCCESS)
+    {
+        delete_wait_work_item( wait_work_item );
+        return status;
+    }
+
+    *NewWaitObject = wait_work_item;
+    return status;
+}
+
+/***********************************************************************
+ *              RtlDeregisterWaitEx   (NTDLL.@)
+ *
+ * Cancels a wait operation and frees the resources associated with calling
+ * RtlRegisterWait().
+ *
+ * PARAMS
+ *  WaitObject [I] Handle to the wait object to free.
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS.
+ *  Failure: Any NTSTATUS code.
+ */
+NTSTATUS WINAPI RtlDeregisterWaitEx(HANDLE WaitHandle, HANDLE CompletionEvent)
+{
+    struct wait_work_item *wait_work_item = WaitHandle;
+    NTSTATUS status;
+    HANDLE LocalEvent = NULL;
+    int CallbackInProgress;
+
+    TRACE( "(%p %p)\n", WaitHandle, CompletionEvent );
+
+    if (WaitHandle == NULL)
+        return STATUS_INVALID_HANDLE;
+
+    InterlockedExchangePointer( &wait_work_item->CompletionEvent, INVALID_HANDLE_VALUE );
+    CallbackInProgress = wait_work_item->CallbackInProgress;
+    TRACE( "callback in progress %u\n", CallbackInProgress );
+    if (CompletionEvent == INVALID_HANDLE_VALUE || !CallbackInProgress)
+    {
+        status = NtCreateEvent( &LocalEvent, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE );
+        if (status != STATUS_SUCCESS)
+            return status;
+        InterlockedExchangePointer( &wait_work_item->CompletionEvent, LocalEvent );
+    }
+    else if (CompletionEvent != NULL)
+    {
+        InterlockedExchangePointer( &wait_work_item->CompletionEvent, CompletionEvent );
+    }
+
+    NtSetEvent( wait_work_item->CancelEvent, NULL );
+
+    if (InterlockedIncrement( &wait_work_item->DeleteCount ) == 2 )
+    {
+        status = STATUS_SUCCESS;
+        delete_wait_work_item( wait_work_item );
+    }
+    else if (LocalEvent)
+    {
+        TRACE( "Waiting for completion event\n" );
+        NtWaitForSingleObject( LocalEvent, FALSE, NULL );
+        status = STATUS_SUCCESS;
+    }
+    else
+    {
+        status = STATUS_PENDING;
+    }
+
+    if (LocalEvent)
+        NtClose( LocalEvent );
+
+    return status;
+}
+
+/***********************************************************************
+ *              RtlDeregisterWait   (NTDLL.@)
+ *
+ * Cancels a wait operation and frees the resources associated with calling
+ * RtlRegisterWait().
+ *
+ * PARAMS
+ *  WaitObject [I] Handle to the wait object to free.
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS.
+ *  Failure: Any NTSTATUS code.
+ */
+NTSTATUS WINAPI RtlDeregisterWait(HANDLE WaitHandle)
+{
+    return RtlDeregisterWaitEx(WaitHandle, NULL);
+}
-- 
2.29.2




More information about the wine-devel mailing list