29#define ERR(fmt, ...) DPRINT1(fmt, ##__VA_ARGS__)
30#define FIXME(fmt, ...) DPRINT(fmt, ##__VA_ARGS__)
31#define WARN(fmt, ...) DPRINT(fmt, ##__VA_ARGS__)
32#define TRACE(fmt, ...) DPRINT(fmt, ##__VA_ARGS__)
34#define ARRAY_SIZE(_x) (sizeof((_x))/sizeof((_x)[0]))
37typedef struct _THREAD_NAME_INFORMATION
40} THREAD_NAME_INFORMATION, *PTHREAD_NAME_INFORMATION;
50#define PRTL_WORK_ITEM_ROUTINE WORKERCALLBACKFUNC
52#define CRITICAL_SECTION RTL_CRITICAL_SECTION
53#define GetProcessHeap() RtlGetProcessHeap()
54#define GetCurrentProcess() NtCurrentProcess()
55#define GetCurrentThread() NtCurrentThread()
56#define GetCurrentThreadId() HandleToULong(NtCurrentTeb()->ClientId.UniqueThread)
63#define WIN32_NO_STATUS
69#include "ntdll_misc.h"
84#define EXPIRE_NEVER (~(ULONGLONG)0)
85#define TIMER_QUEUE_MAGIC 0x516d6954
111 0, 0, { (
DWORD_PTR)(__FILE__
": threadpool_compl_cs") }
144#define THREADPOOL_WORKER_TIMEOUT 5000
145#define MAXIMUM_WAITQUEUE_OBJECTS (MAXIMUM_WAIT_OBJECTS - 1)
318 0, 0, { (
DWORD_PTR)(__FILE__
": timerqueue.cs") }
347 0, 0, { (
DWORD_PTR)(__FILE__
": waitqueue.cs") }
388 0, 0, { (
DWORD_PTR)(__FILE__
": ioqueue.cs") }
448 unsigned int new_capacity, max_capacity;
451 if (
count <= *capacity)
455 if (
count > max_capacity)
458 new_capacity =
max(4, *capacity);
459 while (new_capacity <
count && new_capacity <= max_capacity / 2)
461 if (new_capacity <
count)
462 new_capacity = max_capacity;
467 *elements = new_elements;
468 *capacity = new_capacity;
476 THREAD_NAME_INFORMATION
info;
528 memset( &environment, 0,
sizeof(environment) );
560 ERR(
"NtRemoveIoCompletion failed: 0x%lx\n",
res);
564 DWORD transferred = 0;
668 if (
t->destroy &&
t->runcount == 0)
677 t->callback(
t->param,
TRUE);
711 if (set_event && &
t->entry ==
list_head(&
q->timers))
737 next =
t->expire +
t->period;
844 if (
t->runcount == 0)
946 FIXME(
"asynchronous return on completion event unimplemented\n");
965 if (!default_timer_queue)
977 return default_timer_queue;
1118 else if (CompletionEvent)
1119 event = CompletionEvent;
1123 if (
t->runcount == 0 &&
event)
1150 ULONGLONG timeout_lower, timeout_upper, new_timeout;
1155 TRACE(
"starting timer queue thread\n" );
1169 if (
timer->u.timer.timeout >
now.QuadPart)
1178 if (
timer->u.timer.period && !
timer->shutdown)
1182 timer->u.timer.timeout =
now.QuadPart + 1;
1188 if (
timer->u.timer.timeout < other_timer->
u.
timer.timeout)
1203 if (other_timer->
u.
timer.timeout >= timeout_upper)
1206 timeout_lower = other_timer->
u.
timer.timeout;
1207 new_timeout = timeout_lower + (
ULONGLONG)other_timer->
u.
timer.window_length * 10000;
1208 if (new_timeout < timeout_upper)
1209 timeout_upper = new_timeout;
1215 timeout.QuadPart = timeout_lower;
1233 TRACE(
"terminating timer queue thread\n" );
1251 pool->stack_info.StackReserve,
pool->stack_info.StackCommit,
1256 pool->num_workers++;
1276 timer->u.timer.timeout = 0;
1277 timer->u.timer.period = 0;
1278 timer->u.timer.window_length = 0;
1297 timer->u.timer.timer_initialized =
TRUE;
1315 if (
timer->u.timer.timer_initialized)
1318 if (
timer->u.timer.timer_pending)
1353 TRACE(
"starting wait queue thread\n" );
1368 if (
wait->u.wait.timeout <=
now.QuadPart)
1379 wait->num_pending_callbacks++;
1404 assert( num_handles == 0 );
1424 if (
wait->u.wait.bucket)
1435 wait->u.wait.signaled++;
1436 wait->num_pending_callbacks++;
1444 WARN(
"wait object %p triggered while object was destroyed\n",
wait);
1473 wait->
u.
wait.bucket = other_bucket;
1481 wait->
u.
wait.bucket = other_bucket;
1504 TRACE(
"terminating wait queue thread\n" );
1526 wait->
u.
wait.signaled = 0;
1529 wait->
u.
wait.timeout = 0;
1540 wait->
u.
wait.bucket = bucket;
1577 wait->
u.
wait.bucket = bucket;
1601 if (wait->
u.
wait.bucket)
1632 TRACE(
"starting I/O completion thread\n" );
1641 ERR(
"NtRemoveIoCompletion failed, status %#lx.\n",
status);
1649 if (
io && (
io->shutdown ||
io->u.io.shutting_down))
1652 if (!
io->u.io.pending_count)
1654 if (
io->u.io.skipped_count)
1655 --
io->u.io.skipped_count;
1657 if (
io->u.io.skipped_count)
1669 TRACE(
"Releasing io %p.\n",
io );
1677 TRACE(
"pending_count %u.\n",
io->u.io.pending_count );
1679 if (
io->u.io.pending_count)
1681 --
io->u.io.pending_count;
1683 io->u.io.completion_count + 1,
sizeof(*
io->u.io.completions)))
1685 ERR(
"Failed to allocate memory.\n" );
1718 TRACE(
"terminating I/O completion thread\n" );
1808 pool->cs.DebugInfo->Spare[0] = (
DWORD_PTR)(__FILE__
": threadpool.cs");
1815 pool->max_workers = 500;
1816 pool->min_workers = 0;
1817 pool->num_workers = 0;
1818 pool->num_busy_workers = 0;
1822 TRACE(
"allocated threadpool %p\n",
pool );
1855 TRACE(
"destroying threadpool %p\n",
pool );
1862 pool->cs.DebugInfo->Spare[0] = 0;
1886 if (environment->
Version == 3)
1925 if (!
pool->num_workers)
1971 group->refcount = 1;
1979 group->cs.DebugInfo->Spare[0] = (
DWORD_PTR)(__FILE__
": threadpool_group.cs");
2016 group->cs.DebugInfo->Spare[0] = 0;
2034 object->refcount = 1;
2035 object->shutdown =
FALSE;
2037 object->pool =
pool;
2038 object->group =
NULL;
2039 object->userdata = userdata;
2040 object->group_cancel_callback =
NULL;
2041 object->finalization_callback =
NULL;
2042 object->may_run_long = 0;
2043 object->race_dll =
NULL;
2047 object->is_group_member =
FALSE;
2052 object->completed_event =
NULL;
2053 object->num_pending_callbacks = 0;
2054 object->num_running_callbacks = 0;
2055 object->num_associated_callbacks = 0;
2060 FIXME(
"unsupported environment version %lu\n", environment->
Version );
2065 object->may_run_long = environment->
u.
s.LongFunction != 0;
2066 object->race_dll = environment->
RaceDll;
2068 if (environment->
Version == 3)
2077 FIXME(
"activation context not supported yet\n" );
2079 if (environment->
u.
s.Persistent)
2080 FIXME(
"persistent threads not supported yet\n" );
2086 TRACE(
"allocated object %p of type %u\n",
object,
object->type );
2092 if (is_simple_callback)
2102 object->is_group_member =
TRUE;
2106 if (is_simple_callback)
2112 ++
object->pool->num_busy_workers;
2133 if (
pool->num_busy_workers >=
pool->num_workers &&
2134 pool->num_workers <
pool->max_workers)
2139 if (!
object->num_pending_callbacks++)
2144 object->u.wait.signaled++;
2164 LONG pending_callbacks = 0;
2167 if (
object->num_pending_callbacks)
2169 pending_callbacks =
object->num_pending_callbacks;
2170 object->num_pending_callbacks = 0;
2174 object->u.wait.signaled = 0;
2178 object->u.io.skipped_count +=
object->u.io.pending_count;
2179 object->u.io.pending_count = 0;
2183 while (pending_callbacks--)
2189 if (
object->num_pending_callbacks)
2195 return !
object->num_running_callbacks;
2197 return !
object->num_associated_callbacks;
2229 if (!
io->shutdown && !--
ioqueue.objcount)
2260 TRACE(
"destroying object %p of type %u\n",
object,
object->type );
2273 if (
object->is_group_member)
2276 object->is_group_member =
FALSE;
2324 object->num_pending_callbacks--;
2330 if (wait_result ==
WAIT_OBJECT_0)
object->u.wait.signaled--;
2335 completion =
object->u.io.completions[--
object->u.io.completion_count];
2339 object->num_associated_callbacks++;
2340 object->num_running_callbacks++;
2349 instance.may_run_long =
object->may_run_long;
2353 instance.cleanup.semaphore_count = 0;
2361 TRACE(
"executing simple callback %p(%p, %p)\n",
2362 object->u.simple.callback, callback_instance,
object->userdata );
2363 object->u.simple.callback( callback_instance,
object->userdata );
2364 TRACE(
"callback %p returned\n",
object->u.simple.callback );
2370 TRACE(
"executing work callback %p(%p, %p, %p)\n",
2371 object->u.work.callback, callback_instance,
object->userdata,
object );
2372 object->u.work.callback( callback_instance,
object->userdata, (
TP_WORK *)
object );
2373 TRACE(
"callback %p returned\n",
object->u.work.callback );
2379 TRACE(
"executing timer callback %p(%p, %p, %p)\n",
2380 object->u.timer.callback, callback_instance,
object->userdata,
object );
2381 object->u.timer.callback( callback_instance,
object->userdata, (
TP_TIMER *)
object );
2382 TRACE(
"callback %p returned\n",
object->u.timer.callback );
2388 TRACE(
"executing wait callback %p(%p, %p, %p, %lu)\n",
2389 object->u.wait.callback, callback_instance,
object->userdata,
object, wait_result );
2390 object->u.wait.callback( callback_instance,
object->userdata, (
TP_WAIT *)
object, wait_result );
2391 TRACE(
"callback %p returned\n",
object->u.wait.callback );
2397 TRACE(
"executing I/O callback %p(%p, %p, %#Ix, %p, %p)\n",
2398 object->u.io.callback, callback_instance,
object->userdata,
2400 object->u.io.callback( callback_instance,
object->userdata,
2402 TRACE(
"callback %p returned\n",
object->u.io.callback );
2412 if (
object->finalization_callback)
2414 TRACE(
"executing finalization callback %p(%p, %p)\n",
2415 object->finalization_callback, callback_instance,
object->userdata );
2416 object->finalization_callback( callback_instance,
object->userdata );
2417 TRACE(
"callback %p returned\n",
object->finalization_callback );
2421 if (
instance.cleanup.critical_section)
2453 object->shutdown =
TRUE;
2456 object->num_running_callbacks--;
2462 object->num_associated_callbacks--;
2481 TRACE(
"starting worker thread for pool %p\n",
pool );
2495 if (
object->num_pending_callbacks > 1)
2501 pool->num_busy_workers--;
2518 (!
pool->min_workers && !
pool->objcount)))
2523 pool->num_workers--;
2526 TRACE(
"terminating worker thread for pool %p\n",
pool );
2625 object->u.timer.callback =
callback;
2660 object->u.wait.callback =
callback;
2661 object->u.wait.flags =
flags;
2711 object->u.work.callback =
callback;
2729 TRACE(
"pending_count %u.\n", this->
u.io.pending_count);
2731 this->
u.io.pending_count--;
2749 if (!this->
cleanup.critical_section)
2750 this->
cleanup.critical_section = crit;
2767 ERR(
"called from wrong thread, ignoring\n");
2771 if (this->may_run_long)
2774 pool =
object->pool;
2778 if (
pool->num_busy_workers >=
pool->num_workers)
2780 if (
pool->num_workers <
pool->max_workers)
2791 this->may_run_long =
TRUE;
2847 this->
cleanup.library = module;
2863 ERR(
"called from wrong thread, ignoring\n");
2867 if (!this->associated)
2870 pool =
object->pool;
2873 object->num_associated_callbacks--;
2878 this->associated =
FALSE;
2890 return this->
u.timer.timer_set;
2925 struct list members;
2927 TRACE(
"%p %u %p\n",
group, cancel_pending, userdata );
2943 object->is_group_member =
FALSE;
2947 object->is_group_member =
FALSE;
2974 if (cancel_pending &&
object->group_cancel_callback)
2976 TRACE(
"executing group cancel callback %p(%p, %p)\n",
2977 object->group_cancel_callback,
object->userdata, userdata );
2978 object->group_cancel_callback(
object->userdata, userdata );
2979 TRACE(
"callback %p returned\n",
object->group_cancel_callback );
2986 object->shutdown =
TRUE;
3002 this->
u.io.shutting_down =
TRUE;
3003 can_destroy = !this->
u.io.pending_count && !this->
u.io.skipped_count;
3127 assert( this->
u.timer.timer_initialized );
3128 this->
u.timer.timer_set = timeout !=
NULL;
3151 submit_timer =
TRUE;
3156 if (this->
u.timer.timer_pending)
3159 this->
u.timer.timer_pending =
FALSE;
3165 this->
u.timer.timeout = timestamp;
3166 this->
u.timer.period =
period;
3173 if (this->
u.timer.timeout < other_timer->
u.
timer.timeout)
3182 this->
u.timer.timer_pending =
TRUE;
3203 assert( this->
u.wait.bucket );
3206 if (handle || this->
u.wait.wait_pending)
3227 this->
u.wait.wait_pending =
TRUE;
3228 this->
u.wait.timeout = timestamp;
3233 this->
u.wait.wait_pending =
FALSE;
3267 object->u.simple.callback =
callback;
3284 this->
u.io.pending_count++;
3296 TRACE(
"%p %d\n",
io, cancel_pending );
3324 TRACE(
"%p %d\n",
wait, cancel_pending );
3338 TRACE(
"%p %u\n",
work, cancel_pending );
3423 TRACE(
"out %p, handle %p, callback %p, context %p, milliseconds %lu, flags %lx\n",
3426 memset( &environment, 0,
sizeof(environment) );
3436 object->u.wait.rtl_callback =
callback;
3475 object->completed_event =
event;
3479 if (
object->num_pending_callbacks +
object->num_running_callbacks
void CALLBACK completion(DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags)
void destroy(_Tp *__pointer)
#define InterlockedIncrement
#define InterlockedDecrement
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
static void list_remove(struct list_entry *entry)
static int list_empty(struct list_entry *head)
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
static void list_init(struct list_entry *head)
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
#define STATUS_INVALID_HANDLE
static HINSTANCE instance
#define INVALID_HANDLE_VALUE
#define GetCurrentProcess()
static void cleanup(void)
static void list_move_tail(struct list_head *list, struct list_head *head)
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
@ FileCompletionInformation
GLuint GLuint GLsizei count
GLdouble GLdouble GLdouble GLdouble q
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
DWORD(CALLBACK * PRTL_WORK_ITEM_ROUTINE)(LPVOID)
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
VOID(CALLBACK * PRTL_OVERLAPPED_COMPLETION_ROUTINE)(DWORD, DWORD, LPVOID)
void(NTAPI * RTL_WAITORTIMERCALLBACKFUNC)(PVOID, BOOLEAN)
NTSYSAPI NTSTATUS WINAPI RtlInitializeCriticalSectionEx(RTL_CRITICAL_SECTION *, ULONG, ULONG)
void(CALLBACK * PNTAPCFUNC)(ULONG_PTR, ULONG_PTR, ULONG_PTR)
void(CALLBACK * PRTL_THREAD_START_ROUTINE)(LPVOID)
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define InterlockedCompareExchangePointer
NTSTATUS NTAPI NtSetIoCompletion(IN HANDLE IoCompletionPortHandle, IN PVOID CompletionKey, IN PVOID CompletionContext, IN NTSTATUS CompletionStatus, IN ULONG CompletionInformation)
NTSTATUS NTAPI NtRemoveIoCompletion(IN HANDLE IoCompletionHandle, OUT PVOID *KeyContext, OUT PVOID *ApcContext, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER Timeout OPTIONAL)
NTSTATUS NTAPI NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG NumberOfConcurrentThreads)
NTSTATUS NTAPI LdrUnloadDll(_In_ PVOID BaseAddress)
NTSTATUS NTAPI LdrAddRefDll(_In_ ULONG Flags, _In_ PVOID BaseAddress)
static const CLSID * objects[]
static IPrintDialogCallback callback
#define IO_COMPLETION_ALL_ACCESS
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK io
static PIO_STATUS_BLOCK iosb
static TP_CALLBACK_ENVIRON *static TP_CALLBACK_ENVIRON *static PTP_WORK_CALLBACK
static PTP_TIMER_CALLBACK
static TP_CALLBACK_ENVIRON *static PTP_WAIT_CALLBACK
static void TP_CALLBACK_ENVIRON *static PVOID
NTSTATUS NTAPI NtReleaseMutant(IN HANDLE MutantHandle, IN PLONG PreviousCount OPTIONAL)
NTSYSAPI VOID NTAPI RtlInitializeConditionVariable(_Out_ PRTL_CONDITION_VARIABLE ConditionVariable)
NTSYSAPI NTSTATUS NTAPI RtlDeleteCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlQueueWorkItem(_In_ WORKERCALLBACKFUNC Function, _In_opt_ PVOID Context, _In_ ULONG Flags)
NTSYSAPI VOID NTAPI RtlWakeAllConditionVariable(_Inout_ PRTL_CONDITION_VARIABLE ConditionVariable)
NTSYSAPI NTSTATUS NTAPI RtlRegisterWait(_In_ PHANDLE phNewWaitObject, _In_ HANDLE hObject, _In_ WAITORTIMERCALLBACKFUNC Callback, _In_ PVOID pvContext, _In_ ULONG ulMilliseconds, _In_ ULONG ulFlags)
NTSYSAPI NTSTATUS NTAPI RtlSleepConditionVariableCS(_Inout_ PRTL_CONDITION_VARIABLE ConditionVariable, _Inout_ PRTL_CRITICAL_SECTION CriticalSection, _In_opt_ PLARGE_INTEGER TimeOut)
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI VOID NTAPI RtlExitUserThread(_In_ NTSTATUS Status)
NTSYSAPI VOID NTAPI RtlWakeConditionVariable(_Inout_ PRTL_CONDITION_VARIABLE ConditionVariable)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlCreateUserThread(_In_ PVOID ThreadContext, _Out_ HANDLE *OutThreadHandle, _Reserved_ PVOID Reserved1, _Reserved_ PVOID Reserved2, _Reserved_ PVOID Reserved3, _Reserved_ PVOID Reserved4, _Reserved_ PVOID Reserved5, _Reserved_ PVOID Reserved6, _Reserved_ PVOID Reserved7, _Reserved_ PVOID Reserved8)
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlDeregisterWaitEx(_In_ HANDLE hWaitHandle, _In_opt_ HANDLE hCompletionEvent)
NTSYSAPI NTSTATUS NTAPI RtlDeregisterWait(_In_ HANDLE hWaitHandle)
ULONG(NTAPI * PTHREAD_START_ROUTINE)(PVOID Parameter)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
VOID NTAPI RtlpInitializeThreadPooling(VOID)
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
NTSTATUS NTAPI NtQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceCounter, OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
#define STATUS_TOO_MANY_THREADS
#define STATUS_INVALID_PARAMETER_1
NTSTATUS NTAPI NtWaitForMultipleObjects(IN ULONG ObjectCount, IN PHANDLE HandleArray, IN WAIT_TYPE WaitType, IN BOOLEAN Alertable, IN PLARGE_INTEGER TimeOut OPTIONAL)
static unsigned __int64 next
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
#define LIST_FOR_EACH(cursor, list)
__WINE_SERVER_LIST_INLINE void list_add_before(struct list *elem, struct list *to_add)
VOID WINAPI TpReleaseCleanupGroupMembers(TP_CLEANUP_GROUP *group, BOOL cancel_pending, PVOID userdata)
static RTL_CRITICAL_SECTION_DEBUG waitqueue_debug
static void tp_object_wait(struct threadpool_object *object, BOOL group_wait)
VOID WINAPI TpReleaseTimer(TP_TIMER *timer)
RTL_CRITICAL_SECTION threadpool_compl_cs
VOID WINAPI TpReleasePool(TP_POOL *pool)
static struct @5099 ioqueue
static BOOL tp_object_release(struct threadpool_object *object)
void WINAPI TpStartAsyncIoOperation(TP_IO *io)
VOID WINAPI TpDisassociateCallback(TP_CALLBACK_INSTANCE *instance)
NTSTATUS WINAPI RtlCreateTimer(HANDLE TimerQueue, HANDLE *NewTimer, RTL_WAITORTIMERCALLBACKFUNC Callback, PVOID Parameter, DWORD DueTime, DWORD Period, ULONG Flags)
static PLARGE_INTEGER get_nt_timeout(PLARGE_INTEGER pTime, ULONG timeout)
NTSTATUS WINAPI RtlSetIoCompletionCallback(HANDLE FileHandle, PRTL_OVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags)
NTSTATUS WINAPI TpAllocTimer(TP_TIMER **out, PTP_TIMER_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
static void set_thread_name(const WCHAR *name)
static void CALLBACK ioqueue_thread_proc(void *param)
static struct threadpool_group * impl_from_TP_CLEANUP_GROUP(TP_CLEANUP_GROUP *group)
VOID WINAPI TpCallbackUnloadDllOnCompletion(TP_CALLBACK_INSTANCE *instance, HMODULE module)
static void queue_move_timer(struct queue_timer *t, ULONGLONG time, BOOL set_event)
static struct @5097 timerqueue
VOID WINAPI TpSetTimer(TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LONG window_length)
VOID WINAPI TpReleaseCleanupGroup(TP_CLEANUP_GROUP *group)
NTSTATUS WINAPI TpCallbackMayRunLong(TP_CALLBACK_INSTANCE *instance)
static void CALLBACK process_rtl_work_item(TP_CALLBACK_INSTANCE *instance, void *userdata)
static void tp_group_shutdown(struct threadpool_group *group)
VOID WINAPI TpWaitForWork(TP_WORK *work, BOOL cancel_pending)
NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE NewTimerQueue)
#define MAXIMUM_WAITQUEUE_OBJECTS
static void queue_add_timer(struct queue_timer *t, ULONGLONG time, BOOL set_event)
BOOL WINAPI TpSetPoolMinThreads(TP_POOL *pool, DWORD minimum)
static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
static struct @5098 waitqueue
static struct list * threadpool_get_next_item(const struct threadpool *pool)
static void tp_object_initialize(struct threadpool_object *object, struct threadpool *pool, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
static void tp_waitqueue_unlock(struct threadpool_object *wait)
static ULONG queue_get_timeout(struct timer_queue *q)
static NTSTATUS tp_waitqueue_lock(struct threadpool_object *wait)
static BOOL tp_group_release(struct threadpool_group *group)
NTSTATUS WINAPI TpSimpleTryPost(PTP_SIMPLE_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
static struct threadpool * default_threadpool
static ULONGLONG queue_current_time(void)
void WINAPI TpReleaseIoCompletion(TP_IO *io)
static DWORD WINAPI timer_callback_wrapper(LPVOID p)
static NTSTATUS tp_threadpool_alloc(struct threadpool **out)
VOID WINAPI TpPostWork(TP_WORK *work)
NTSTATUS WINAPI TpAllocWork(TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
NTSTATUS WINAPI RtlDeleteTimer(HANDLE TimerQueue, HANDLE Timer, HANDLE CompletionEvent)
static void tp_object_submit(struct threadpool_object *object, BOOL signaled)
static NTSTATUS tp_new_worker_thread(struct threadpool *pool)
NTSTATUS WINAPI TpAllocCleanupGroup(TP_CLEANUP_GROUP **out)
static BOOL tp_threadpool_release(struct threadpool *pool)
NTSTATUS WINAPI TpAllocWait(TP_WAIT **out, PTP_WAIT_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
struct list pending_timers
static RTL_CRITICAL_SECTION_DEBUG timerqueue_debug
static struct threadpool_object * impl_from_TP_WORK(TP_WORK *work)
NTSTATUS WINAPI TpQueryPoolStackInformation(TP_POOL *pool, TP_POOL_STACK_INFORMATION *stack_info)
#define TIMER_QUEUE_MAGIC
VOID WINAPI TpWaitForWait(TP_WAIT *wait, BOOL cancel_pending)
static struct threadpool_object * impl_from_TP_WAIT(TP_WAIT *wait)
VOID WINAPI TpReleaseWork(TP_WORK *work)
VOID WINAPI TpWaitForTimer(TP_TIMER *timer, BOOL cancel_pending)
void WINAPI TpCancelAsyncIoOperation(TP_IO *io)
static BOOL object_is_finished(struct threadpool_object *object, BOOL group)
#define THREADPOOL_WORKER_TIMEOUT
VOID WINAPI TpCallbackSetEventOnCompletion(TP_CALLBACK_INSTANCE *instance, HANDLE event)
VOID WINAPI TpReleaseWait(TP_WAIT *wait)
static void tp_ioqueue_unlock(struct threadpool_object *io)
static void CALLBACK threadpool_worker_proc(void *param)
static void tp_threadpool_unlock(struct threadpool *pool)
static void WINAPI timer_queue_thread_proc(LPVOID p)
static NTSTATUS tp_group_alloc(struct threadpool_group **out)
VOID WINAPI TpSetWait(TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout)
VOID WINAPI TpCallbackReleaseMutexOnCompletion(TP_CALLBACK_INSTANCE *instance, HANDLE mutex)
static struct timer_queue * get_timer_queue(HANDLE TimerQueue)
static void queue_destroy_timer(struct queue_timer *t)
static struct threadpool_instance * impl_from_TP_CALLBACK_INSTANCE(TP_CALLBACK_INSTANCE *instance)
static DWORD CALLBACK iocp_poller(LPVOID Arg)
static struct threadpool_object * impl_from_TP_TIMER(TP_TIMER *timer)
static NTSTATUS tp_alloc_wait(TP_WAIT **out, PTP_WAIT_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment, DWORD flags)
BOOL WINAPI TpIsTimerSet(TP_TIMER *timer)
RTL_CONDITION_VARIABLE update_event
static struct threadpool_object * impl_from_TP_IO(TP_IO *io)
NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
static NTSTATUS tp_ioqueue_lock(struct threadpool_object *io, HANDLE file)
static RTL_CRITICAL_SECTION_DEBUG critsect_compl_debug
static void CALLBACK timerqueue_thread_proc(void *param)
static void tp_object_execute(struct threadpool_object *object, BOOL wait_thread)
static void tp_timerqueue_unlock(struct threadpool_object *timer)
VOID WINAPI TpCallbackReleaseSemaphoreOnCompletion(TP_CALLBACK_INSTANCE *instance, HANDLE semaphore, DWORD count)
VOID WINAPI TpSetPoolMaxThreads(TP_POOL *pool, DWORD maximum)
NTSTATUS WINAPI TpAllocIoCompletion(TP_IO **out, HANDLE file, PTP_IO_CALLBACK callback, void *userdata, TP_CALLBACK_ENVIRON *environment)
static void CALLBACK waitqueue_thread_proc(void *param)
static RTL_CRITICAL_SECTION_DEBUG ioqueue_debug
static void tp_object_cancel(struct threadpool_object *object)
NTSTATUS WINAPI RtlUpdateTimer(HANDLE TimerQueue, HANDLE Timer, DWORD DueTime, DWORD Period)
static void timer_cleanup_callback(struct queue_timer *t)
NTSTATUS WINAPI TpSetPoolStackInformation(TP_POOL *pool, TP_POOL_STACK_INFORMATION *stack_info)
void WINAPI TpWaitForIoCompletion(TP_IO *io, BOOL cancel_pending)
NTSTATUS WINAPI TpAllocPool(TP_POOL **out, PVOID reserved)
VOID WINAPI TpCallbackLeaveCriticalSectionOnCompletion(TP_CALLBACK_INSTANCE *instance, CRITICAL_SECTION *crit)
static void queue_remove_timer(struct queue_timer *t)
static struct threadpool * impl_from_TP_POOL(TP_POOL *pool)
static struct @5096 old_threadpool
static void tp_threadpool_shutdown(struct threadpool *pool)
static void queue_timer_expire(struct timer_queue *q)
static void tp_object_prepare_shutdown(struct threadpool_object *object)
static NTSTATUS tp_timerqueue_lock(struct threadpool_object *timer)
static NTSTATUS tp_threadpool_lock(struct threadpool **out, TP_CALLBACK_ENVIRON *environment)
static void CALLBACK rtl_wait_callback(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WAIT *wait, TP_WAIT_RESULT result)
static void tp_object_prio_queue(struct threadpool_object *object)
NTSTATUS NTAPI NtReleaseSemaphore(IN HANDLE SemaphoreHandle, IN LONG ReleaseCount, OUT PLONG PreviousCount OPTIONAL)
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED * overlapped
INT WSAAPI shutdown(IN SOCKET s, IN INT how)
LIST_ENTRY ProcessLocksList
PTP_CLEANUP_GROUP CleanupGroup
union _TP_CALLBACK_ENVIRON_V3::@4304 u
PTP_SIMPLE_CALLBACK FinalizationCallback
TP_CALLBACK_PRIORITY CallbackPriority
PTP_CLEANUP_GROUP_CANCEL_CALLBACK CleanupGroupCancelCallback
struct _ACTIVATION_CONTEXT * ActivationContext
struct _TP_CALLBACK_ENVIRON_V3::@4304::@4305 s
RTL_WAITORTIMERCALLBACKFUNC callback
PRTL_WORK_ITEM_ROUTINE function
CRITICAL_SECTION * critical_section
struct threadpool_instance::@5106 cleanup
struct threadpool_object * object
PTP_WAIT_CALLBACK callback
PTP_SIMPLE_CALLBACK callback
PTP_CLEANUP_GROUP_CANCEL_CALLBACK group_cancel_callback
RTL_CONDITION_VARIABLE finished_event
TP_CALLBACK_PRIORITY priority
struct io_completion * completions
struct threadpool_object::@5100::@5102 work
unsigned int skipped_count
enum threadpool_objtype type
union threadpool_object::@5100 u
unsigned int completion_count
unsigned int completion_max
unsigned int pending_count
LONG num_associated_callbacks
RTL_WAITORTIMERCALLBACKFUNC rtl_callback
struct threadpool_object::@5100::@5101 simple
LONG num_running_callbacks
LONG num_pending_callbacks
PTP_WORK_CALLBACK callback
struct threadpool_object::@5100::@5105 io
RTL_CONDITION_VARIABLE group_finished_event
struct threadpool_object::@5100::@5103 timer
struct threadpool_object::@5100::@5104 wait
PTP_SIMPLE_CALLBACK finalization_callback
struct waitqueue_bucket * bucket
PTP_TIMER_CALLBACK callback
struct threadpool_group * group
TP_POOL_STACK_INFORMATION stack_info
RTL_CONDITION_VARIABLE update_event
#define STATUS_INVALID_PARAMETER
#define STATUS_UNSUCCESSFUL
static EFI_HANDLE * handles
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
_In_ WDFTIMER _In_ LONGLONG DueTime
HANDLE WINAPI GetCurrentThread(void)
DWORD WINAPI GetCurrentThreadId(void)
_In_ PCCERT_CONTEXT _In_opt_ LPFILETIME pTime
#define WT_TRANSFER_IMPERSONATION
@ TP_CALLBACK_PRIORITY_NORMAL
@ TP_CALLBACK_PRIORITY_HIGH
@ TP_CALLBACK_PRIORITY_LOW
struct _TP_CLEANUP_GROUP TP_CLEANUP_GROUP
VOID(NTAPI * PTP_WAIT_CALLBACK)(PTP_CALLBACK_INSTANCE, PVOID, PTP_WAIT, TP_WAIT_RESULT)
#define WT_EXECUTEINPERSISTENTTHREAD
struct _TP_CALLBACK_INSTANCE * PTP_CALLBACK_INSTANCE
#define WT_EXECUTEONLYONCE
#define WT_EXECUTEINIOTHREAD
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
#define WT_EXECUTELONGFUNCTION
#define WT_EXECUTEINWAITTHREAD
VOID(NTAPI * PTP_CLEANUP_GROUP_CANCEL_CALLBACK)(_Inout_opt_ PVOID ObjectContext, _Inout_opt_ PVOID CleanupContext)
VOID(NTAPI * PTP_WORK_CALLBACK)(_Inout_ PTP_CALLBACK_INSTANCE Instance, _Inout_opt_ PVOID Context, _Inout_ PTP_WORK Work)
#define WT_EXECUTEINTIMERTHREAD
enum _TP_CALLBACK_PRIORITY TP_CALLBACK_PRIORITY
struct _TP_TIMER TP_TIMER
VOID(NTAPI * PTP_SIMPLE_CALLBACK)(_Inout_ PTP_CALLBACK_INSTANCE Instance, _Inout_opt_ PVOID Context)
VOID(NTAPI * PTP_TIMER_CALLBACK)(PTP_CALLBACK_INSTANCE, PVOID, PTP_TIMER)
struct _TP_CALLBACK_INSTANCE TP_CALLBACK_INSTANCE
#define WT_EXECUTEDEFAULT
_Must_inspect_result_ _In_ ULONG Flags
_In_ LARGE_INTEGER _In_ ULONG Period
#define RTL_CONDITION_VARIABLE_INIT
_Inout_opt_ PVOID Parameter