[CONSRV]
[reactos.git] / subsystems / win32 / csrsrv / thredsup.c
index 72566f8..d7238d2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS CSR SubSystem
- * FILE:            subsystems/win32/csrss/csrsrv/thredsup.c
+ * PROJECT:         ReactOS Client/Server Runtime SubSystem
+ * FILE:            subsystems/win32/csrsrv/thredsup.c
  * PURPOSE:         CSR Server DLL Thread Management
  * PROGRAMMERS:     ReactOS Portable Systems Group
  *                  Alex Ionescu (alex@relsoft.net)
@@ -123,11 +123,11 @@ CsrAllocateThread(IN PCSR_PROCESS CsrProcess)
 
     /* Allocate the structure */
     CsrThread = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, sizeof(CSR_THREAD));
-    if (!CsrThread) return(NULL);
+    if (!CsrThread) return NULL;
 
     /* Reference the Thread and Process */
-    CsrThread->ReferenceCount++;
-    CsrProcess->ReferenceCount++;
+    CsrLockedReferenceThread(CsrThread);
+    CsrLockedReferenceProcess(CsrProcess);
 
     /* Set the Parent Process */
     CsrThread->Process = CsrProcess;
@@ -201,9 +201,13 @@ CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL,
         /* Get the thread */
         FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks);
 
+        /* Move to the next entry */
+        NextEntry = NextEntry->Flink;
+
         /* Compare the CID */
-        // FIXME: if (*(PULONGLONG)&FoundThread->ClientId == *(PULONGLONG)ClientId)
-        if (FoundThread->ClientId.UniqueThread == ClientId->UniqueThread)
+        // if (*(PULONGLONG)&FoundThread->ClientId == *(PULONGLONG)ClientId)
+        if ( FoundThread->ClientId.UniqueProcess == ClientId->UniqueProcess &&
+             FoundThread->ClientId.UniqueThread  == ClientId->UniqueThread )
         {
             /* Match found, return the process */
             *Process = FoundThread->Process;
@@ -212,9 +216,6 @@ CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL,
 //            DPRINT1("Found: %p %p\n", FoundThread, FoundThread->Process);
             return FoundThread;
         }
-
-        /* Next */
-        NextEntry = NextEntry->Flink;
     }
 
     /* Nothing found */
@@ -267,7 +268,7 @@ CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL,
         /* Check for TID Match */
         if (FoundThread->ClientId.UniqueThread == Cid->UniqueThread) break;
 
-        /* Next entry */
+        /* Move to the next entry */
         NextEntry = NextEntry->Flink;
     }
 
@@ -464,14 +465,75 @@ CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread)
     if (!LockCount)
     {
         /* Call the generic cleanup code */
-        CsrThreadRefcountZero(CsrThread);
         CsrAcquireProcessLock();
+        CsrThreadRefcountZero(CsrThread);
     }
 }
 
 
 /* PUBLIC FUNCTIONS ***********************************************************/
 
