Author: ion
Date: Sun Feb 19 06:32:17 2012
New Revision: 55698
URL:
http://svn.reactos.org/svn/reactos?rev=55698&view=rev
Log:
[CSRSRV]: Switch to the CSRSRV2 model of having a dynamic amount of threads handling CSRSS
requests depending on how many are deadlocked, instead of creating a thread for every
single client. CSRSRV now has about 2 API threads instead of 16.
Modified:
trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c
trunk/reactos/subsystems/win32/csrss/csrsrv/init.c
trunk/reactos/subsystems/win32/csrss/csrsrv/session.c
trunk/reactos/subsystems/win32/csrss/include/api.h
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csr…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c [iso-8859-1] Sun Feb 19
06:32:17 2012
@@ -20,6 +20,9 @@
static unsigned ApiDefinitionsCount = 0;
static PCSRSS_API_DEFINITION ApiDefinitions = NULL;
UNICODE_STRING CsrApiPortName;
+volatile LONG CsrpStaticThreadCount;
+volatile LONG CsrpDynamicThreadTotal;
+ULONG CsrMaxApiRequestThreads;
/* FUNCTIONS *****************************************************************/
@@ -290,7 +293,7 @@
NULL /* FIXME*/);
/* Create the Port Object */
- Status = NtCreatePort(&hApiPort, //&CsrApiPort,
+ Status = NtCreatePort(&CsrApiPort,
&ObjectAttributes,
LPC_MAX_DATA_LENGTH, // hack
LPC_MAX_MESSAGE_LENGTH, // hack
@@ -741,10 +744,10 @@
CsrpHandleConnectionRequest (PPORT_MESSAGE Request)
{
NTSTATUS Status;
- HANDLE ServerPort = NULL, ServerThread = NULL;
+ HANDLE ServerPort = NULL;//, ServerThread = NULL;
PCSR_PROCESS ProcessData = NULL;
REMOTE_PORT_VIEW RemotePortView;
- CLIENT_ID ClientId;
+// CLIENT_ID ClientId;
BOOLEAN AllowConnection = FALSE;
PCSR_CONNECTION_INFO ConnectInfo;
ServerPort = NULL;
@@ -836,7 +839,7 @@
Request->ClientId.UniqueProcess,
Request->ClientId.UniqueThread);
}
-
+#if 0
if (!NT_SUCCESS(Status)) return Status;
Status = RtlCreateUserThread(NtCurrentProcess(),
@@ -863,6 +866,7 @@
Status = STATUS_SUCCESS;
DPRINT("CSR: %s done\n", __FUNCTION__);
+#endif
return Status;
}
@@ -911,6 +915,83 @@
/* Return it */
return CsrThread;
+}
+
+/*++
+ * @name CsrpCheckRequestThreads
+ *
+ * The CsrpCheckRequestThreads routine checks if there are no more threads
+ * to handle CSR API Requests, and creates a new thread if possible, to
+ * avoid starvation.
+ *
+ * @param None.
+ *
+ * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
+ * if a new thread couldn't be created.
+ *
+ * @remarks None.
+ *
+ *--*/
+NTSTATUS
+NTAPI
+CsrpCheckRequestThreads(VOID)
+{
+ HANDLE hThread;
+ CLIENT_ID ClientId;
+ NTSTATUS Status;
+
+ /* Decrease the count, and see if we're out */
+ if (!(_InterlockedDecrement(&CsrpStaticThreadCount)))
+ {
+ /* Check if we've still got space for a Dynamic Thread */
+ if (CsrpDynamicThreadTotal < CsrMaxApiRequestThreads)
+ {
+ /* Create a new dynamic thread */
+ Status = RtlCreateUserThread(NtCurrentProcess(),
+ NULL,
+ TRUE,
+ 0,
+ 0,
+ 0,
+
(PVOID)ClientConnectionThread,//CsrApiRequestThread,
+ NULL,
+ &hThread,
+ &ClientId);
+ /* Check success */
+ if (NT_SUCCESS(Status))
+ {
+ /* Increase the thread counts */
+ _InterlockedIncrement(&CsrpStaticThreadCount);
+ _InterlockedIncrement(&CsrpDynamicThreadTotal);
+
+ /* Add a new server thread */
+ if (CsrAddStaticServerThread(hThread,
+ &ClientId,
+ CsrThreadIsServerThread))
+ {
+ /* Activate it */
+ NtResumeThread(hThread, NULL);
+ }
+ else
+ {
+ /* Failed to create a new static thread */
+ _InterlockedDecrement(&CsrpStaticThreadCount);
+ _InterlockedDecrement(&CsrpDynamicThreadTotal);
+
+ /* Terminate it */
+ DPRINT1("Failing\n");
+ NtTerminateThread(hThread, 0);
+ NtClose(hThread);
+
+ /* Return */
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+ }
+ }
+
+ /* Success */
+ return STATUS_SUCCESS;
}
VOID
@@ -926,12 +1007,13 @@
PCSR_PROCESS ProcessData;
PCSR_THREAD ServerThread;
ULONG MessageType;
+ HANDLE ReplyPort;
DPRINT("CSR: %s called\n", __FUNCTION__);
/* Setup LPC loop port and message */
Reply = NULL;
-// ReplyPort = CsrApiPort;
+ ReplyPort = CsrApiPort;
/* Connect to user32 */
while (!CsrConnectToUser())
@@ -955,8 +1037,8 @@
ASSERT(NT_SUCCESS(Status));
/* Increase the Thread Counts */
- //_InterlockedIncrement(&CsrpStaticThreadCount);
- //_InterlockedIncrement(&CsrpDynamicThreadTotal);
+ _InterlockedIncrement(&CsrpStaticThreadCount);
+ _InterlockedIncrement(&CsrpDynamicThreadTotal);
}
/* Now start the loop */
@@ -976,7 +1058,8 @@
}
/* Send the reply and wait for a new request */
- Status = NtReplyWaitReceivePort(hApiPort,
+ DPRINT("Replying to: %lx (%lx)\n", ReplyPort, CsrApiPort);
+ Status = NtReplyWaitReceivePort(ReplyPort,
0,
&Reply->Header,
&Request->Header);
@@ -988,17 +1071,18 @@
{
/* Check for specific status cases */
if ((Status != STATUS_INVALID_CID) &&
- (Status != STATUS_UNSUCCESSFUL))// &&
-// ((Status == STATUS_INVALID_HANDLE) || (ReplyPort == CsrApiPort)))
+ (Status != STATUS_UNSUCCESSFUL) &&
+ ((Status == STATUS_INVALID_HANDLE) || (ReplyPort == CsrApiPort)))
{
/* Notify the debugger */
DPRINT1("CSRSS: ReceivePort failed - Status == %X\n",
Status);
- //DPRINT1("CSRSS: ReplyPortHandle %lx CsrApiPort %lx\n",
ReplyPort, CsrApiPort);
+ DPRINT1("CSRSS: ReplyPortHandle %lx CsrApiPort %lx\n",
ReplyPort, CsrApiPort);
}
/* We failed big time, so start out fresh */
Reply = NULL;
- //ReplyPort = CsrApiPort;
+ ReplyPort = CsrApiPort;
+ DPRINT1("failed: %lx\n", Status);
continue;
}
else
@@ -1020,13 +1104,17 @@
{
DPRINT("Port died, oh well\n");
CsrFreeProcessData( Request->Header.ClientId.UniqueProcess );
- break;
+ Reply = NULL;
+ ReplyPort = CsrApiPort;
+ continue;
}
if (MessageType == LPC_CONNECTION_REQUEST)
{
+ DPRINT("Accepting new connection\n");
CsrpHandleConnectionRequest((PPORT_MESSAGE)Request);
Reply = NULL;
+ ReplyPort = CsrApiPort;
continue;
}
@@ -1034,6 +1122,7 @@
{
DPRINT("Client died, oh well\n");
Reply = NULL;
+ ReplyPort = CsrApiPort;
continue;
}
@@ -1042,6 +1131,7 @@
{
DPRINT1("CSR: received message %d\n",
Request->Header.u2.s2.Type);
Reply = NULL;
+ ReplyPort = CsrApiPort;
continue;
}
@@ -1056,12 +1146,16 @@
DPRINT1("Message %d: Unable to find data for process 0x%x\n",
MessageType,
Request->Header.ClientId.UniqueProcess);
- break;
+ Reply = NULL;
+ ReplyPort = CsrApiPort;
+ continue;
}
if (ProcessData->Flags & CsrProcessTerminated)
{
DPRINT1("Message %d: process %d already terminated\n",
Request->Type, Request->Header.ClientId.UniqueProcess);
+ Reply = NULL;
+ ReplyPort = CsrApiPort;
continue;
}
@@ -1072,20 +1166,61 @@
PCSR_THREAD Thread;
Thread = CsrLocateThreadByClientId(NULL, &Request->Header.ClientId);
CsrHandleHardError(Thread, (PHARDERROR_MSG)Request);
+ ReplyPort = CsrApiPort;
}
else
{
PCSR_THREAD Thread;
PCSR_PROCESS Process = NULL;
- //DPRINT1("locate thread %lx/%lx\n",
Request->Header.ClientId.UniqueProcess, Request->Header.ClientId.UniqueThread);
- Thread = CsrLocateThreadByClientId(&Process,
&Request->Header.ClientId);
- //DPRINT1("Thread found: %p %p\n", Thread, Process);
-
- /* Call the Handler */
- if (Thread) NtCurrentTeb()->CsrClientThread = Thread;
- CsrApiCallHandler(ProcessData, Request);
- if (Thread) NtCurrentTeb()->CsrClientThread = ServerThread;
+ /* Validation complete, start SEH */
+ _SEH2_TRY
+ {
+ /* Make sure we have enough threads */
+ CsrpCheckRequestThreads();
+
+ //DPRINT1("locate thread %lx/%lx\n",
Request->Header.ClientId.UniqueProcess, Request->Header.ClientId.UniqueThread);
+ Thread = CsrLocateThreadByClientId(&Process,
&Request->Header.ClientId);
+ if (!Thread)
+ {
+ DPRINT("No thread found for request %lx and clientID
%lx.%lx\n",
+ Request->Type & 0xFFFF,
+ Request->Header.ClientId.UniqueProcess,
+ Request->Header.ClientId.UniqueThread);
+ }
+ //DPRINT1("Thread found: %p %p\n", Thread, Process);
+
+ if (Thread) NtCurrentTeb()->CsrClientThread = Thread;
+
+ /* Now we reply to a particular client */
+ if (Thread)
+ {
+ ReplyPort = Thread->Process->ClientPort;
+ ASSERT(Thread->Process == ProcessData);
+ }
+ else
+ {
+ ReplyPort = ProcessData->ClientPort;
+ }
+
+ /* Call the Handler */
+ CsrApiCallHandler(ProcessData, Request);
+
+ /* Increase the static thread count */
+ _InterlockedIncrement(&CsrpStaticThreadCount);
+
+ if (Thread)
+ {
+ NtCurrentTeb()->CsrClientThread = ServerThread;
+ CsrDereferenceThread(Thread);
+ }
+ }
+ _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation()))
+ {
+ Reply = NULL;
+ ReplyPort = CsrApiPort;
+ }
+ _SEH2_END;
}
/* Send back the reply */
@@ -1095,7 +1230,7 @@
/* Close the port and exit the thread */
// NtClose(ServerPort);
- DPRINT("CSR: %s done\n", __FUNCTION__);
+ DPRINT1("CSR: %s done\n", __FUNCTION__);
/* We're out of the loop for some reason, terminate! */
NtTerminateThread(NtCurrentThread(), Status);
//return Status;
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/init.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csr…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/csrsrv/init.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/csrsrv/init.c [iso-8859-1] Sun Feb 19 06:32:17
2012
@@ -22,7 +22,7 @@
PCSR_THREAD CsrSbApiRequestThreadPtr;
HANDLE CsrSmApiPort;
HANDLE hSbApiPort = (HANDLE) 0;
-HANDLE hApiPort = (HANDLE) 0;
+HANDLE CsrApiPort = (HANDLE) 0;
ULONG CsrDebug = 0xFFFFFFFF;
ULONG CsrMaxApiRequestThreads;
ULONG CsrTotalPerProcessDataLength;
@@ -1098,7 +1098,7 @@
NtClose(CsrInitializationEvent);
/* Have us handle Hard Errors */
- Status = NtSetDefaultHardErrorPort(hApiPort);
+ Status = NtSetDefaultHardErrorPort(CsrApiPort);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed
(Status=%08lx)\n",
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/session.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csr…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/csrsrv/session.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/csrsrv/session.c [iso-8859-1] Sun Feb 19 06:32:17
2012
@@ -231,7 +231,7 @@
/* Set the exception port */
Status = NtSetInformationProcess(hProcess,
ProcessExceptionPort,
- &hApiPort,//&CsrApiPort,
+ &CsrApiPort,
sizeof(HANDLE));
/* Check for success */
Modified: trunk/reactos/subsystems/win32/csrss/include/api.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/inc…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/include/api.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/include/api.h [iso-8859-1] Sun Feb 19 06:32:17
2012
@@ -299,7 +299,7 @@
NTAPI
CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage);
-extern HANDLE hApiPort;
+extern HANDLE CsrApiPort;
extern HANDLE CsrSmApiPort;
extern HANDLE CsrSbApiPort;
extern LIST_ENTRY CsrThreadHashTable[256];
@@ -313,6 +313,7 @@
extern PVOID *CsrSrvSharedStaticServerData;
extern HANDLE CsrInitializationEvent;
extern PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX];
+extern ULONG CsrMaxApiRequestThreads;
NTSTATUS
NTAPI
@@ -386,6 +387,10 @@
IN OUT PULONG Reply
);
+LONG
+NTAPI
+CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo);
+
VOID
NTAPI
CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess);