mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 12:23:31 +00:00
[RTL/NTDLL/KERNEL32]: Rtl provides worker queue and timer queue functionality, which queues a worker thread associated with a caller-supplied callback. In Windows, Rtl by default calls RtlCreateUserThread, but as soon as kernel32 loads, it's DllMain calls an exported function RtlSetThreadPoolStartFunc which changes that default to a special Base function that calls CreateRemoteThread instead. The net result is that Win32 processes using the Rtl functionality get their threads properly registered with CSRSS. In ReactOS, this did not happen, so when those threads called into CSRSS, CSRSS had no CSR_THREAD structure/state for them, which is why CsrCreateThread (and the API loop) are so badly hacked. This commit implements RtlSetThreadPoolStartFunc, implements the kernel32 base functions which wrap CreateRemoteThread, and implements the rtl functions which wrap RtlCreateUserThread. Services, Setup, and any ReactOS application using RPC now have the worker threads correctly registered.
svn path=/trunk/; revision=55706
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+50
-15
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user