+/*++
+ * @name CsrAddStaticServerThread
+ * @implemented NT4
+ *
+ * The CsrAddStaticServerThread routine adds a new CSR Thread to the
+ * CSR Server Process (CsrRootProcess).
+ *
+ * @param hThread
+ *        Handle to an existing NT Thread to which to associate this
+ *        CSR Thread.
+ *
+ * @param ClientId
+ *        Pointer to the Client ID structure of the NT Thread to associate
+ *        with this CSR Thread.
+ *
+ * @param ThreadFlags
+ *        Initial CSR Thread Flags to associate to this CSR Thread. Usually
+ *        CsrThreadIsServerThread.
+ *
+ * @return Pointer to the newly allocated CSR Thread.
+ *
+ * @remarks None.
+ *
+ *--*/
+PCSR_THREAD
+NTAPI
+CsrAddStaticServerThread(IN HANDLE hThread,
+                         IN PCLIENT_ID ClientId,
+                         IN ULONG ThreadFlags)
+{
+    PCSR_THREAD CsrThread;
+
+    /* Get the Lock */
+    CsrAcquireProcessLock();
+
+    /* Allocate the Server Thread */
+    CsrThread = CsrAllocateThread(CsrRootProcess);
+    if (CsrThread)
+    {
+        /* Setup the Object */
+        CsrThread->ThreadHandle = hThread;
+        ProtectHandle(hThread);
+        CsrThread->ClientId = *ClientId;
+        CsrThread->Flags = ThreadFlags;
+
+        /* Insert it into the Thread List */
+        InsertTailList(&CsrRootProcess->ThreadList, &CsrThread->Link);
+
+        /* Increment the thread count */
+        CsrRootProcess->ThreadCount++;
+    }
+    else
+    {
+        DPRINT1("CsrAddStaticServerThread: alloc failed for thread 0x%x\n", hThread);
+    }
+
+    /* Release the Process Lock and return */
+    CsrReleaseProcessLock();
+    return CsrThread;
+}
+
 /*++
  * @name CsrCreateRemoteThread
  * @implemented NT4
@@ -518,7 +580,7 @@ CsrCreateRemoteThread(IN HANDLE hThread,
     }
 
     /* Lock the Owner Process */
-    Status = CsrLockProcessByClientId(&ClientId->UniqueProcess, &CsrProcess);
+    Status = CsrLockProcessByClientId(ClientId->UniqueProcess, &CsrProcess);
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("No known process for %lx\n", ClientId->UniqueProcess);
@@ -573,75 +635,6 @@ CsrCreateRemoteThread(IN HANDLE hThread,
     return STATUS_SUCCESS;
 }
 
-/*++
- * @name CsrDestroyThread
- * @implemented NT4
- *
- * The CsrDestroyThread routine destroys the CSR Thread corresponding to
- * a given Thread ID.
- *
- * @param Cid
- *        Pointer to the Client ID Structure corresponding to the CSR
- *        Thread which is about to be destroyed.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
- *         if the CSR Thread is already terminating.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrDestroyThread(IN PCLIENT_ID Cid)
-{
-    CLIENT_ID ClientId = *Cid;
-    PCSR_THREAD CsrThread;
-    PCSR_PROCESS CsrProcess;
-
-    /* Acquire lock */
-    CsrAcquireProcessLock();
-
-    /* Find the thread */
-    CsrThread = CsrLocateThreadByClientId(&CsrProcess,
-                                          &ClientId);
-
-    /* Make sure we got one back, and that it's not already gone */
-    if (!CsrThread || CsrThread->Flags & CsrThreadTerminated)
-    {
-        /* Release the lock and return failure */
-        CsrReleaseProcessLock();
-        return STATUS_THREAD_IS_TERMINATING;
-    }
-
-    /* Set the terminated flag */
-    CsrThread->Flags |= CsrThreadTerminated;
-
-    /* Acquire the Wait Lock */
-    CsrAcquireWaitLock();
-
-    /* Do we have an active wait block? */
-    if (CsrThread->WaitBlock)
-    {
-        /* Notify waiters of termination */
-        CsrNotifyWaitBlock(CsrThread->WaitBlock,
-                           NULL,
-                           NULL,
-                           NULL,
-                           CsrProcessTerminating,
-                           TRUE);
-    }
-
-    /* Release the Wait Lock */
-    CsrReleaseWaitLock();
-
-    /* Dereference the thread */
-    CsrLockedDereferenceThread(CsrThread);
-
-    /* Release the Process Lock and return success */
-    CsrReleaseProcessLock();
-    return STATUS_SUCCESS;
-}
-
 /*++
  * @name CsrCreateThread
  * @implemented NT4
@@ -667,7 +660,6 @@ CsrDestroyThread(IN PCLIENT_ID Cid)
  *--*/
 NTSTATUS
 NTAPI
