- Remove some duplicated/useless code and use internal forward exports instead.
- Set kernel apc pending flag when needed in KeReleaseMutant
- Optimize check for kernel apc delivery in KeReleaseMutant
- Raise right exception in KeReleaseMutant
- Simplify KeInitializeMutant and remove some duplicated operations.
- Remove duplicated listhead initialization in KeInitiializeMutex
- Use correct increment in KeReleaseMutex
Modified: trunk/reactos/ntoskrnl/ke/mutex.c
Modified: trunk/reactos/ntoskrnl/ntoskrnl.def

Modified: trunk/reactos/ntoskrnl/ke/mutex.c
--- trunk/reactos/ntoskrnl/ke/mutex.c	2005-10-01 08:20:12 UTC (rev 18184)
+++ trunk/reactos/ntoskrnl/ke/mutex.c	2005-10-01 08:58:49 UTC (rev 18185)
@@ -27,33 +27,30 @@
 KeInitializeMutant(IN PKMUTANT Mutant,
                    IN BOOLEAN InitialOwner)
 {
-    ULONG Signaled = TRUE;
-    PKTHREAD CurrentThread = NULL;
+    PKTHREAD CurrentThread;
     KIRQL OldIrql;
-
     DPRINT("KeInitializeMutant: %x\n", Mutant);
 
     /* Check if we have an initial owner */
-    if (InitialOwner == TRUE) {
-
-        /* In this case, the object is not signaled */
-        Signaled = FALSE;
-
+    if (InitialOwner == TRUE)
+    {
         /* We also need to associate a thread */
         CurrentThread = KeGetCurrentThread();
+        Mutant->OwnerThread = CurrentThread;
 
         /* We're about to touch the Thread, so lock the Dispatcher */
         OldIrql = KeAcquireDispatcherDatabaseLock();
 
         /* And insert it into its list */
-        InsertTailList(&CurrentThread->MutantListHead, &Mutant->MutantListEntry);
+        InsertTailList(&CurrentThread->MutantListHead,
+                       &Mutant->MutantListEntry);
 
         /* Release Dispatcher Lock */
         KeReleaseDispatcherDatabaseLock(OldIrql);
         DPRINT("Mutant with Initial Owner\n");
-
-    } else {
-
+    }
+    else
+    {
         /* In this case, we don't have an owner yet */
         Mutant->OwnerThread = NULL;
     }
@@ -62,10 +59,9 @@
     KeInitializeDispatcherHeader(&Mutant->Header,
                                  MutantObject,
                                  sizeof(KMUTANT) / sizeof(ULONG),
-                                 Signaled);
+                                 InitialOwner ? FALSE : TRUE);
 
     /* Initialize the default data */
-    Mutant->OwnerThread = CurrentThread;
     Mutant->Abandoned = FALSE;
     Mutant->ApcDisable = 0;
 }
@@ -80,18 +76,16 @@
 {
     DPRINT("KeInitializeMutex: %x\n", Mutex);
 
-
     /* Set up the Dispatcher Header */
     KeInitializeDispatcherHeader(&Mutex->Header,
                                  MutantObject,
                                  sizeof(KMUTEX) / sizeof(ULONG),
-                                 1);
+                                 TRUE);
 
     /* Initialize the default data */
     Mutex->OwnerThread = NULL;
     Mutex->Abandoned = FALSE;
     Mutex->ApcDisable = 1;
-    InitializeListHead(&Mutex->Header.WaitListHead);
 }
 
 /*
@@ -110,17 +104,6 @@
  */
 LONG
 STDCALL
