https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0bf42067d28ea488e03c9…
commit 0bf42067d28ea488e03c9955632d2a614c4262c2
Author: Justin Miller <justin.miller(a)reactos.org>
AuthorDate: Fri Apr 26 01:03:15 2024 -0700
Commit: Justin Miller <justinmiller100(a)gmail.com>
CommitDate: Sun Jan 26 23:30:59 2025 -0800
[KERNEL32][ROSTESTS][SDK] Enable threadpooling
[NTDLL] Init KeyedEvents even on NT5.2 dll_export
[MEDIA] Update winesync.txt accordingly
[SDK][DLL] Initialize crtical sections at runtime
---
dll/ntdll/def/ntdll.spec | 68 ++--
dll/ntdll/include/ntdllp.h | 5 +
dll/ntdll/ldr/ldrinit.c | 4 +-
dll/ntdll/nt_0600/ntdll_vista.spec | 29 --
media/doc/WINESYNC.txt | 4 +-
modules/rostests/winetests/ntdll/CMakeLists.txt | 1 +
modules/rostests/winetests/ntdll/testlist.c | 2 +
modules/rostests/winetests/ntdll/threadpool.c | 16 +
sdk/include/ndk/rtlfuncs.h | 5 +
sdk/include/xdk/winnt_old.h | 6 +
sdk/lib/rtl/CMakeLists.txt | 9 +-
sdk/lib/rtl/rtl.h | 2 +
sdk/lib/rtl/threadpool.c | 172 ++++++++-
sdk/lib/rtl/timerqueue.c | 493 ------------------------
sdk/lib/rtl/wait.c | 275 -------------
15 files changed, 249 insertions(+), 842 deletions(-)
diff --git a/dll/ntdll/def/ntdll.spec b/dll/ntdll/def/ntdll.spec
index de23297ea55..b023b06f9c3 100644
--- a/dll/ntdll/def/ntdll.spec
+++ b/dll/ntdll/def/ntdll.spec
@@ -1311,45 +1311,47 @@
@ stub -version=0x600+ ShipAssertMsgA
@ stub -version=0x600+ ShipAssertMsgW
@ stub -version=0x600+ TpAllocAlpcCompletion
-@ stub -version=0x600+ TpAllocCleanupGroup
-@ stub -version=0x600+ TpAllocIoCompletion
-@ stub -version=0x600+ TpAllocPool
-@ stub -version=0x600+ TpAllocTimer
-@ stub -version=0x600+ TpAllocWait
-@ stub -version=0x600+ TpAllocWork
-@ stub -version=0x600+ TpCallbackLeaveCriticalSectionOnCompletion
-@ stub -version=0x600+ TpCallbackMayRunLong
-@ stub -version=0x600+ TpCallbackReleaseMutexOnCompletion
-@ stub -version=0x600+ TpCallbackReleaseSemaphoreOnCompletion
-@ stub -version=0x600+ TpCallbackSetEventOnCompletion
-@ stub -version=0x600+ TpCallbackUnloadDllOnCompletion
-@ stub -version=0x600+ TpCancelAsyncIoOperation
+@ stdcall -version=0x600+ TpAllocCleanupGroup(ptr)
+@ stdcall -version=0x600+ TpAllocIoCompletion(ptr ptr ptr ptr ptr)
+@ stdcall -version=0x600+ TpAllocPool(ptr ptr)
+@ stdcall -version=0x600+ TpAllocTimer(ptr ptr ptr ptr)
+@ stdcall -version=0x600+ TpAllocWait(ptr ptr ptr ptr)
+@ stdcall -version=0x600+ TpAllocWork(ptr ptr ptr ptr)
+@ stdcall -version=0x600+ TpCallbackLeaveCriticalSectionOnCompletion(ptr ptr)
+@ stdcall -version=0x600+ TpCallbackMayRunLong(ptr)
+@ stdcall -version=0x600+ TpCallbackReleaseMutexOnCompletion(ptr ptr)
+@ stdcall -version=0x600+ TpCallbackReleaseSemaphoreOnCompletion(ptr ptr long)
+@ stdcall -version=0x600+ TpCallbackSetEventOnCompletion(ptr ptr)
+@ stdcall -version=0x600+ TpCallbackUnloadDllOnCompletion(ptr ptr)
+@ stdcall -version=0x600+ TpCancelAsyncIoOperation(ptr)
@ stub -version=0x600+ TpCaptureCaller
@ stub -version=0x600+ TpCheckTerminateWorker
@ stub -version=0x600+ TpDbgDumpHeapUsage
@ stub -version=0x600+ TpDbgSetLogRoutine
-@ stub -version=0x600+ TpDisassociateCallback
-@ stub -version=0x600+ TpIsTimerSet
-@ stub -version=0x600+ TpPostWork
+@ stdcall -version=0x600+ TpDisassociateCallback(ptr)
+@ stdcall -version=0x600+ TpIsTimerSet(ptr)
+@ stdcall -version=0x600+ TpPostWork(ptr)
+@ stdcall -version=0x600+ TpQueryPoolStackInformation(ptr ptr)
@ stub -version=0x600+ TpReleaseAlpcCompletion
-@ stub -version=0x600+ TpReleaseCleanupGroup
-@ stub -version=0x600+ TpReleaseCleanupGroupMembers
-@ stub -version=0x600+ TpReleaseIoCompletion
-@ stub -version=0x600+ TpReleasePool
-@ stub -version=0x600+ TpReleaseTimer
-@ stub -version=0x600+ TpReleaseWait
-@ stub -version=0x600+ TpReleaseWork
-@ stub -version=0x600+ TpSetPoolMaxThreads
-@ stub -version=0x600+ TpSetPoolMinThreads
-@ stub -version=0x600+ TpSetTimer
-@ stub -version=0x600+ TpSetWait
-@ stub -version=0x600+ TpSimpleTryPost
-@ stub -version=0x600+ TpStartAsyncIoOperation
+@ stdcall -version=0x600+ TpReleaseCleanupGroup(ptr)
+@ stdcall -version=0x600+ TpReleaseCleanupGroupMembers(ptr long ptr)
+@ stdcall -version=0x600+ TpReleaseIoCompletion(ptr)
+@ stdcall -version=0x600+ TpReleasePool(ptr)
+@ stdcall -version=0x600+ TpReleaseTimer(ptr)
+@ stdcall -version=0x600+ TpReleaseWait(ptr)
+@ stdcall -version=0x600+ TpReleaseWork(ptr)
+@ stdcall -version=0x600+ TpSetPoolMaxThreads(ptr long)
+@ stdcall -version=0x600+ TpSetPoolMinThreads(ptr long)
+@ stdcall -version=0x600+ TpSetPoolStackInformation(ptr ptr)
+@ stdcall -version=0x600+ TpSetTimer(ptr ptr long long)
+@ stdcall -version=0x600+ TpSetWait(ptr long ptr)
+@ stdcall -version=0x600+ TpSimpleTryPost(ptr ptr ptr)
+@ stdcall -version=0x600+ TpStartAsyncIoOperation(ptr)
@ stub -version=0x600+ TpWaitForAlpcCompletion
-@ stub -version=0x600+ TpWaitForIoCompletion
-@ stub -version=0x600+ TpWaitForTimer
-@ stub -version=0x600+ TpWaitForWait
-@ stub -version=0x600+ TpWaitForWork
+@ stdcall -version=0x600+ TpWaitForIoCompletion(ptr long)
+@ stdcall -version=0x600+ TpWaitForTimer(ptr long)
+@ stdcall -version=0x600+ TpWaitForWait(ptr long)
+@ stdcall -version=0x600+ TpWaitForWork(ptr long)
@ stdcall -ret64 VerSetConditionMask(double long long)
@ stub -version=0x600+ WerCheckEventEscalation
@ stub -version=0x600+ WerReportSQMEvent
diff --git a/dll/ntdll/include/ntdllp.h b/dll/ntdll/include/ntdllp.h
index bd5cc9ea91c..c5ea35a2761 100644
--- a/dll/ntdll/include/ntdllp.h
+++ b/dll/ntdll/include/ntdllp.h
@@ -242,4 +242,9 @@ NTAPI
RtlpInitializeKeyedEvent(
VOID);
+VOID
+NTAPI
+RtlpInitializeThreadPooling(
+ VOID);
+
/* EOF */
diff --git a/dll/ntdll/ldr/ldrinit.c b/dll/ntdll/ldr/ldrinit.c
index 4fbc4f293aa..cde86383759 100644
--- a/dll/ntdll/ldr/ldrinit.c
+++ b/dll/ntdll/ldr/ldrinit.c
@@ -2415,10 +2415,10 @@ LdrpInitializeProcess(IN PCONTEXT Context,
/* Check whether all static imports were properly loaded and return here */
if (!NT_SUCCESS(ImportStatus)) return ImportStatus;
-#if (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)
+ /* Following two calls are for Vista+ support, required for winesync */
/* Initialize the keyed event for condition variables */
RtlpInitializeKeyedEvent();
-#endif
+ RtlpInitializeThreadPooling();
/* Initialize TLS */
Status = LdrpInitializeTls();
diff --git a/dll/ntdll/nt_0600/ntdll_vista.spec b/dll/ntdll/nt_0600/ntdll_vista.spec
index 23fd88e02c4..d36c6449d8e 100644
--- a/dll/ntdll/nt_0600/ntdll_vista.spec
+++ b/dll/ntdll/nt_0600/ntdll_vista.spec
@@ -13,34 +13,5 @@
@ stdcall RtlRunOnceComplete(ptr long ptr)
@ stdcall RtlRunOnceExecuteOnce(ptr ptr ptr ptr)
-@ stdcall TpAllocCleanupGroup(ptr)
-@ stdcall TpAllocPool(ptr ptr)
-@ stdcall TpAllocTimer(ptr ptr ptr ptr)
-@ stdcall TpAllocWait(ptr ptr ptr ptr)
-@ stdcall TpAllocWork(ptr ptr ptr ptr)
-@ stdcall TpCallbackLeaveCriticalSectionOnCompletion(ptr ptr)
-@ stdcall TpCallbackMayRunLong(ptr)
-@ stdcall TpCallbackReleaseMutexOnCompletion(ptr ptr)
-@ stdcall TpCallbackReleaseSemaphoreOnCompletion(ptr ptr long)
-@ stdcall TpCallbackSetEventOnCompletion(ptr ptr)
-@ stdcall TpCallbackUnloadDllOnCompletion(ptr ptr)
-@ stdcall TpDisassociateCallback(ptr)
-@ stdcall TpIsTimerSet(ptr)
-@ stdcall TpPostWork(ptr)
-@ stdcall TpReleaseCleanupGroup(ptr)
-@ stdcall TpReleaseCleanupGroupMembers(ptr long ptr)
-@ stdcall TpReleasePool(ptr)
-@ stdcall TpReleaseTimer(ptr)
-@ stdcall TpReleaseWait(ptr)
-@ stdcall TpReleaseWork(ptr)
-@ 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 RtlConnectToSm(ptr ptr long ptr) SmConnectToSm
@ stdcall RtlSendMsgToSm(ptr ptr) SmSendMsgToSm
diff --git a/media/doc/WINESYNC.txt b/media/doc/WINESYNC.txt
index 61e11c67f15..44f5cb523ae 100644
--- a/media/doc/WINESYNC.txt
+++ b/media/doc/WINESYNC.txt
@@ -267,8 +267,8 @@ check Wine current sources first as it may already be fixed.
sdk/lib/3rdparty/strmbase # Synced to WineStaging-3.3
-sdk/lib/rtl/actctx.c # Synced to wine-5.18
-sdk/lib/rtl/threadpool.c # Synced with wine-9.7
+sdk/lib/rtl/actctx.c # Partly synced with WineStaging-1.9.16
+sdk/lib/rtl/threadpool.c # Synced with Wine-9.7
advapi32 -
dll/win32/advapi32/wine/cred.c # Synced to WineStaging-3.3
diff --git a/modules/rostests/winetests/ntdll/CMakeLists.txt
b/modules/rostests/winetests/ntdll/CMakeLists.txt
index c5a886481e7..dbcf2116039 100644
--- a/modules/rostests/winetests/ntdll/CMakeLists.txt
+++ b/modules/rostests/winetests/ntdll/CMakeLists.txt
@@ -23,6 +23,7 @@ list(APPEND SOURCE
rtlstr.c
string.c
testlist.c
+ threadpool.c
time.c)
if(ARCH STREQUAL "i386")
diff --git a/modules/rostests/winetests/ntdll/testlist.c
b/modules/rostests/winetests/ntdll/testlist.c
index 989040c562a..1c9edc99e86 100644
--- a/modules/rostests/winetests/ntdll/testlist.c
+++ b/modules/rostests/winetests/ntdll/testlist.c
@@ -23,6 +23,7 @@ extern void func_rtl(void);
extern void func_rtlbitmap(void);
extern void func_rtlstr(void);
extern void func_string(void);
+extern void func_threadpool(void);
extern void func_time(void);
const struct test winetest_testlist[] =
@@ -49,6 +50,7 @@ const struct test winetest_testlist[] =
{ "rtlbitmap", func_rtlbitmap },
{ "rtlstr", func_rtlstr },
{ "string", func_string },
+ { "threadpool", func_threadpool},
{ "time", func_time },
{ 0, 0 }
};
diff --git a/modules/rostests/winetests/ntdll/threadpool.c
b/modules/rostests/winetests/ntdll/threadpool.c
index 1dd96bfd2f3..88f4e55fa97 100644
--- a/modules/rostests/winetests/ntdll/threadpool.c
+++ b/modules/rostests/winetests/ntdll/threadpool.c
@@ -20,6 +20,10 @@
#include "ntdll_test.h"
+#ifdef __REACTOS__
+typedef void (CALLBACK
*PTP_IO_CALLBACK)(PTP_CALLBACK_INSTANCE,void*,void*,IO_STATUS_BLOCK*,PTP_IO);
+#endif
+
static NTSTATUS (WINAPI *pTpAllocCleanupGroup)(TP_CLEANUP_GROUP **);
static NTSTATUS (WINAPI *pTpAllocIoCompletion)(TP_IO **,HANDLE,PTP_IO_CALLBACK,void
*,TP_CALLBACK_ENVIRON *);
static NTSTATUS (WINAPI *pTpAllocPool)(TP_POOL **,PVOID);
@@ -580,7 +584,9 @@ static void test_tp_simple(void)
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress
);
TP_POOL_STACK_INFORMATION stack_info;
TP_CALLBACK_ENVIRON environment;
+#ifndef __REACTOS__
TP_CALLBACK_ENVIRON_V3 environment3;
+#endif
TP_CLEANUP_GROUP *group;
HANDLE semaphore;
NTSTATUS status;
@@ -616,6 +622,7 @@ static void test_tp_simple(void)
result = WaitForSingleObject(semaphore, 1000);
ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result);
+#ifndef __REACTOS__ // Windows 7
/* test with environment version 3 */
memset(&environment3, 0, sizeof(environment3));
environment3.Version = 3;
@@ -635,6 +642,7 @@ static void test_tp_simple(void)
status = pTpSimpleTryPost(simple_cb, semaphore, (TP_CALLBACK_ENVIRON
*)&environment3);
ok(status == STATUS_INVALID_PARAMETER || broken(!status) /* Vista does not support
priorities */,
"TpSimpleTryPost failed with status %lx\n", status);
+#endif
/* test with invalid version number */
memset(&environment, 0, sizeof(environment));
@@ -2031,7 +2039,11 @@ static DWORD WINAPI io_wait_thread(void *arg)
static void test_tp_io(void)
{
TP_CALLBACK_ENVIRON environment = {.Version = 1};
+#ifdef __REACTOS__
+ OVERLAPPED ovl = {0}, ovl2 = {0};
+#else
OVERLAPPED ovl = {}, ovl2 = {};
+#endif
HANDLE client, server, thread;
struct io_cb_ctx userdata;
char in[1], in2[1];
@@ -2251,7 +2263,11 @@ static void CALLBACK kernel32_io_cb(TP_CALLBACK_INSTANCE *instance,
void *userda
static void test_kernel32_tp_io(void)
{
TP_CALLBACK_ENVIRON environment = {.Version = 1};
+#ifdef __REACTOS__
+ OVERLAPPED ovl = {0}, ovl2 = {0};
+#else
OVERLAPPED ovl = {}, ovl2 = {};
+#endif
HANDLE client, server, thread;
struct io_cb_ctx userdata;
char in[1], in2[1];
diff --git a/sdk/include/ndk/rtlfuncs.h b/sdk/include/ndk/rtlfuncs.h
index 7b128cd440b..c9135cfc909 100644
--- a/sdk/include/ndk/rtlfuncs.h
+++ b/sdk/include/ndk/rtlfuncs.h
@@ -4748,24 +4748,29 @@ RtlSleepConditionVariableSRW(
//
// Synchronization functions
//
+NTSYSAPI
VOID
NTAPI
RtlInitializeConditionVariable(OUT PRTL_CONDITION_VARIABLE ConditionVariable);
+NTSYSAPI
VOID
NTAPI
RtlWakeConditionVariable(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable);
+NTSYSAPI
VOID
NTAPI
RtlWakeAllConditionVariable(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable);
+NTSYSAPI
NTSTATUS
NTAPI
RtlSleepConditionVariableCS(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
IN OUT PRTL_CRITICAL_SECTION CriticalSection,
IN const PLARGE_INTEGER TimeOut OPTIONAL);
+NTSYSAPI
NTSTATUS
NTAPI
RtlSleepConditionVariableSRW(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
diff --git a/sdk/include/xdk/winnt_old.h b/sdk/include/xdk/winnt_old.h
index ee28a933347..3de049071bf 100644
--- a/sdk/include/xdk/winnt_old.h
+++ b/sdk/include/xdk/winnt_old.h
@@ -4495,6 +4495,12 @@ typedef enum _TP_CALLBACK_PRIORITY {
TP_CALLBACK_PRIORITY_COUNT = TP_CALLBACK_PRIORITY_INVALID
} TP_CALLBACK_PRIORITY;
+typedef struct _TP_POOL_STACK_INFORMATION
+{
+ SIZE_T StackReserve;
+ SIZE_T StackCommit;
+} TP_POOL_STACK_INFORMATION,*PTP_POOL_STACK_INFORMATION;
+
typedef VOID
(NTAPI *PTP_WORK_CALLBACK)(
_Inout_ PTP_CALLBACK_INSTANCE Instance,
diff --git a/sdk/lib/rtl/CMakeLists.txt b/sdk/lib/rtl/CMakeLists.txt
index 78077605a91..202857437d5 100644
--- a/sdk/lib/rtl/CMakeLists.txt
+++ b/sdk/lib/rtl/CMakeLists.txt
@@ -8,13 +8,19 @@ add_definitions(
if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL
"Clang")
# Enable this again. CORE-17637
add_compile_options(-Wunused-result)
+
+ add_compile_options(-Wno-incompatible-pointer-types)
+ add_compile_options(-Wno-missing-braces)
endif()
+include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine)
+
list(APPEND RTL_WINE_SOURCE
actctx.c
timerqueue.c
- wait.c
+ threadpool.c
)
+set_source_files_properties(threadpool.c PROPERTIES COMPILE_DEFINITIONS __WINESRC__)
if(MSVC)
# Silence warning C4267: 'initializing': conversion from 'size_t' to
'const int', possible loss of data
@@ -127,7 +133,6 @@ list(APPEND SOURCE_VISTA
condvar.c
runonce.c
srw.c
- threadpool.c
utf8.c)
add_library(rtl_vista ${SOURCE_VISTA})
diff --git a/sdk/lib/rtl/rtl.h b/sdk/lib/rtl/rtl.h
index 037b2ee2c9b..d818fcad4dc 100644
--- a/sdk/lib/rtl/rtl.h
+++ b/sdk/lib/rtl/rtl.h
@@ -56,6 +56,7 @@
/* Use intrinsics for x86 and x64 */
#if defined(_M_IX86) || defined(_M_AMD64)
+#ifndef InterlockedCompareExchange
#define InterlockedCompareExchange _InterlockedCompareExchange
#define InterlockedIncrement _InterlockedIncrement
#define InterlockedDecrement _InterlockedDecrement
@@ -64,5 +65,6 @@
#define InterlockedBitTestAndSet _interlockedbittestandset
#define InterlockedBitTestAndSet64 _interlockedbittestandset64
#endif
+#endif
#endif /* RTL_H */
diff --git a/sdk/lib/rtl/threadpool.c b/sdk/lib/rtl/threadpool.c
index c6e40fc78f4..efdfa454618 100644
--- a/sdk/lib/rtl/threadpool.c
+++ b/sdk/lib/rtl/threadpool.c
@@ -19,6 +19,42 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+
+#ifdef __REACTOS__
+#include <rtl_vista.h>
+#define NDEBUG
+#include "wine/list.h"
+#include <debug.h>
+
+#define ERR(fmt, ...) DPRINT1(fmt, ##__VA_ARGS__)
+#define FIXME(fmt, ...) DPRINT(fmt, ##__VA_ARGS__)
+#define WARN(fmt, ...) DPRINT(fmt, ##__VA_ARGS__)
+#define TRACE(fmt, ...) DPRINT(fmt, ##__VA_ARGS__)
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(_x) (sizeof((_x))/sizeof((_x)[0]))
+#endif
+
+typedef struct _THREAD_NAME_INFORMATION
+{
+ UNICODE_STRING ThreadName;
+} THREAD_NAME_INFORMATION, *PTHREAD_NAME_INFORMATION;
+
+typedef void (CALLBACK *PNTAPCFUNC)(ULONG_PTR,ULONG_PTR,ULONG_PTR);
+typedef void (CALLBACK *PRTL_THREAD_START_ROUTINE)(LPVOID);
+typedef DWORD (CALLBACK *PRTL_WORK_ITEM_ROUTINE)(LPVOID);
+typedef void (NTAPI *RTL_WAITORTIMERCALLBACKFUNC)(PVOID,BOOLEAN);
+typedef VOID (CALLBACK *PRTL_OVERLAPPED_COMPLETION_ROUTINE)(DWORD,DWORD,LPVOID);
+
+typedef void (CALLBACK
*PTP_IO_CALLBACK)(PTP_CALLBACK_INSTANCE,void*,void*,IO_STATUS_BLOCK*,PTP_IO);
+NTSYSAPI NTSTATUS WINAPI TpSimpleTryPost(PTP_SIMPLE_CALLBACK,PVOID,TP_CALLBACK_ENVIRON
*);
+#define PRTL_WORK_ITEM_ROUTINE WORKERCALLBACKFUNC
+
+#define CRITICAL_SECTION RTL_CRITICAL_SECTION
+#define GetProcessHeap() RtlGetProcessHeap()
+#define GetCurrentProcess() NtCurrentProcess()
+#define GetCurrentThread() NtCurrentThread()
+#define GetCurrentThreadId() HandleToULong(NtCurrentTeb()->ClientId.UniqueThread)
+#else
#include <assert.h>
#include <stdarg.h>
#include <limits.h>
@@ -33,6 +69,7 @@
#include "ntdll_misc.h"
WINE_DEFAULT_DEBUG_CHANNEL(threadpool);
+#endif
/*
* Old thread pooling API
@@ -47,7 +84,9 @@ struct rtl_work_item
#define EXPIRE_NEVER (~(ULONGLONG)0)
#define TIMER_QUEUE_MAGIC 0x516d6954 /* TimQ */
+#ifndef __REACTOS__
static RTL_CRITICAL_SECTION_DEBUG critsect_compl_debug;
+#endif
static struct
{
@@ -57,15 +96,21 @@ static struct
old_threadpool =
{
NULL, /* compl_port */
+#ifdef __REACTOS__
+ {0}, /* threadpool_compl_cs */
+#else
{ &critsect_compl_debug, -1, 0, 0, 0, 0 }, /* threadpool_compl_cs */
+#endif
};
+#ifndef __REACTOS__
static RTL_CRITICAL_SECTION_DEBUG critsect_compl_debug =
{
0, 0, &old_threadpool.threadpool_compl_cs,
{ &critsect_compl_debug.ProcessLocksList,
&critsect_compl_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": threadpool_compl_cs") }
};
+#endif
struct timer_queue;
struct queue_timer
@@ -235,8 +280,10 @@ struct threadpool_group
struct list members;
};
+#ifndef __REACTOS__
/* global timerqueue object */
static RTL_CRITICAL_SECTION_DEBUG timerqueue_debug;
+#endif
static struct
{
@@ -248,13 +295,22 @@ static struct
}
timerqueue =
{
+#ifdef __REACTOS__
+ {0}, /* cs */
+#else
{ &timerqueue_debug, -1, 0, 0, 0, 0 }, /* cs */
+#endif
0, /* objcount */
FALSE, /* thread_running */
LIST_INIT( timerqueue.pending_timers ), /* pending_timers */
+#if __REACTOS__
+ 0,
+#else
RTL_CONDITION_VARIABLE_INIT /* update_event */
+#endif
};
+#ifndef __REACTOS__
static RTL_CRITICAL_SECTION_DEBUG timerqueue_debug =
{
0, 0, &timerqueue.cs,
@@ -264,6 +320,7 @@ static RTL_CRITICAL_SECTION_DEBUG timerqueue_debug =
/* global waitqueue object */
static RTL_CRITICAL_SECTION_DEBUG waitqueue_debug;
+#endif
static struct
{
@@ -273,17 +330,23 @@ static struct
}
waitqueue =
{
+#ifdef __REACTOS__
+ {0}, /* cs */
+#else
{ &waitqueue_debug, -1, 0, 0, 0, 0 }, /* cs */
+#endif
0, /* num_buckets */
LIST_INIT( waitqueue.buckets ) /* buckets */
};
+#ifndef __REACTOS__
static RTL_CRITICAL_SECTION_DEBUG waitqueue_debug =
{
0, 0, &waitqueue.cs,
{ &waitqueue_debug.ProcessLocksList, &waitqueue_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": waitqueue.cs") }
};
+#endif
struct waitqueue_bucket
{
@@ -295,8 +358,10 @@ struct waitqueue_bucket
BOOL alertable;
};
+#ifndef __REACTOS__
/* global I/O completion queue object */
static RTL_CRITICAL_SECTION_DEBUG ioqueue_debug;
+#endif
static struct
{
@@ -308,15 +373,21 @@ static struct
}
ioqueue =
{
+#ifdef __REACTOS__
+ .cs = {0},
+#else
.cs = { &ioqueue_debug, -1, 0, 0, 0, 0 },
+#endif
};
+#ifndef __REACTOS__
static RTL_CRITICAL_SECTION_DEBUG ioqueue_debug =
{
0, 0, &ioqueue.cs,
{ &ioqueue_debug.ProcessLocksList, &ioqueue_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": ioqueue.cs") }
};
+#endif
static inline struct threadpool *impl_from_TP_POOL( TP_POOL *pool )
{
@@ -361,7 +432,11 @@ static inline struct threadpool_instance
*impl_from_TP_CALLBACK_INSTANCE( TP_CAL
return (struct threadpool_instance *)instance;
}
+#ifdef __REACTOS__
+ULONG NTAPI threadpool_worker_proc(PVOID param );
+#else
static void CALLBACK threadpool_worker_proc( void *param );
+#endif
static void tp_object_submit( struct threadpool_object *object, BOOL signaled );
static void tp_object_execute( struct threadpool_object *object, BOOL wait_thread );
static void tp_object_prepare_shutdown( struct threadpool_object *object );
@@ -397,12 +472,15 @@ static BOOL array_reserve(void **elements, unsigned int *capacity,
unsigned int
static void set_thread_name(const WCHAR *name)
{
+#ifndef __REACTOS__ // This is impossible on non vista+
THREAD_NAME_INFORMATION info;
RtlInitUnicodeString(&info.ThreadName, name);
NtSetInformationThread(GetCurrentThread(), ThreadNameInformation, &info,
sizeof(info));
+#endif
}
+#ifndef __REACTOS__
static void CALLBACK process_rtl_work_item( TP_CALLBACK_INSTANCE *instance, void
*userdata )
{
struct rtl_work_item *item = userdata;
@@ -472,7 +550,11 @@ static DWORD CALLBACK iocp_poller(LPVOID Arg)
PRTL_OVERLAPPED_COMPLETION_ROUTINE callback;
LPVOID overlapped;
IO_STATUS_BLOCK iosb;
+#ifdef __REACTOS__
+ NTSTATUS res = NtRemoveIoCompletion( cport, (PVOID)&callback,
(PVOID)&overlapped, &iosb, NULL );
+#else
NTSTATUS res = NtRemoveIoCompletion( cport, (PULONG_PTR)&callback,
(PULONG_PTR)&overlapped, &iosb, NULL );
+#endif
if (res)
{
ERR("NtRemoveIoCompletion failed: 0x%lx\n", res);
@@ -545,6 +627,7 @@ NTSTATUS WINAPI RtlSetIoCompletionCallback(HANDLE FileHandle,
PRTL_OVERLAPPED_CO
return NtSetInformationFile( FileHandle, &iosb, &info, sizeof(info),
FileCompletionInformation );
}
+#endif
static inline PLARGE_INTEGER get_nt_timeout( PLARGE_INTEGER pTime, ULONG timeout )
{
@@ -553,7 +636,6 @@ static inline PLARGE_INTEGER get_nt_timeout( PLARGE_INTEGER pTime,
ULONG timeout
return pTime;
}
-
/************************** Timer Queue Impl **************************/
static void queue_remove_timer(struct queue_timer *t)
@@ -705,7 +787,11 @@ static ULONG queue_get_timeout(struct timer_queue *q)
return timeout;
}
+#ifdef __REACTOS__
+ULONG NTAPI timer_queue_thread_proc(PVOID p)
+#else
static void WINAPI timer_queue_thread_proc(LPVOID p)
+#endif
{
struct timer_queue *q = p;
ULONG timeout_ms;
@@ -746,6 +832,9 @@ static void WINAPI timer_queue_thread_proc(LPVOID p)
q->magic = 0;
RtlFreeHeap(GetProcessHeap(), 0, q);
RtlExitUserThread( 0 );
+#ifdef __REACTOS__
+ return STATUS_SUCCESS;
+#endif
}
static void queue_destroy_timer(struct queue_timer *t)
@@ -1052,7 +1141,11 @@ NTSTATUS WINAPI RtlDeleteTimer(HANDLE TimerQueue, HANDLE Timer,
/***********************************************************************
* timerqueue_thread_proc (internal)
*/
+#ifdef __REACTOS__
+ULONG NTAPI timerqueue_thread_proc(PVOID param )
+#else
static void CALLBACK timerqueue_thread_proc( void *param )
+#endif
{
ULONGLONG timeout_lower, timeout_upper, new_timeout;
struct threadpool_object *other_timer;
@@ -1139,6 +1232,9 @@ static void CALLBACK timerqueue_thread_proc( void *param )
TRACE( "terminating timer queue thread\n" );
RtlExitUserThread( 0 );
+#ifdef __REACTOS__
+ return STATUS_SUCCESS;
+#endif
}
/***********************************************************************
@@ -1240,7 +1336,11 @@ static void tp_timerqueue_unlock( struct threadpool_object *timer
)
/***********************************************************************
* waitqueue_thread_proc (internal)
*/
+#ifdef __REACTOS__
+void NTAPI waitqueue_thread_proc(PVOID param )
+#else
static void CALLBACK waitqueue_thread_proc( void *param )
+#endif
{
struct threadpool_object *objects[MAXIMUM_WAITQUEUE_OBJECTS];
HANDLE handles[MAXIMUM_WAITQUEUE_OBJECTS + 1];
@@ -1467,7 +1567,7 @@ static NTSTATUS tp_waitqueue_lock( struct threadpool_object *wait )
}
status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, 0, 0, 0,
- waitqueue_thread_proc, bucket, &thread, NULL );
+ (PTHREAD_START_ROUTINE)waitqueue_thread_proc, bucket,
&thread, NULL );
if (status == STATUS_SUCCESS)
{
list_add_tail( &waitqueue.buckets, &bucket->bucket_entry );
@@ -1512,12 +1612,20 @@ static void tp_waitqueue_unlock( struct threadpool_object *wait )
RtlLeaveCriticalSection( &waitqueue.cs );
}
+#ifdef __REACTOS__
+ULONG NTAPI ioqueue_thread_proc(PVOID param )
+#else
static void CALLBACK ioqueue_thread_proc( void *param )
+#endif
{
struct io_completion *completion;
struct threadpool_object *io;
IO_STATUS_BLOCK iosb;
+#ifdef __REACTOS__
+ PVOID key, value;
+#else
ULONG_PTR key, value;
+#endif
BOOL destroy, skip;
NTSTATUS status;
@@ -1581,7 +1689,11 @@ static void CALLBACK ioqueue_thread_proc( void *param )
completion =
&io->u.io.completions[io->u.io.completion_count++];
completion->iosb = iosb;
+#ifdef __REACTOS__
+ completion->cvalue = (ULONG_PTR)value;
+#else
completion->cvalue = value;
+#endif
tp_object_submit( io, FALSE );
}
@@ -1606,6 +1718,10 @@ static void CALLBACK ioqueue_thread_proc( void *param )
TRACE( "terminating I/O completion thread\n" );
RtlExitUserThread( 0 );
+
+#ifdef __REACTOS__
+ return STATUS_SUCCESS;
+#endif
}
static NTSTATUS tp_ioqueue_lock( struct threadpool_object *io, HANDLE file )
@@ -1640,8 +1756,13 @@ static NTSTATUS tp_ioqueue_lock( struct threadpool_object *io,
HANDLE file )
FILE_COMPLETION_INFORMATION info;
IO_STATUS_BLOCK iosb;
+#ifdef __REACTOS__
+ info.Port = ioqueue.port;
+ info.Key = io;
+#else
info.CompletionPort = ioqueue.port;
info.CompletionKey = (ULONG_PTR)io;
+#endif
status = NtSetInformationFile( file, &iosb, &info, sizeof(info),
FileCompletionInformation );
}
@@ -1663,7 +1784,11 @@ static NTSTATUS tp_ioqueue_lock( struct threadpool_object *io,
HANDLE file )
*/
static NTSTATUS tp_threadpool_alloc( struct threadpool **out )
{
+#ifdef __REACTOS__
+ IMAGE_NT_HEADERS *nt = RtlImageNtHeader(
NtCurrentTeb()->ProcessEnvironmentBlock->ImageBaseAddress );
+#else
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress
);
+#endif
struct threadpool *pool;
unsigned int i;
@@ -1675,8 +1800,13 @@ static NTSTATUS tp_threadpool_alloc( struct threadpool **out )
pool->objcount = 0;
pool->shutdown = FALSE;
+#ifdef __REACTOS__
+ RtlInitializeCriticalSection( &pool->cs );
+#else
RtlInitializeCriticalSectionEx( &pool->cs, 0,
RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO );
+
pool->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ":
threadpool.cs");
+#endif
for (i = 0; i < ARRAY_SIZE(pool->pools); ++i)
list_init( &pool->pools[i] );
@@ -1728,8 +1858,9 @@ static BOOL tp_threadpool_release( struct threadpool *pool )
assert( !pool->objcount );
for (i = 0; i < ARRAY_SIZE(pool->pools); ++i)
assert( list_empty( &pool->pools[i] ) );
-
+#ifndef __REACTOS__
pool->cs.DebugInfo->Spare[0] = 0;
+#endif
RtlDeleteCriticalSection( &pool->cs );
RtlFreeHeap( GetProcessHeap(), 0, pool );
@@ -1750,6 +1881,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out,
TP_CALLBACK_ENVIRON
if (environment)
{
+#ifndef __REACTOS__ //Windows 7 stuff
/* Validate environment parameters. */
if (environment->Version == 3)
{
@@ -1765,7 +1897,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out,
TP_CALLBACK_ENVIRON
return STATUS_INVALID_PARAMETER;
}
}
-
+#endif
pool = (struct threadpool *)environment->Pool;
}
@@ -1786,7 +1918,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out,
TP_CALLBACK_ENVIRON
pool = default_threadpool;
}
-
+
RtlEnterCriticalSection( &pool->cs );
/* Make sure that the threadpool has at least one thread. */
@@ -1839,8 +1971,13 @@ static NTSTATUS tp_group_alloc( struct threadpool_group **out )
group->refcount = 1;
group->shutdown = FALSE;
+#ifdef __REACTOS__
+ RtlInitializeCriticalSection( &group->cs );
+#else
RtlInitializeCriticalSectionEx( &group->cs, 0,
RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO );
+
group->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ":
threadpool_group.cs");
+#endif
list_init( &group->members );
@@ -1875,7 +2012,9 @@ static BOOL tp_group_release( struct threadpool_group *group )
assert( group->shutdown );
assert( list_empty( &group->members ) );
+#ifndef __REACTOS__
group->cs.DebugInfo->Spare[0] = 0;
+#endif
RtlDeleteCriticalSection( &group->cs );
RtlFreeHeap( GetProcessHeap(), 0, group );
@@ -1925,6 +2064,7 @@ static void tp_object_initialize( struct threadpool_object *object,
struct threa
object->finalization_callback = environment->FinalizationCallback;
object->may_run_long = environment->u.s.LongFunction != 0;
object->race_dll = environment->RaceDll;
+#ifndef __REACTOS__ //Windows 7 stuff
if (environment->Version == 3)
{
TP_CALLBACK_ENVIRON_V3 *environment_v3 = (TP_CALLBACK_ENVIRON_V3
*)environment;
@@ -1932,7 +2072,7 @@ static void tp_object_initialize( struct threadpool_object *object,
struct threa
object->priority = environment_v3->CallbackPriority;
assert( object->priority < ARRAY_SIZE(pool->pools) );
}
-
+#endif
if (environment->ActivationContext)
FIXME( "activation context not supported yet\n" );
@@ -2328,7 +2468,11 @@ skip_cleanup:
/***********************************************************************
* threadpool_worker_proc (internal)
*/
+#ifdef __REACTOS__
+ULONG NTAPI threadpool_worker_proc(PVOID param )
+#else
static void CALLBACK threadpool_worker_proc( void *param )
+#endif
{
struct threadpool *pool = param;
LARGE_INTEGER timeout;
@@ -2382,6 +2526,9 @@ static void CALLBACK threadpool_worker_proc( void *param )
TRACE( "terminating worker thread for pool %p\n", pool );
tp_threadpool_release( pool );
RtlExitUserThread( 0 );
+#ifdef __REACTOS__
+ return STATUS_SUCCESS;
+#endif
}
/***********************************************************************
@@ -3355,3 +3502,16 @@ NTSTATUS WINAPI RtlDeregisterWait(HANDLE WaitHandle)
{
return RtlDeregisterWaitEx(WaitHandle, NULL);
}
+
+#ifdef __REACTOS__
+VOID
+NTAPI
+RtlpInitializeThreadPooling(
+ VOID)
+{
+ RtlInitializeCriticalSection(&old_threadpool.threadpool_compl_cs);
+ RtlInitializeCriticalSection(&timerqueue.cs);
+ RtlInitializeCriticalSection(&waitqueue.cs);
+ RtlInitializeCriticalSection(&ioqueue.cs);
+}
+#endif
diff --git a/sdk/lib/rtl/timerqueue.c b/sdk/lib/rtl/timerqueue.c
index 596588bdafd..195059ae1ea 100644
--- a/sdk/lib/rtl/timerqueue.c
+++ b/sdk/lib/rtl/timerqueue.c
@@ -64,405 +64,6 @@ struct timer_queue
#define EXPIRE_NEVER (~(ULONGLONG) 0)
#define TIMER_QUEUE_MAGIC 0x516d6954 /* TimQ */
-static void queue_remove_timer(struct queue_timer *t)
-{
- /* We MUST hold the queue cs while calling this function. This ensures
- that we cannot queue another callback for this timer. The runcount
- being zero makes sure we don't have any already queued. */
- struct timer_queue *q = t->q;
-
- assert(t->runcount == 0);
- assert(t->destroy);
-
- list_remove(&t->entry);
- if (t->event)
- NtSetEvent(t->event, NULL);
- RtlFreeHeap(RtlGetProcessHeap(), 0, t);
-
- if (q->quit && list_empty(&q->timers))
- NtSetEvent(q->event, NULL);
-}
-
-static void timer_cleanup_callback(struct queue_timer *t)
-{
- struct timer_queue *q = t->q;
- RtlEnterCriticalSection(&q->cs);
-
- assert(0 < t->runcount);
- --t->runcount;
-
- if (t->destroy && t->runcount == 0)
- queue_remove_timer(t);
-
- RtlLeaveCriticalSection(&q->cs);
-}
-
-static VOID WINAPI timer_callback_wrapper(LPVOID p)
-{
- struct queue_timer *t = p;
- t->callback(t->param, TRUE);
- timer_cleanup_callback(t);
-}
-
-static inline ULONGLONG queue_current_time(void)
-{
- LARGE_INTEGER now, freq;
- NtQueryPerformanceCounter(&now, &freq);
- return now.QuadPart * 1000 / freq.QuadPart;
-}
-
-static void queue_add_timer(struct queue_timer *t, ULONGLONG time,
- BOOL set_event)
-{
- /* We MUST hold the queue cs while calling this function. */
- struct timer_queue *q = t->q;
- struct list *ptr = &q->timers;
-
- assert(!q->quit || (t->destroy && time == EXPIRE_NEVER));
-
- if (time != EXPIRE_NEVER)
- LIST_FOR_EACH(ptr, &q->timers)
- {
- struct queue_timer *cur = LIST_ENTRY(ptr, struct queue_timer, entry);
- if (time < cur->expire)
- break;
- }
- list_add_before(ptr, &t->entry);
-
- t->expire = time;
-
- /* If we insert at the head of the list, we need to expire sooner
- than expected. */
- if (set_event && &t->entry == list_head(&q->timers))
- NtSetEvent(q->event, NULL);
-}
-
-static inline void queue_move_timer(struct queue_timer *t, ULONGLONG time,
- BOOL set_event)
-{
- /* We MUST hold the queue cs while calling this function. */
- list_remove(&t->entry);
- queue_add_timer(t, time, set_event);
-}
-
-static void queue_timer_expire(struct timer_queue *q)
-{
- struct queue_timer *t = NULL;
-
- RtlEnterCriticalSection(&q->cs);
- if (list_head(&q->timers))
- {
- ULONGLONG now, next;
- t = LIST_ENTRY(list_head(&q->timers), struct queue_timer, entry);
- if (!t->destroy && t->expire <= ((now = queue_current_time())))
- {
- ++t->runcount;
- if (t->period)
- {
- next = t->expire + t->period;
- /* avoid trigger cascade if overloaded / hibernated */
- if (next < now)
- next = now + t->period;
- }
- else
- next = EXPIRE_NEVER;
- queue_move_timer(t, next, FALSE);
- }
- else
- t = NULL;
- }
- RtlLeaveCriticalSection(&q->cs);
-
- if (t)
- {
- if (t->flags & WT_EXECUTEINTIMERTHREAD)
- timer_callback_wrapper(t);
- else
- {
- ULONG flags
- = (t->flags
- & (WT_EXECUTEINIOTHREAD | WT_EXECUTEINPERSISTENTTHREAD
- | WT_EXECUTELONGFUNCTION | WT_TRANSFER_IMPERSONATION));
- NTSTATUS status = RtlQueueWorkItem(timer_callback_wrapper, t, flags);
- if (status != STATUS_SUCCESS)
- timer_cleanup_callback(t);
- }
- }
-}
-
-static ULONG queue_get_timeout(struct timer_queue *q)
-{
- struct queue_timer *t;
- ULONG timeout = INFINITE;
-
- RtlEnterCriticalSection(&q->cs);
- if (list_head(&q->timers))
- {
- t = LIST_ENTRY(list_head(&q->timers), struct queue_timer, entry);
- assert(!t->destroy || t->expire == EXPIRE_NEVER);
-
- if (t->expire != EXPIRE_NEVER)
- {
- ULONGLONG time = queue_current_time();
- timeout = t->expire < time ? 0 : (ULONG)(t->expire - time);
- }
- }
- RtlLeaveCriticalSection(&q->cs);
-
- return timeout;
-}
-
-static DWORD WINAPI timer_queue_thread_proc(LPVOID p)
-{
- struct timer_queue *q = p;
- ULONG timeout_ms;
-
- timeout_ms = INFINITE;
- for (;;)
- {
- LARGE_INTEGER timeout;
- NTSTATUS status;
- BOOL done = FALSE;
-
- status = NtWaitForSingleObject(
- q->event, FALSE, get_nt_timeout(&timeout, timeout_ms));
-
- if (status == STATUS_WAIT_0)
- {
- /* There are two possible ways to trigger the event. Either
- we are quitting and the last timer got removed, or a new
- timer got put at the head of the list so we need to adjust
- our timeout. */
- RtlEnterCriticalSection(&q->cs);
- if (q->quit && list_empty(&q->timers))
- done = TRUE;
- RtlLeaveCriticalSection(&q->cs);
- }
- else if (status == STATUS_TIMEOUT)
- queue_timer_expire(q);
-
- if (done)
- break;
-
- timeout_ms = queue_get_timeout(q);
- }
-
- NtClose(q->event);
- RtlDeleteCriticalSection(&q->cs);
- q->magic = 0;
- RtlFreeHeap(RtlGetProcessHeap(), 0, q);
- RtlpExitThreadFunc(STATUS_SUCCESS);
- return 0;
-}
-
-static void queue_destroy_timer(struct queue_timer *t)
-{
- /* We MUST hold the queue cs while calling this function. */
- t->destroy = TRUE;
- if (t->runcount == 0)
- /* Ensure a timer is promptly removed. If callbacks are pending,
- it will be removed after the last one finishes by the callback
- cleanup wrapper. */
- queue_remove_timer(t);
- else
- /* Make sure no destroyed timer masks an active timer at the head
- of the sorted list. */
- queue_move_timer(t, EXPIRE_NEVER, FALSE);
-}
-
-/***********************************************************************
- * RtlCreateTimerQueue (NTDLL.@)
- *
- * Creates a timer queue object and returns a handle to it.
- *
- * PARAMS
- * NewTimerQueue [O] The newly created queue.
- *
- * RETURNS
- * Success: STATUS_SUCCESS.
- * Failure: Any NTSTATUS code.
- */
-NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE NewTimerQueue)
-{
- NTSTATUS status;
- struct timer_queue *q = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof *q);
- if (!q)
- return STATUS_NO_MEMORY;
-
- RtlInitializeCriticalSection(&q->cs);
- list_init(&q->timers);
- q->quit = FALSE;
- q->magic = TIMER_QUEUE_MAGIC;
- status = NtCreateEvent(&q->event, EVENT_ALL_ACCESS, NULL,
SynchronizationEvent, FALSE);
- if (status != STATUS_SUCCESS)
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, q);
- return status;
- }
- status = RtlpStartThreadFunc(timer_queue_thread_proc, q, &q->thread);
- if (status != STATUS_SUCCESS)
- {
- NtClose(q->event);
- RtlFreeHeap(RtlGetProcessHeap(), 0, q);
- return status;
- }
-
- NtResumeThread(q->thread, NULL);
- *NewTimerQueue = q;
- return STATUS_SUCCESS;
-}
-
-/***********************************************************************
- * RtlDeleteTimerQueueEx (NTDLL.@)
- *
- * Deletes a timer queue object.
- *
- * PARAMS
- * TimerQueue [I] The timer queue to destroy.
- * CompletionEvent [I] If NULL, return immediately. If INVALID_HANDLE_VALUE,
- * wait until all timers are finished firing before
- * returning. Otherwise, return immediately and set the
- * event when all timers are done.
- *
- * RETURNS
- * Success: STATUS_SUCCESS if synchronous, STATUS_PENDING if not.
- * Failure: Any NTSTATUS code.
- */
-NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
-{
- struct timer_queue *q = TimerQueue;
- struct queue_timer *t, *temp;
- HANDLE thread;
- NTSTATUS status;
-
- if (!q || q->magic != TIMER_QUEUE_MAGIC)
- return STATUS_INVALID_HANDLE;
-
- thread = q->thread;
-
- RtlEnterCriticalSection(&q->cs);
- q->quit = TRUE;
- if (list_head(&q->timers))
- /* When the last timer is removed, it will signal the timer thread to
- exit... */
- LIST_FOR_EACH_ENTRY_SAFE(t, temp, &q->timers, struct queue_timer, entry)
- queue_destroy_timer(t);
- else
- /* However if we have none, we must do it ourselves. */
- NtSetEvent(q->event, NULL);
- RtlLeaveCriticalSection(&q->cs);
-
- if (CompletionEvent == INVALID_HANDLE_VALUE)
- {
- NtWaitForSingleObject(thread, FALSE, NULL);
- status = STATUS_SUCCESS;
- }
- else
- {
- if (CompletionEvent)
- {
- DPRINT1("asynchronous return on completion event
unimplemented\n");
- NtWaitForSingleObject(thread, FALSE, NULL);
- NtSetEvent(CompletionEvent, NULL);
- }
- status = STATUS_PENDING;
- }
-
- NtClose(thread);
- return status;
-}
-
-static struct timer_queue *get_timer_queue(HANDLE TimerQueue)
-{
- static struct timer_queue *default_timer_queue;
-
- if (TimerQueue)
- return TimerQueue;
- else
- {
- if (!default_timer_queue)
- {
- HANDLE q;
- NTSTATUS status = RtlCreateTimerQueue(&q);
- if (status == STATUS_SUCCESS)
- {
- PVOID p = InterlockedCompareExchangePointer(
- (void **) &default_timer_queue, q, NULL);
- if (p)
- /* Got beat to the punch. */
- RtlDeleteTimerQueueEx(q, NULL);
- }
- }
- return default_timer_queue;
- }
-}
-
-/***********************************************************************
- * RtlCreateTimer (NTDLL.@)
- *
- * Creates a new timer associated with the given queue.
- *
- * PARAMS
- * NewTimer [O] The newly created timer.
- * TimerQueue [I] The queue to hold the timer.
- * Callback [I] The callback to fire.
- * Parameter [I] The argument for the callback.
- * DueTime [I] The delay, in milliseconds, before first firing the
- * timer.
- * Period [I] The period, in milliseconds, at which to fire the timer
- * after the first callback. If zero, the timer will only
- * fire once. It still needs to be deleted with
- * RtlDeleteTimer.
- * Flags [I] Flags controlling the execution of the callback. In
- * addition to the WT_* thread pool flags (see
- * RtlQueueWorkItem), WT_EXECUTEINTIMERTHREAD and
- * WT_EXECUTEONLYONCE are supported.
- *
- * RETURNS
- * Success: STATUS_SUCCESS.
- * Failure: Any NTSTATUS code.
- */
-NTSTATUS WINAPI RtlCreateTimer(HANDLE TimerQueue, PHANDLE NewTimer,
- WAITORTIMERCALLBACKFUNC Callback,
- PVOID Parameter, DWORD DueTime, DWORD Period,
- ULONG Flags)
-{
- NTSTATUS status;
- struct queue_timer *t;
- struct timer_queue *q = get_timer_queue(TimerQueue);
-
- if (!q) return STATUS_NO_MEMORY;
- if (q->magic != TIMER_QUEUE_MAGIC) return STATUS_INVALID_HANDLE;
-
- t = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof *t);
- if (!t)
- return STATUS_NO_MEMORY;
-
- t->q = q;
- t->runcount = 0;
- t->callback = Callback;
- t->param = Parameter;
- t->period = Period;
- t->flags = Flags;
- t->destroy = FALSE;
- t->event = NULL;
-
- status = STATUS_SUCCESS;
- RtlEnterCriticalSection(&q->cs);
- if (q->quit)
- status = STATUS_INVALID_HANDLE;
- else
- queue_add_timer(t, queue_current_time() + DueTime, TRUE);
- RtlLeaveCriticalSection(&q->cs);
-
- if (status == STATUS_SUCCESS)
- *NewTimer = t;
- else
- RtlFreeHeap(RtlGetProcessHeap(), 0, t);
-
- return status;
-}
-
NTSTATUS
WINAPI
RtlSetTimer(
@@ -483,100 +84,6 @@ RtlSetTimer(
Flags);
}
-/***********************************************************************
- * RtlUpdateTimer (NTDLL.@)
- *
- * Changes the time at which a timer expires.
- *
- * PARAMS
- * TimerQueue [I] The queue that holds the timer.
- * Timer [I] The timer to update.
- * DueTime [I] The delay, in milliseconds, before next firing the timer.
- * Period [I] The period, in milliseconds, at which to fire the timer
- * after the first callback. If zero, the timer will not
- * refire once. It still needs to be deleted with
- * RtlDeleteTimer.
- *
- * RETURNS
- * Success: STATUS_SUCCESS.
- * Failure: Any NTSTATUS code.
- */
-NTSTATUS WINAPI RtlUpdateTimer(HANDLE TimerQueue, HANDLE Timer,
- DWORD DueTime, DWORD Period)
-{
- struct queue_timer *t = Timer;
- struct timer_queue *q = t->q;
-
- RtlEnterCriticalSection(&q->cs);
- /* Can't change a timer if it was once-only or destroyed. */
- if (t->expire != EXPIRE_NEVER)
- {
- t->period = Period;
- queue_move_timer(t, queue_current_time() + DueTime, TRUE);
- }
- RtlLeaveCriticalSection(&q->cs);
-
- return STATUS_SUCCESS;
-}
-
-/***********************************************************************
- * RtlDeleteTimer (NTDLL.@)
- *
- * Cancels a timer-queue timer.
- *
- * PARAMS
- * TimerQueue [I] The queue that holds the timer.
- * Timer [I] The timer to update.
- * CompletionEvent [I] If NULL, return immediately. If INVALID_HANDLE_VALUE,
- * wait until the timer is finished firing all pending
- * callbacks before returning. Otherwise, return
- * immediately and set the timer is done.
- *
- * RETURNS
- * Success: STATUS_SUCCESS if the timer is done, STATUS_PENDING if not,
- or if the completion event is NULL.
- * Failure: Any NTSTATUS code.
- */
-NTSTATUS WINAPI RtlDeleteTimer(HANDLE TimerQueue, HANDLE Timer,
- HANDLE CompletionEvent)
-{
- struct queue_timer *t = Timer;
- struct timer_queue *q;
- NTSTATUS status = STATUS_PENDING;
- HANDLE event = NULL;
-
- if (!Timer)
- return STATUS_INVALID_PARAMETER_1;
- q = t->q;
- if (CompletionEvent == INVALID_HANDLE_VALUE)
- {
- status = NtCreateEvent(&event, EVENT_ALL_ACCESS, NULL, SynchronizationEvent,
FALSE);
- if (status == STATUS_SUCCESS)
- status = STATUS_PENDING;
- }
- else if (CompletionEvent)
- event = CompletionEvent;
-
- RtlEnterCriticalSection(&q->cs);
- t->event = event;
- if (t->runcount == 0 && event)
- status = STATUS_SUCCESS;
- queue_destroy_timer(t);
- RtlLeaveCriticalSection(&q->cs);
-
- if (CompletionEvent == INVALID_HANDLE_VALUE && event)
- {
- if (status == STATUS_PENDING)
- {
- NtWaitForSingleObject(event, FALSE, NULL);
- status = STATUS_SUCCESS;
- }
- NtClose(event);
- }
-
- return status;
-}
-
/*
* @implemented
*/
diff --git a/sdk/lib/rtl/wait.c b/sdk/lib/rtl/wait.c
deleted file mode 100644
index bab26365d5c..00000000000
--- a/sdk/lib/rtl/wait.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * PURPOSE: Rtl user wait functions
- * FILE: lib/rtl/wait.c
- * PROGRAMERS:
- * Alex Ionescu (alex(a)relsoft.net)
- * Eric Kohl
- * KJK::Hyperion
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <rtl.h>
-
-#define NDEBUG
-#include <debug.h>
-
-typedef struct _RTLP_WAIT
-{
- HANDLE Object;
- BOOLEAN CallbackInProgress;
- HANDLE CancelEvent;
- LONG DeleteCount;
- HANDLE CompletionEvent;
- ULONG Flags;
- WAITORTIMERCALLBACKFUNC Callback;
- PVOID Context;
- ULONG Milliseconds;
-} RTLP_WAIT, *PRTLP_WAIT;
-
-/* PRIVATE FUNCTIONS *******************************************************/
-
-static inline PLARGE_INTEGER get_nt_timeout( PLARGE_INTEGER pTime, ULONG timeout )
-{
- if (timeout == INFINITE) return NULL;
- pTime->QuadPart = (ULONGLONG)timeout * -10000;
- return pTime;
-}
-
-static VOID
-NTAPI
-Wait_thread_proc(LPVOID Arg)
-{
- PRTLP_WAIT Wait = (PRTLP_WAIT) Arg;
- NTSTATUS Status;
- BOOLEAN alertable = (Wait->Flags & WT_EXECUTEINIOTHREAD) != 0;
- HANDLE handles[2] = { Wait->CancelEvent, Wait->Object };
- LARGE_INTEGER timeout;
- HANDLE completion_event;
-
-// TRACE("\n");
-
- while (TRUE)
- {
- Status = NtWaitForMultipleObjects( 2,
- handles,
- WaitAny,
- alertable,
- get_nt_timeout( &timeout,
Wait->Milliseconds ) );
-
- if (Status == STATUS_WAIT_1 || Status == STATUS_TIMEOUT)
- {
- BOOLEAN TimerOrWaitFired;
-
- if (Status == STATUS_WAIT_1)
- {
- // TRACE( "object %p signaled, calling callback %p with context
%p\n",
- // Wait->Object, Wait->Callback,
- // Wait->Context );
- TimerOrWaitFired = FALSE;
- }
- else
- {
- // TRACE( "wait for object %p timed out, calling callback %p with
context %p\n",
- // Wait->Object, Wait->Callback,
- // Wait->Context );
- TimerOrWaitFired = TRUE;
- }
- Wait->CallbackInProgress = TRUE;
- Wait->Callback( Wait->Context, TimerOrWaitFired );
- Wait->CallbackInProgress = FALSE;
-
- if (Wait->Flags & WT_EXECUTEONLYONCE)
- break;
- }
- else if (Status != STATUS_USER_APC)
- break;
- }
-
- completion_event = Wait->CompletionEvent;
- if (completion_event) NtSetEvent( completion_event, NULL );
-
- if (InterlockedIncrement( &Wait->DeleteCount ) == 2 )
- {
- NtClose( Wait->CancelEvent );
- RtlFreeHeap( RtlGetProcessHeap(), 0, Wait );
- }
-}
-
-
-/* FUNCTIONS ***************************************************************/
-
-
-/***********************************************************************
- * RtlRegisterWait
- *
- * 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
-NTAPI
-RtlRegisterWait(PHANDLE NewWaitObject,
- HANDLE Object,
- WAITORTIMERCALLBACKFUNC Callback,
- PVOID Context,
- ULONG Milliseconds,
- ULONG Flags)
-{
- PRTLP_WAIT Wait;
- NTSTATUS Status;
-
- //TRACE( "(%p, %p, %p, %p, %d, 0x%x)\n", NewWaitObject, Object, Callback,
Context, Milliseconds, Flags );
-
- Wait = RtlAllocateHeap( RtlGetProcessHeap(), 0, sizeof(RTLP_WAIT) );
- if (!Wait)
- return STATUS_NO_MEMORY;
-
- Wait->Object = Object;
- Wait->Callback = Callback;
- Wait->Context = Context;
- Wait->Milliseconds = Milliseconds;
- Wait->Flags = Flags;
- Wait->CallbackInProgress = FALSE;
- Wait->DeleteCount = 0;
- Wait->CompletionEvent = NULL;
-
- Status = NtCreateEvent( &Wait->CancelEvent,
- EVENT_ALL_ACCESS,
- NULL,
- NotificationEvent,
- FALSE );
-
- if (Status != STATUS_SUCCESS)
- {
- RtlFreeHeap( RtlGetProcessHeap(), 0, Wait );
- return Status;
- }
-
- Flags = Flags & (WT_EXECUTEINIOTHREAD | WT_EXECUTEINPERSISTENTTHREAD |
- WT_EXECUTELONGFUNCTION | WT_TRANSFER_IMPERSONATION);
-
- Status = RtlQueueWorkItem( Wait_thread_proc,
- Wait,
- Flags );
-
- if (Status != STATUS_SUCCESS)
- {
- NtClose( Wait->CancelEvent );
- RtlFreeHeap( RtlGetProcessHeap(), 0, Wait );
- return Status;
- }
-
- *NewWaitObject = Wait;
- return Status;
-}
-
-/***********************************************************************
- * RtlDeregisterWaitEx
- *
- * 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
-NTAPI
-RtlDeregisterWaitEx(HANDLE WaitHandle,
- HANDLE CompletionEvent)
-{
- PRTLP_WAIT Wait = (PRTLP_WAIT) WaitHandle;
- NTSTATUS Status = STATUS_SUCCESS;
-
- //TRACE( "(%p)\n", WaitHandle );
-
- NtSetEvent( Wait->CancelEvent, NULL );
- if (Wait->CallbackInProgress)
- {
- if (CompletionEvent != NULL)
- {
- if (CompletionEvent == INVALID_HANDLE_VALUE)
- {
- Status = NtCreateEvent( &CompletionEvent,
- EVENT_ALL_ACCESS,
- NULL,
- NotificationEvent,
- FALSE );
-
- if (Status != STATUS_SUCCESS)
- return Status;
-
- (void)InterlockedExchangePointer( &Wait->CompletionEvent,
CompletionEvent );
-
- if (Wait->CallbackInProgress)
- NtWaitForSingleObject( CompletionEvent, FALSE, NULL );
-
- NtClose( CompletionEvent );
- }
- else
- {
- (void)InterlockedExchangePointer( &Wait->CompletionEvent,
CompletionEvent );
-
- if (Wait->CallbackInProgress)
- Status = STATUS_PENDING;
- }
- }
- else
- Status = STATUS_PENDING;
- }
-
- if (InterlockedIncrement( &Wait->DeleteCount ) == 2 )
- {
- Status = STATUS_SUCCESS;
- NtClose( Wait->CancelEvent );
- RtlFreeHeap( RtlGetProcessHeap(), 0, Wait );
- }
-
- return Status;
-}
-
-/***********************************************************************
- * RtlDeregisterWait
- *
- * 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
-NTAPI
-RtlDeregisterWait(HANDLE WaitHandle)
-{
- return RtlDeregisterWaitEx(WaitHandle, NULL);
-}
-
-/* EOF */