-#if 0
 CsrCreateThread(IN PCSR_PROCESS CsrProcess,
                 IN HANDLE hThread,
                 IN PCLIENT_ID ClientId,
@@ -678,12 +670,13 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess,
     PCSR_PROCESS CurrentProcess;
     CLIENT_ID CurrentCid;
     KERNEL_USER_TIMES KernelTimes;
+
     DPRINT("CSRSRV: %s called\n", __FUNCTION__);
 
     if (HaveClient)
     {
         /* Get the current thread and CID */
-        CurrentThread = NtCurrentTeb()->CsrClientThread;
+        CurrentThread = CsrGetClientThread();
         CurrentCid = CurrentThread->ClientId;
 
         /* Acquire the Process Lock */
@@ -691,6 +684,8 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess,
 
         /* Get the current Process and make sure the Thread is valid with this CID */
         CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid);
+
+        /* Something is wrong if we get an empty thread back */
         if (!CurrentThread)
         {
             DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__);
@@ -737,127 +732,9 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess,
 
     /* Release the lock and return */
     CsrReleaseProcessLock();
-    return STATUS_SUCCESS;
-}
-#else
-CsrCreateThread(IN PCSR_PROCESS CsrProcess,
-                IN HANDLE hThread,
-                IN PCLIENT_ID ClientId)
-{
-    PCSR_THREAD CsrThread;
-    PCSR_PROCESS CurrentProcess;
-    PCSR_THREAD CurrentThread = CsrGetClientThread();
-    CLIENT_ID CurrentCid;
-    KERNEL_USER_TIMES KernelTimes;
-
-    /* Get the current thread and CID */
-    CurrentCid = CurrentThread->ClientId;
-
-    /* Acquire the Process Lock */
-    CsrAcquireProcessLock();
-
-    /* Get the current Process and make sure the Thread is valid with this CID */
-    CurrentThread = CsrLocateThreadByClientId(&CurrentProcess,
-                                              &CurrentCid);
-
-    /* Something is wrong if we get an empty thread back */
-    if (!CurrentThread)
-    {
-        DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__);
-        CsrReleaseProcessLock();
-        return STATUS_THREAD_IS_TERMINATING;
-    }
-
-    /* Get the Thread Create Time */
-    NtQueryInformationThread(hThread,
-                             ThreadTimes,
-                             (PVOID)&KernelTimes,
-                             sizeof(KernelTimes),
-                             NULL);
-
-    /* Allocate a CSR Thread Structure */
-    if (!(CsrThread = CsrAllocateThread(CsrProcess)))
-    {
-        DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
-        CsrReleaseProcessLock();
-        return STATUS_NO_MEMORY;
-    }
-
-    /* Save the data we have */
-    CsrThread->CreateTime = KernelTimes.CreateTime;
-    CsrThread->ClientId = *ClientId;
-    CsrThread->ThreadHandle = hThread;
-    CsrThread->Flags = 0;
 
-    /* Insert the Thread into the Process */
-    CsrInsertThread(CsrProcess, CsrThread);
-
-    /* Release the lock and return */
-    CsrReleaseProcessLock();
     return STATUS_SUCCESS;
 }