-KeReadStateMutex(IN PKMUTEX Mutex)
-{
-    /* Return the Signal State */
-    return(Mutex->Header.SignalState);
-}
-
-/*
- * @implemented
- */
-LONG
-STDCALL
 KeReleaseMutant(IN PKMUTANT Mutant,
                 IN KPRIORITY Increment,
                 IN BOOLEAN Abandon,
@@ -129,7 +112,6 @@
     KIRQL OldIrql;
     LONG PreviousState;
     PKTHREAD CurrentThread = KeGetCurrentThread();
-
     DPRINT("KeReleaseMutant: %x\n", Mutant);
 
     /* Lock the Dispatcher Database */
@@ -139,22 +121,26 @@
     PreviousState = Mutant->Header.SignalState;
 
     /* Check if it is to be abandonned */
-    if (Abandon == FALSE) {
-
+    if (Abandon == FALSE)
+    {
         /* Make sure that the Owner Thread is the current Thread */
-        if (Mutant->OwnerThread != CurrentThread) {
+        if (Mutant->OwnerThread != CurrentThread)
+        {
+            DPRINT1("Trying to touch a Mutant that the caller doesn't own!\n");
 
+            /* Release the lock */
             KeReleaseDispatcherDatabaseLock(OldIrql);
 
-            DPRINT1("Trying to touch a Mutant that the caller doesn't own!\n");
-            ExRaiseStatus(STATUS_MUTANT_NOT_OWNED);
+            /* Raise an exception */
+            ExRaiseStatus(Mutant->Abandoned ? STATUS_ABANDONED :
+                                              STATUS_MUTANT_NOT_OWNED);
         }
 
         /* If the thread owns it, then increase the signal state */
         Mutant->Header.SignalState++;
-
-    } else  {
-
+    }
+    else
+    {
         /* It's going to be abandonned */
         DPRINT("Abandonning the Mutant\n");
         Mutant->Header.SignalState = 1;
@@ -162,25 +148,28 @@
     }
 
     /* Check if the signal state is only single */
-    if (Mutant->Header.SignalState == 1) {
-
+    if (Mutant->Header.SignalState == 1)
+    {
         /* Check if it's below 0 now */
-        if (PreviousState <= 0) {
-
+        if (PreviousState <= 0)
+        {
             /* Remove the mutant from the list */
-            DPRINT("Removing Mutant\n");
+            DPRINT("Removing Mutant %p\n", Mutant);
             RemoveEntryList(&Mutant->MutantListEntry);
 
             /* Reenable APCs */
             DPRINT("Re-enabling APCs\n");
             CurrentThread->KernelApcDisable += Mutant->ApcDisable;
 
-            /* Force an Interrupt if Apcs are pending */
-            if (!IsListEmpty(&CurrentThread->ApcState.ApcListHead[KernelMode])) {
+            /* Check if the thread has APCs enabled */
+            if (!CurrentThread->KernelApcDisable)
+            {
+                /* Check if any are pending */
+                if (!IsListEmpty(&CurrentThread->ApcState.ApcListHead[KernelMode]))
+                {
+                    /* Set Kernel APC Pending */
+                    CurrentThread->ApcState.KernelApcPending = TRUE;
 
-                /* Make sure they aren't disabled though */
-                if (!CurrentThread->KernelApcDisable) {
-
                     /* Request the Interrupt */
                     DPRINT("Requesting APC Interupt\n");
                     HalRequestSoftwareInterrupt(APC_LEVEL);
@@ -193,8 +182,8 @@
 
         /* Check if the Wait List isn't empty */
         DPRINT("Checking whether to wake the Mutant\n");
-        if (!IsListEmpty(&Mutant->Header.WaitListHead)) {
-
+        if (!IsListEmpty(&Mutant->Header.WaitListHead))
+        {
             /* Wake the Mutant */
             DPRINT("Waking the Mutant\n");
             KiWaitTest(&Mutant->Header, Increment);
@@ -202,13 +191,13 @@
     }
 
     /* If the Wait is true, then return with a Wait and don't unlock the Dispatcher Database */
-    if (Wait == FALSE) {
-
+    if (Wait == FALSE)
+    {
         /* Release the Lock */
         KeReleaseDispatcherDatabaseLock(OldIrql);
-
-    } else {
-
+    }
+    else
+    {
         /* Set a wait */
         CurrentThread->WaitNext = TRUE;
         CurrentThread->WaitIrql = OldIrql;
@@ -226,28 +215,8 @@
 KeReleaseMutex(IN PKMUTEX Mutex,
                IN BOOLEAN Wait)
 {
-
     /* There's no difference at this level between the two */
-    return KeReleaseMutant(Mutex, IO_NO_INCREMENT, FALSE, Wait);
+    return KeReleaseMutant(Mutex, 1, FALSE, Wait);
 }
 
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-KeWaitForMutexObject(IN PKMUTEX Mutex,
-                     IN KWAIT_REASON WaitReason,
-                     IN KPROCESSOR_MODE WaitMode,
-                     IN BOOLEAN Alertable,
-                     IN PLARGE_INTEGER Timeout)
-{
-    /* This is a simple macro. Export the function here though */
-    return KeWaitForSingleObject(Mutex,
-                                 WaitReason,
-                                 WaitMode,
-                                 Alertable,
-                                 Timeout);
-}
-
 /* EOF */

Modified: trunk/reactos/ntoskrnl/ntoskrnl.def
--- trunk/reactos/ntoskrnl/ntoskrnl.def	2005-10-01 08:20:12 UTC (rev 18184)
+++ trunk/reactos/ntoskrnl/ntoskrnl.def	2005-10-01 08:58:49 UTC (rev 18185)
@@ -588,7 +588,7 @@
 KeRaiseUserException@4
 KeReadStateEvent@4
 KeReadStateMutant@4
-KeReadStateMutex@4
+KeReadStateMutex@4=KeReadStateMutant@4
 KeReadStateQueue@4
 KeReadStateSemaphore@4
 KeReadStateTimer@4
@@ -645,7 +645,7 @@
 KeUnstackDetachProcess@4
 KeUserModeCallback@20
 KeWaitForMultipleObjects@32
-KeWaitForMutexObject@20
+KeWaitForMutexObject@20=KeWaitForSingleObject@20
 KeWaitForSingleObject@20
 @KefAcquireSpinLockAtDpcLevel@4
 @KefReleaseSpinLockFromDpcLevel@4