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]))
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;
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);
737 next =
t->expire +
t->period;
846 if (
t->runcount == 0)
948 FIXME(
"asynchronous return on completion event unimplemented\n");
967 if (!default_timer_queue)
979 return default_timer_queue;
1120 else if (CompletionEvent)
1121 event = CompletionEvent;
1125 if (
t->runcount == 0 &&
event)
1152 ULONGLONG timeout_lower, timeout_upper, new_timeout;
1157 TRACE(
"starting timer queue thread\n" );
1171 if (
timer->u.timer.timeout >
now.QuadPart)
1180 if (
timer->u.timer.period && !
timer->shutdown)
1184 timer->u.timer.timeout =
now.QuadPart + 1;
1190 if (
timer->u.timer.timeout < other_timer->
u.
timer.timeout)
1205 if (other_timer->
u.
timer.timeout >= timeout_upper)
1208 timeout_lower = other_timer->
u.
timer.timeout;
1209 new_timeout = timeout_lower + (
ULONGLONG)other_timer->
u.
timer.window_length * 10000;
1210 if (new_timeout < timeout_upper)
1211 timeout_upper = new_timeout;
1217 timeout.QuadPart = timeout_lower;
1235 TRACE(
"terminating timer queue thread\n" );
1253 pool->stack_info.StackReserve,
pool->stack_info.StackCommit,
1258 pool->num_workers++;
1278 timer->u.timer.timeout = 0;
1279 timer->u.timer.period = 0;
1280 timer->u.timer.window_length = 0;
1299 timer->u.timer.timer_initialized =
TRUE;
1317 if (
timer->u.timer.timer_initialized)
1320 if (
timer->u.timer.timer_pending)
1355 TRACE(
"starting wait queue thread\n" );
1370 if (
wait->u.wait.timeout <=
now.QuadPart)
1381 wait->num_pending_callbacks++;
1406 assert( num_handles == 0 );
1426 if (
wait->u.wait.bucket)
1437 wait->u.wait.signaled++;
1438 wait->num_pending_callbacks++;
1446 WARN(
"wait object %p triggered while object was destroyed\n",
wait);
1475 wait->
u.
wait.bucket = other_bucket;
1483 wait->
u.
wait.bucket = other_bucket;
1506 TRACE(
"terminating wait queue thread\n" );
1528 wait->
u.
wait.signaled = 0;
1531 wait->
u.
wait.timeout = 0;
1542 wait->
u.
wait.bucket = bucket;
1579 wait->
u.
wait.bucket = bucket;
1603 if (wait->
u.
wait.bucket)
1634 TRACE(
"starting I/O completion thread\n" );
1643 ERR(
"NtRemoveIoCompletion failed, status %#lx.\n",
status);
1651 if (
io && (
io->shutdown ||
io->u.io.shutting_down))
1654 if (!
io->u.io.pending_count)
1656 if (
io->u.io.skipped_count)
1657 --
io->u.io.skipped_count;
1659 if (
io->u.io.skipped_count)
1671 TRACE(
"Releasing io %p.\n",
io );
1679 TRACE(
"pending_count %u.\n",
io->u.io.pending_count );
1681 if (
io->u.io.pending_count)
1683 --
io->u.io.pending_count;
1685 io->u.io.completion_count + 1,
sizeof(*
io->u.io.completions)))
1687 ERR(
"Failed to allocate memory.\n" );
1720 TRACE(
"terminating I/O completion thread\n" );
1810 pool->cs.DebugInfo->Spare[0] = (
DWORD_PTR)(__FILE__
": threadpool.cs");
1817 pool->max_workers = 500;
1818 pool->min_workers = 0;
1819 pool->num_workers = 0;
1820 pool->num_busy_workers = 0;
1824 TRACE(
"allocated threadpool %p\n",
pool );
1857 TRACE(
"destroying threadpool %p\n",
pool );
1864 pool->cs.DebugInfo->Spare[0] = 0;
1888 if (environment->
Version == 3)
1927 if (!
pool->num_workers)
1973 group->refcount = 1;
1981 group->cs.DebugInfo->Spare[0] = (
DWORD_PTR)(__FILE__
": threadpool_group.cs");
2018 group->cs.DebugInfo->Spare[0] = 0;
2036 object->refcount = 1;
2037 object->shutdown =
FALSE;
2039 object->pool =
pool;
2040 object->group =
NULL;
2041 object->userdata = userdata;
2042 object->group_cancel_callback =
NULL;
2043 object->finalization_callback =
NULL;
2044 object->may_run_long = 0;
2045 object->race_dll =
NULL;
2049 object->is_group_member =
FALSE;
2054 object->completed_event =
NULL;
2055 object->num_pending_callbacks = 0;
2056 object->num_running_callbacks = 0;
2057 object->num_associated_callbacks = 0;
2062 FIXME(
"unsupported environment version %lu\n", environment->
Version );
2067 object->may_run_long = environment->
u.
s.LongFunction != 0;
2068 object->race_dll = environment->
RaceDll;
2070 if (environment->
Version == 3)
2079 FIXME(
"activation context not supported yet\n" );
2081 if (environment->
u.
s.Persistent)
2082 FIXME(
"persistent threads not supported yet\n" );
2088 TRACE(
"allocated object %p of type %u\n",
object,
object->type );
2094 if (is_simple_callback)
2104 object->is_group_member =
TRUE;
2108 if (is_simple_callback)
2114 ++
object->pool->num_busy_workers;
2135 if (
pool->num_busy_workers >=
pool->num_workers &&
2136 pool->num_workers <
pool->max_workers)
2141 if (!
object->num_pending_callbacks++)
2146 object->u.wait.signaled++;
2166 LONG pending_callbacks = 0;
2169 if (
object->num_pending_callbacks)
2171 pending_callbacks =
object->num_pending_callbacks;
2172 object->num_pending_callbacks = 0;
2176 object->u.wait.signaled = 0;
2180 object->u.io.skipped_count +=
object->u.io.pending_count;
2181 object->u.io.pending_count = 0;
2185 while (pending_callbacks--)
2191 if (
object->num_pending_callbacks)
2197 return !
object->num_running_callbacks;
2199 return !
object->num_associated_callbacks;
2231 if (!
io->shutdown && !--
ioqueue.objcount)
2262 TRACE(
"destroying object %p of type %u\n",
object,
object->type );
2275 if (
object->is_group_member)
2278 object->is_group_member =
FALSE;
2326 object->num_pending_callbacks--;
2332 if (wait_result ==
WAIT_OBJECT_0)
object->u.wait.signaled--;
2337 completion =
object->u.io.completions[--
object->u.io.completion_count];
2341 object->num_associated_callbacks++;
2342 object->num_running_callbacks++;
2351 instance.may_run_long =
object->may_run_long;
2355 instance.cleanup.semaphore_count = 0;
2363 TRACE(
"executing simple callback %p(%p, %p)\n",
2364 object->u.simple.callback, callback_instance,
object->userdata );
2365 object->u.simple.callback( callback_instance,
object->userdata );
2366 TRACE(
"callback %p returned\n",
object->u.simple.callback );
2372 TRACE(
"executing work callback %p(%p, %p, %p)\n",
2373 object->u.work.callback, callback_instance,
object->userdata,
object );
2374 object->u.work.callback( callback_instance,
object->userdata, (
TP_WORK *)
object );
2375 TRACE(
"callback %p returned\n",
object->u.work.callback );
2381 TRACE(
"executing timer callback %p(%p, %p, %p)\n",
2382 object->u.timer.callback, callback_instance,
object->userdata,
object );
2383 object->u.timer.callback( callback_instance,
object->userdata, (
TP_TIMER *)
object );
2384 TRACE(
"callback %p returned\n",
object->u.timer.callback );
2390 TRACE(
"executing wait callback %p(%p, %p, %p, %lu)\n",
2391 object->u.wait.callback, callback_instance,
object->userdata,
object, wait_result );
2392 object->u.wait.callback( callback_instance,
object->userdata, (
TP_WAIT *)
object, wait_result );
2393 TRACE(
"callback %p returned\n",
object->u.wait.callback );
2399 TRACE(
"executing I/O callback %p(%p, %p, %#Ix, %p, %p)\n",
2400 object->u.io.callback, callback_instance,
object->userdata,
2402 object->u.io.callback( callback_instance,
object->userdata,
2404 TRACE(
"callback %p returned\n",
object->u.io.callback );
2414 if (
object->finalization_callback)
2416 TRACE(
"executing finalization callback %p(%p, %p)\n",
2417 object->finalization_callback, callback_instance,
object->userdata );
2418 object->finalization_callback( callback_instance,
object->userdata );
2419 TRACE(
"callback %p returned\n",
object->finalization_callback );
2423 if (
instance.cleanup.critical_section)
2455 object->shutdown =
TRUE;
2458 object->num_running_callbacks--;
2464 object->num_associated_callbacks--;
2483 TRACE(
"starting worker thread for pool %p\n",
pool );
2497 if (
object->num_pending_callbacks > 1)
2503 pool->num_busy_workers--;
2520 (!
pool->min_workers && !
pool->objcount)))
2525 pool->num_workers--;
2528 TRACE(
"terminating worker thread for pool %p\n",
pool );
2627 object->u.timer.callback =
callback;
2662 object->u.wait.callback =
callback;
2663 object->u.wait.flags =
flags;
2713 object->u.work.callback =
callback;
2731 TRACE(
"pending_count %u.\n", this->
u.io.pending_count);
2733 this->
u.io.pending_count--;
2751 if (!this->
cleanup.critical_section)
2752 this->
cleanup.critical_section = crit;
2769 ERR(
"called from wrong thread, ignoring\n");
2773 if (this->may_run_long)
2776 pool =
object->pool;
2780 if (
pool->num_busy_workers >=
pool->num_workers)
2782 if (
pool->num_workers <
pool->max_workers)
2793 this->may_run_long =
TRUE;
2849 this->
cleanup.library = module;
2865 ERR(
"called from wrong thread, ignoring\n");
2869 if (!this->associated)
2872 pool =
object->pool;
2875 object->num_associated_callbacks--;
2880 this->associated =
FALSE;
2892 return this->
u.timer.timer_set;
2927 struct list members;
2929 TRACE(
"%p %u %p\n",
group, cancel_pending, userdata );
2945 object->is_group_member =
FALSE;
2949 object->is_group_member =
FALSE;
2976 if (cancel_pending &&
object->group_cancel_callback)
2978 TRACE(
"executing group cancel callback %p(%p, %p)\n",
2979 object->group_cancel_callback,
object->userdata, userdata );
2980 object->group_cancel_callback(
object->userdata, userdata );
2981 TRACE(
"callback %p returned\n",
object->group_cancel_callback );
2988 object->shutdown =
TRUE;
3004 this->
u.io.shutting_down =
TRUE;
3005 can_destroy = !this->
u.io.pending_count && !this->
u.io.skipped_count;
3129 assert( this->
u.timer.timer_initialized );
3130 this->
u.timer.timer_set = timeout !=
NULL;
3153 submit_timer =
TRUE;
3158 if (this->
u.timer.timer_pending)
3161 this->
u.timer.timer_pending =
FALSE;
3167 this->
u.timer.timeout = timestamp;
3168 this->
u.timer.period =
period;
3175 if (this->
u.timer.timeout < other_timer->
u.
timer.timeout)
3184 this->
u.timer.timer_pending =
TRUE;
3205 assert( this->
u.wait.bucket );
3208 if (handle || this->
u.wait.wait_pending)
3229 this->
u.wait.wait_pending =
TRUE;
3230 this->
u.wait.timeout = timestamp;
3235 this->
u.wait.wait_pending =
FALSE;
3269 object->u.simple.callback =
callback;
3286 this->
u.io.pending_count++;
3298 TRACE(
"%p %d\n",
io, cancel_pending );
3326 TRACE(
"%p %d\n",
wait, cancel_pending );
3340 TRACE(
"%p %u\n",
work, cancel_pending );
3426 TRACE(
"out %p, handle %p, callback %p, context %p, milliseconds %lu, flags %lx\n",
3429 memset( &environment, 0,
sizeof(environment) );
3439 object->u.wait.rtl_callback =
callback;
3478 object->completed_event =
event;
3482 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)
static uacpi_status set_event(uacpi_u8 event, uacpi_u8 value)
_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 void WINAPI TpWaitForWork(TP_WORK *, BOOL)
NTSYSAPI void WINAPI TpReleaseWork(TP_WORK *)
NTSYSAPI void WINAPI TpDisassociateCallback(TP_CALLBACK_INSTANCE *)
NTSYSAPI NTSTATUS WINAPI TpQueryPoolStackInformation(TP_POOL *, TP_POOL_STACK_INFORMATION *stack_info)
NTSYSAPI void WINAPI TpStartAsyncIoOperation(TP_IO *)
NTSYSAPI void WINAPI TpReleasePool(TP_POOL *)
NTSYSAPI NTSTATUS WINAPI TpAllocTimer(TP_TIMER **, PTP_TIMER_CALLBACK, PVOID, TP_CALLBACK_ENVIRON *)
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T) __WINE_ALLOC_SIZE(4) __WINE_DEALLOC(RtlFreeHeap
VOID(CALLBACK * PRTL_OVERLAPPED_COMPLETION_ROUTINE)(DWORD, DWORD, LPVOID)
NTSYSAPI NTSTATUS WINAPI TpAllocCleanupGroup(TP_CLEANUP_GROUP **)
void(NTAPI * RTL_WAITORTIMERCALLBACKFUNC)(PVOID, BOOLEAN)
NTSYSAPI void WINAPI TpWaitForTimer(TP_TIMER *, BOOL)
NTSYSAPI void WINAPI TpWaitForIoCompletion(TP_IO *, BOOL)
NTSYSAPI void WINAPI TpCancelAsyncIoOperation(TP_IO *)
NTSYSAPI BOOL WINAPI TpIsTimerSet(TP_TIMER *)
NTSYSAPI void WINAPI TpReleaseTimer(TP_TIMER *)
NTSYSAPI void WINAPI TpPostWork(TP_WORK *)
NTSYSAPI void WINAPI TpWaitForWait(TP_WAIT *, BOOL)
NTSYSAPI NTSTATUS WINAPI TpAllocIoCompletion(TP_IO **, HANDLE, PTP_IO_CALLBACK, void *, TP_CALLBACK_ENVIRON *)
NTSYSAPI void WINAPI TpSetWait(TP_WAIT *, HANDLE, LARGE_INTEGER *)
NTSYSAPI NTSTATUS WINAPI TpAllocPool(TP_POOL **, PVOID)
NTSYSAPI NTSTATUS WINAPI RtlInitializeCriticalSectionEx(RTL_CRITICAL_SECTION *, ULONG, ULONG)
struct _THREAD_NAME_INFORMATION THREAD_NAME_INFORMATION
NTSYSAPI void WINAPI TpReleaseIoCompletion(TP_IO *)
void(CALLBACK * PNTAPCFUNC)(ULONG_PTR, ULONG_PTR, ULONG_PTR)
struct _THREAD_NAME_INFORMATION * PTHREAD_NAME_INFORMATION
void(CALLBACK * PRTL_THREAD_START_ROUTINE)(LPVOID)
NTSYSAPI NTSTATUS WINAPI TpAllocWait(TP_WAIT **, PTP_WAIT_CALLBACK, PVOID, TP_CALLBACK_ENVIRON *)
NTSYSAPI void WINAPI TpSetPoolMaxThreads(TP_POOL *, DWORD)
NTSYSAPI void WINAPI TpCallbackReleaseSemaphoreOnCompletion(TP_CALLBACK_INSTANCE *, HANDLE, DWORD)
NTSYSAPI NTSTATUS WINAPI TpAllocWork(TP_WORK **, PTP_WORK_CALLBACK, PVOID, TP_CALLBACK_ENVIRON *)
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
NTSYSAPI void WINAPI TpReleaseCleanupGroupMembers(TP_CLEANUP_GROUP *, BOOL, PVOID)
NTSYSAPI void WINAPI TpReleaseCleanupGroup(TP_CLEANUP_GROUP *)
NTSYSAPI void WINAPI TpSetTimer(TP_TIMER *, LARGE_INTEGER *, LONG, LONG)
NTSYSAPI NTSTATUS WINAPI TpSimpleTryPost(PTP_SIMPLE_CALLBACK, PVOID, TP_CALLBACK_ENVIRON *)
NTSYSAPI NTSTATUS WINAPI TpCallbackMayRunLong(TP_CALLBACK_INSTANCE *)
void(CALLBACK * PTP_IO_CALLBACK)(PTP_CALLBACK_INSTANCE, void *, void *, IO_STATUS_BLOCK *, PTP_IO)
NTSYSAPI NTSTATUS WINAPI TpSetPoolStackInformation(TP_POOL *, TP_POOL_STACK_INFORMATION *stack_info)
NTSYSAPI void WINAPI TpReleaseWait(TP_WAIT *)
#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)
static RTL_CRITICAL_SECTION_DEBUG waitqueue_debug
static void tp_object_wait(struct threadpool_object *object, BOOL group_wait)
static struct @5260 waitqueue
RTL_CRITICAL_SECTION threadpool_compl_cs
static BOOL tp_object_release(struct threadpool_object *object)
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)
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 void CALLBACK process_rtl_work_item(TP_CALLBACK_INSTANCE *instance, void *userdata)
static void tp_group_shutdown(struct threadpool_group *group)
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 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)
static struct threadpool * default_threadpool
static ULONGLONG queue_current_time(void)
static DWORD WINAPI timer_callback_wrapper(LPVOID p)
static NTSTATUS tp_threadpool_alloc(struct threadpool **out)
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)
static BOOL tp_threadpool_release(struct threadpool *pool)
struct list pending_timers
static RTL_CRITICAL_SECTION_DEBUG timerqueue_debug
static struct threadpool_object * impl_from_TP_WORK(TP_WORK *work)
static struct @5259 timerqueue
#define TIMER_QUEUE_MAGIC
static struct threadpool_object * impl_from_TP_WAIT(TP_WAIT *wait)
static BOOL object_is_finished(struct threadpool_object *object, BOOL group)
#define THREADPOOL_WORKER_TIMEOUT
VOID WINAPI TpCallbackSetEventOnCompletion(TP_CALLBACK_INSTANCE *instance, HANDLE event)
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 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 struct @5258 old_threadpool
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)
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)
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)
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 void tp_threadpool_shutdown(struct threadpool *pool)
static void queue_timer_expire(struct timer_queue *q)
static struct @5261 ioqueue
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
PTP_SIMPLE_CALLBACK FinalizationCallback
struct _TP_CALLBACK_ENVIRON_V3::@4475::@4476 s
TP_CALLBACK_PRIORITY CallbackPriority
PTP_CLEANUP_GROUP_CANCEL_CALLBACK CleanupGroupCancelCallback
struct _ACTIVATION_CONTEXT * ActivationContext
union _TP_CALLBACK_ENVIRON_V3::@4475 u
RTL_WAITORTIMERCALLBACKFUNC callback
PRTL_WORK_ITEM_ROUTINE function
CRITICAL_SECTION * critical_section
struct threadpool_instance::@5268 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 threadpool_object::@5262::@5266 wait
struct io_completion * completions
struct threadpool_object::@5262::@5264 work
unsigned int skipped_count
enum threadpool_objtype type
struct threadpool_object::@5262::@5263 simple
struct threadpool_object::@5262::@5265 timer
unsigned int completion_count
unsigned int completion_max
union threadpool_object::@5262 u
unsigned int pending_count
LONG num_associated_callbacks
RTL_WAITORTIMERCALLBACKFUNC rtl_callback
LONG num_running_callbacks
LONG num_pending_callbacks
PTP_WORK_CALLBACK callback
RTL_CONDITION_VARIABLE group_finished_event
PTP_SIMPLE_CALLBACK finalization_callback
struct waitqueue_bucket * bucket
PTP_TIMER_CALLBACK callback
struct threadpool_group * group
struct threadpool_object::@5262::@5267 io
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)
#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