diff --git a/reactos/dll/ntdll/def/ntdll.pspec b/reactos/dll/ntdll/def/ntdll.pspec index 7eb3e5519e9..0ce536711f4 100644 --- a/reactos/dll/ntdll/def/ntdll.pspec +++ b/reactos/dll/ntdll/def/ntdll.pspec @@ -896,7 +896,7 @@ //@ stdcall RtlSetSecurityObjectEx //@ stdcall RtlSetThreadErrorMode @ stdcall RtlSetThreadIsCritical(long ptr long) -//@ stdcall RtlSetThreadPoolStartFunc +@ stdcall RtlSetThreadPoolStartFunc(ptr ptr) @ stdcall RtlSetTimeZoneInformation(ptr) //@ stdcall RtlSetTimer @ stdcall RtlSetUnhandledExceptionFilter(ptr) diff --git a/reactos/dll/ntdll/def/ntdll.spec b/reactos/dll/ntdll/def/ntdll.spec index 3464847710f..9a9deff0689 100644 --- a/reactos/dll/ntdll/def/ntdll.spec +++ b/reactos/dll/ntdll/def/ntdll.spec @@ -896,7 +896,7 @@ ;@ stdcall RtlSetSecurityObjectEx ;@ stdcall RtlSetThreadErrorMode @ stdcall RtlSetThreadIsCritical(long ptr long) -;@ stdcall RtlSetThreadPoolStartFunc +@ stdcall RtlSetThreadPoolStartFunc(ptr ptr) @ stdcall RtlSetTimeZoneInformation(ptr) ;@ stdcall RtlSetTimer @ stdcall RtlSetUnhandledExceptionFilter(ptr) diff --git a/reactos/dll/win32/kernel32/client/dllmain.c b/reactos/dll/win32/kernel32/client/dllmain.c index b0068fefe00..0b34785c9bb 100644 --- a/reactos/dll/win32/kernel32/client/dllmain.c +++ b/reactos/dll/win32/kernel32/client/dllmain.c @@ -220,6 +220,46 @@ BasepInitConsole(VOID) return TRUE; } +NTSTATUS +NTAPI +BaseCreateThreadPoolThread(IN PTHREAD_START_ROUTINE Function, + IN PVOID Parameter, + OUT PHANDLE ThreadHandle) +{ + NTSTATUS Status; + + /* Create a Win32 thread */ + *ThreadHandle = CreateRemoteThread(NtCurrentProcess(), + NULL, + 0, + Function, + Parameter, + CREATE_SUSPENDED, + NULL); + if (!(*ThreadHandle)) + { + /* Get the status value if we couldn't get a handle */ + Status = NtCurrentTeb()->LastStatusValue; + if (NT_SUCCESS(Status)) Status = STATUS_UNSUCCESSFUL; + } + else + { + /* Set success code */ + Status = STATUS_SUCCESS; + } + + /* All done */ + return Status; +} + +NTSTATUS +NTAPI +BaseExitThreadPoolThread(IN NTSTATUS ExitStatus) +{ + /* Exit the thread */ + ExitThread(ExitStatus); +} + BOOL WINAPI DllMain(HANDLE hDll, @@ -246,6 +286,9 @@ DllMain(HANDLE hDll, /* Set no filter intially */ GlobalTopLevelExceptionFilter = RtlEncodePointer(NULL); + + /* Enable the Rtl thread pool and timer queue to use proper Win32 thread */ + RtlSetThreadPoolStartFunc(BaseCreateThreadPoolThread, BaseExitThreadPoolThread); /* Don't bother us for each thread */ LdrDisableThreadCalloutsForDll((PVOID)hDll); diff --git a/reactos/dll/win32/kernel32/client/proc.c b/reactos/dll/win32/kernel32/client/proc.c index b3e200ea194..9bc61f5bf63 100644 --- a/reactos/dll/win32/kernel32/client/proc.c +++ b/reactos/dll/win32/kernel32/client/proc.c @@ -544,7 +544,7 @@ BasepNotifyCsrOfThread(IN HANDLE ThreadHandle, sizeof(CSR_API_MESSAGE)); if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status)) { - DPRINT1("Failed to tell csrss about new thread\n"); + DPRINT1("Failed to tell csrss about new thread: %lx %lx\n", Status, CsrRequest.Status); return CsrRequest.Status; } diff --git a/reactos/include/ndk/rtlfuncs.h b/reactos/include/ndk/rtlfuncs.h index 235c2d836e7..39b5b23fec3 100644 --- a/reactos/include/ndk/rtlfuncs.h +++ b/reactos/include/ndk/rtlfuncs.h @@ -2410,6 +2410,14 @@ RtlGetCurrentProcessorNumber( // // Thread Pool Functions // +// +NTSTATUS +NTAPI +RtlSetThreadPoolStartFunc( + IN PRTL_START_POOL_THREAD StartPoolThread, + IN PRTL_EXIT_POOL_THREAD ExitPoolThread +); + NTSYSAPI NTSTATUS NTAPI diff --git a/reactos/include/ndk/rtltypes.h b/reactos/include/ndk/rtltypes.h index 198af634e52..ac08f574bff 100644 --- a/reactos/include/ndk/rtltypes.h +++ b/reactos/include/ndk/rtltypes.h @@ -522,6 +522,21 @@ typedef VOID PVOID Parameter ); +// +// Worker Start/Exit Function +// +typedef NTSTATUS +(NTAPI *PRTL_START_POOL_THREAD)( + IN PTHREAD_START_ROUTINE Function, + IN PVOID Parameter, + OUT PHANDLE ThreadHandle +); + +typedef NTSTATUS +(NTAPI *PRTL_EXIT_POOL_THREAD)( + IN NTSTATUS ExitStatus +); + // // Declare empty structure definitions so that they may be referenced by // routines before they are defined diff --git a/reactos/lib/rtl/timerqueue.c b/reactos/lib/rtl/timerqueue.c index 8e4821be902..6174d7bc2f7 100644 --- a/reactos/lib/rtl/timerqueue.c +++ b/reactos/lib/rtl/timerqueue.c @@ -19,6 +19,8 @@ /* FUNCTIONS ***************************************************************/ +extern PRTL_START_POOL_THREAD RtlpStartThreadFunc; +extern PRTL_EXIT_POOL_THREAD RtlpExitThreadFunc; HANDLE TimerThreadHandle = NULL; NTSTATUS @@ -239,7 +241,7 @@ static void WINAPI timer_queue_thread_proc(LPVOID p) NtClose(q->event); RtlDeleteCriticalSection(&q->cs); RtlFreeHeap(RtlGetProcessHeap(), 0, q); - RtlExitUserThread(STATUS_SUCCESS); + RtlpExitThreadFunc(STATUS_SUCCESS); } static void queue_destroy_timer(struct queue_timer *t) @@ -285,8 +287,7 @@ NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE NewTimerQueue) RtlFreeHeap(RtlGetProcessHeap(), 0, q); return status; } - status = RtlCreateUserThread(NtCurrentProcess(), NULL, FALSE, 0, 0, 0, - (PTHREAD_START_ROUTINE)timer_queue_thread_proc, q, &q->thread, NULL); + status = RtlpStartThreadFunc((PVOID)timer_queue_thread_proc, q, &q->thread); if (status != STATUS_SUCCESS) { NtClose(q->event); @@ -294,6 +295,7 @@ NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE NewTimerQueue) return status; } + NtResumeThread(q->thread, NULL); *NewTimerQueue = q; return STATUS_SUCCESS; } diff --git a/reactos/lib/rtl/workitem.c b/reactos/lib/rtl/workitem.c index cb6c83ab35a..f33771351dd 100644 --- a/reactos/lib/rtl/workitem.c +++ b/reactos/lib/rtl/workitem.c @@ -15,6 +15,36 @@ /* FUNCTIONS ***************************************************************/ +NTSTATUS +NTAPI +RtlpStartThread(IN PTHREAD_START_ROUTINE Function, + IN PVOID Parameter, + OUT PHANDLE ThreadHandle) +{ + /* Create a native worker thread -- used for SMSS, CSRSS, etc... */ + return RtlCreateUserThread(NtCurrentProcess(), + NULL, + TRUE, + 0, + 0, + 0, + Function, + Parameter, + ThreadHandle, + NULL); +} + +NTSTATUS +NTAPI +RtlpExitThread(IN NTSTATUS ExitStatus) +{ + /* Kill a native worker thread -- used for SMSS, CSRSS, etc... */ + return NtTerminateThread(NtCurrentThread(), ExitStatus); +} + +PRTL_START_POOL_THREAD RtlpStartThreadFunc = RtlpStartThread; +PRTL_EXIT_POOL_THREAD RtlpExitThreadFunc = RtlpExitThread; + #define MAX_WORKERTHREADS 0x100 #define WORKERTHREAD_CREATION_THRESHOLD 0x5 @@ -141,19 +171,11 @@ RtlpStartWorkerThread(PTHREAD_START_ROUTINE StartRoutine) Timeout.QuadPart = -10000LL; /* Wait for 100ms */ /* Start the thread */ - Status = RtlCreateUserThread(NtCurrentProcess(), - NULL, - FALSE, - 0, - 0, - 0, - StartRoutine, - (PVOID)&WorkerInitialized, - &ThreadHandle, - NULL); - + Status = RtlpStartThreadFunc(StartRoutine, (PVOID)&WorkerInitialized, &ThreadHandle); if (NT_SUCCESS(Status)) { + NtResumeThread(ThreadHandle, NULL); + /* Poll until the thread got a chance to initialize */ while (WorkerInitialized == 0) { @@ -568,7 +590,7 @@ InitFailed: InterlockedExchange((PLONG)Parameter, 1); - RtlExitUserThread(Status); + RtlpExitThreadFunc(Status); return 0; } @@ -647,7 +669,7 @@ Wait: } NtClose(ThreadInfo.ThreadHandle); - RtlExitUserThread(Status); + RtlpExitThreadFunc(Status); return 0; } @@ -670,7 +692,7 @@ RtlpWorkerThreadProc(IN PVOID Parameter) 1); /* Oops, too many worker threads... */ - RtlExitUserThread(Status); + RtlpExitThreadFunc(Status); return 0; } @@ -743,7 +765,7 @@ RtlpWorkerThreadProc(IN PVOID Parameter) } } - RtlExitUserThread(Status); + RtlpExitThreadFunc(Status); return 0; } @@ -892,3 +914,16 @@ RtlSetIoCompletionCallback(IN HANDLE FileHandle, UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; } + +/* + * @implemented + */ +NTSTATUS +NTAPI +RtlSetThreadPoolStartFunc(IN PRTL_START_POOL_THREAD StartPoolThread, + IN PRTL_EXIT_POOL_THREAD ExitPoolThread) +{ + RtlpStartThreadFunc = StartPoolThread; + RtlpExitThreadFunc = ExitPoolThread; + return STATUS_SUCCESS; +}