[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