[3/7] ntdll: Implement TpSetWait and TpWaitForWait.

Sebastian Lackner sebastian at fds-team.de
Sat Jul 4 19:23:43 CDT 2015


---
 dlls/ntdll/ntdll.spec   |    2 +
 dlls/ntdll/threadpool.c |   75 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+)

diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 78814cd..75dc647 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -993,8 +993,10 @@
 @ stdcall TpSetPoolMaxThreads(ptr long)
 @ stdcall TpSetPoolMinThreads(ptr long)
 @ stdcall TpSetTimer(ptr ptr long long)
+@ stdcall TpSetWait(ptr long ptr)
 @ stdcall TpSimpleTryPost(ptr ptr ptr)
 @ stdcall TpWaitForTimer(ptr long)
+@ stdcall TpWaitForWait(ptr long)
 @ stdcall TpWaitForWork(ptr long)
 @ stdcall -ret64 VerSetConditionMask(int64 long long)
 @ stdcall WinSqmIsOptedIn()
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index e7f07d3..1931276 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -2836,6 +2836,67 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO
 }
 
 /***********************************************************************
+ *           TpSetWait    (NTDLL.@)
+ */
+VOID WINAPI TpSetWait( TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout )
+{
+    struct threadpool_object *this = impl_from_TP_WAIT( wait );
+    ULONGLONG timestamp = TIMEOUT_INFINITE;
+    BOOL submit_wait = FALSE;
+
+    TRACE( "%p %p %p\n", wait, handle, timeout );
+
+    RtlEnterCriticalSection( &waitqueue.cs );
+
+    assert( this->u.wait.bucket );
+    this->u.wait.handle = handle;
+
+    if (handle || this->u.wait.wait_pending)
+    {
+        struct waitqueue_bucket *bucket = this->u.wait.bucket;
+        list_remove( &this->u.wait.wait_entry );
+
+        /* Convert relative timeout to absolute timestamp. */
+        if (handle && timeout)
+        {
+            timestamp = timeout->QuadPart;
+            if ((LONGLONG)timestamp < 0)
+            {
+                LARGE_INTEGER now;
+                NtQuerySystemTime( &now );
+                timestamp = now.QuadPart - timestamp;
+            }
+            else if (!timestamp)
+            {
+                submit_wait = TRUE;
+                handle = NULL;
+            }
+        }
+
+        /* Add wait object back into one of the queues. */
+        if (handle)
+        {
+            list_add_tail( &bucket->waiting, &this->u.wait.wait_entry );
+            this->u.wait.wait_pending = TRUE;
+            this->u.wait.timeout = timestamp;
+        }
+        else
+        {
+            list_add_tail( &bucket->reserved, &this->u.wait.wait_entry );
+            this->u.wait.wait_pending = FALSE;
+        }
+
+        /* Wake up the wait queue thread. */
+        NtSetEvent( bucket->update_event, NULL );
+    }
+
+    RtlLeaveCriticalSection( &waitqueue.cs );
+
+    if (submit_wait)
+        tp_object_submit( this, FALSE );
+}
+
+/***********************************************************************
  *           TpSimpleTryPost    (NTDLL.@)
  */
 NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata,
@@ -2880,6 +2941,20 @@ VOID WINAPI TpWaitForTimer( TP_TIMER *timer, BOOL cancel_pending )
 }
 
 /***********************************************************************
+ *           TpWaitForWait    (NTDLL.@)
+ */
+VOID WINAPI TpWaitForWait( TP_WAIT *wait, BOOL cancel_pending )
+{
+    struct threadpool_object *this = impl_from_TP_WAIT( wait );
+
+    TRACE( "%p %d\n", wait, cancel_pending );
+
+    if (cancel_pending)
+        tp_object_cancel( this, FALSE, NULL );
+    tp_object_wait( this, FALSE );
+}
+
+/***********************************************************************
  *           TpWaitForWork    (NTDLL.@)
  */
 VOID WINAPI TpWaitForWork( TP_WORK *work, BOOL cancel_pending )
-- 
2.4.4



More information about the wine-patches mailing list