-#endif
-
-/*++
- * @name CsrAddStaticServerThread
- * @implemented NT4
- *
- * The CsrAddStaticServerThread routine adds a new CSR Thread to the
- * CSR Server Process (CsrRootProcess).
- *
- * @param hThread
- *        Handle to an existing NT Thread to which to associate this
- *        CSR Thread.
- *
- * @param ClientId
- *        Pointer to the Client ID structure of the NT Thread to associate
- *        with this CSR Thread.
- *
- * @param ThreadFlags
- *        Initial CSR Thread Flags to associate to this CSR Thread. Usually
- *        CsrThreadIsServerThread.
- *
- * @return Pointer to the newly allocated CSR Thread.
- *
- * @remarks None.
- *
- *--*/
-PCSR_THREAD
-NTAPI
-CsrAddStaticServerThread(IN HANDLE hThread,
-                         IN PCLIENT_ID ClientId,
-                         IN ULONG ThreadFlags)
-{
-    PCSR_THREAD CsrThread;
-
-    /* Get the Lock */
-    CsrAcquireProcessLock();
-
-    /* Allocate the Server Thread */
-    CsrThread = CsrAllocateThread(CsrRootProcess);
-    if (CsrThread)
-    {
-        /* Setup the Object */
-        CsrThread->ThreadHandle = hThread;
-        ProtectHandle(hThread);
-        CsrThread->ClientId = *ClientId;
-        CsrThread->Flags = ThreadFlags;
-
-        /* Insert it into the Thread List */
-        InsertTailList(&CsrRootProcess->ThreadList, &CsrThread->Link);
-
-        /* Increment the thread count */
-        CsrRootProcess->ThreadCount++;
-    }
-    else
-    {
-        DPRINT1("CsrAddStaticServerThread: alloc failed for thread 0x%x\n", hThread);
-    }
-
-    /* Release the Process Lock and return */
-    CsrReleaseProcessLock();
-    return CsrThread;
-}
 
 /*++
  * @name CsrDereferenceThread
@@ -895,6 +772,74 @@ CsrDereferenceThread(IN PCSR_THREAD CsrThread)
     }
 }
 
+/*++
+ * @name CsrDestroyThread
+ * @implemented NT4
+ *
+ * The CsrDestroyThread routine destroys the CSR Thread corresponding to
+ * a given Thread ID.
+ *
+ * @param Cid
+ *        Pointer to the Client ID Structure corresponding to the CSR
+ *        Thread which is about to be destroyed.
+ *
+ * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
+ *         if the CSR Thread is already terminating.
+ *
+ * @remarks None.
+ *
+ *--*/
+NTSTATUS
+NTAPI
+CsrDestroyThread(IN PCLIENT_ID Cid)
+{
+    CLIENT_ID ClientId = *Cid;
+    PCSR_THREAD CsrThread;
+    PCSR_PROCESS CsrProcess;
+
+    /* Acquire lock */
+    CsrAcquireProcessLock();
+
+    /* Find the thread */
+    CsrThread = CsrLocateThreadByClientId(&CsrProcess,
+                                          &ClientId);
+
+    /* Make sure we got one back, and that it's not already gone */
+    if (!CsrThread || CsrThread->Flags & CsrThreadTerminated)
+    {
+        /* Release the lock and return failure */
+        CsrReleaseProcessLock();
+        return STATUS_THREAD_IS_TERMINATING;
+    }
+
+    /* Set the terminated flag */
+    CsrThread->Flags |= CsrThreadTerminated;
+
+    /* Acquire the Wait Lock */
+    CsrAcquireWaitLock();
+
+    /* Do we have an active wait block? */
+    if (CsrThread->WaitBlock)
+    {
+        /* Notify waiters of termination */
+        CsrNotifyWaitBlock(CsrThread->WaitBlock,
+                           NULL,
+                           NULL,
+                           NULL,
+                           CsrProcessTerminating,
+                           TRUE);
+    }
+
+    /* Release the Wait Lock */
+    CsrReleaseWaitLock();
+
+    /* Dereference the thread */
+    CsrLockedDereferenceThread(CsrThread);
+
+    /* Release the Process Lock and return success */
+    CsrReleaseProcessLock();
+    return STATUS_SUCCESS;
+}
 
 /*++
  * @name CsrExecServerThread
@@ -1034,7 +979,7 @@ CsrLockThreadByClientId(IN HANDLE Tid,
             break;
         }
 
-        /* Next entry */
+        /* Move to the next entry */
         NextEntry = NextEntry->Flink;
     }
 
@@ -1046,7 +991,7 @@ CsrLockThreadByClientId(IN HANDLE Tid,
     {
         /* Reference the found thread */
         Status = STATUS_SUCCESS;
-        CurrentThread->ReferenceCount++;
+        CsrLockedReferenceThread(CurrentThread);
         *CsrThread = CurrentThread;
     }
     else