Attach/detach mutant(mutex) to/from owning thread.

Fixed return value of KeWaitForMultipleObjects() on timeout.

svn path=/trunk/; revision=2355
This commit is contained in:
Eric Kohl 2001-11-07 02:17:22 +00:00
parent 7e8fb651af
commit 7a232306cc
7 changed files with 160 additions and 75 deletions

View file

@ -314,6 +314,7 @@ enum
#define IO_SERIAL_INCREMENT 2
#define IO_SOUND_INCREMENT 8
#define IO_VIDEO_INCREMENT 1
#define MUTANT_INCREMENT 1
#define SEMAPHORE_INCREMENT 1
#define FILE_BYTE_ALIGNMENT 0x00000000

View file

@ -266,8 +266,8 @@ LONG
STDCALL
KeReleaseMutant(
IN PKMUTANT Mutant,
ULONG Param2,
ULONG Param3,
IN KPRIORITY Increment,
IN BOOLEAN Abandon,
IN BOOLEAN Wait
);

View file

@ -1,4 +1,4 @@
/* $Id: wait.c,v 1.14 2001/01/20 12:20:43 ekohl Exp $
/* $Id: wait.c,v 1.15 2001/11/07 02:17:22 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -16,6 +16,7 @@
#include <windows.h>
#include <wchar.h>
#define NDEBUG
#include <kernel32/kernel32.h>
/* FUNCTIONS ****************************************************************/
@ -63,7 +64,7 @@ WaitForSingleObjectEx(HANDLE hHandle,
SetLastErrorByStatus (errCode);
return 0xFFFFFFFF;
return(WAIT_FAILED);
}
@ -92,6 +93,8 @@ WaitForMultipleObjectsEx(DWORD nCount,
LARGE_INTEGER Time;
PLARGE_INTEGER TimePtr;
DPRINT("nCount %lu\n", nCount);
if (dwMilliseconds == INFINITE)
{
TimePtr = NULL;
@ -112,15 +115,18 @@ WaitForMultipleObjectsEx(DWORD nCount,
{
return WAIT_TIMEOUT;
}
else if ((errCode >= WAIT_OBJECT_0) &&
(errCode <= WAIT_OBJECT_0 + nCount - 1))
else if (((errCode >= WAIT_OBJECT_0) &&
(errCode <= WAIT_OBJECT_0 + nCount - 1)) ||
((errCode >= WAIT_ABANDONED_0) &&
(errCode <= WAIT_ABANDONED_0 + nCount - 1)))
{
return errCode;
return(errCode);
}
DPRINT("errCode %lx\n", errCode);
SetLastErrorByStatus (errCode);
return 0xFFFFFFFF;
return(WAIT_FAILED);
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: mutex.c,v 1.9 2001/11/04 00:17:24 ekohl Exp $
/* $Id: mutex.c,v 1.10 2001/11/07 02:14:10 ekohl Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/mutex.c
@ -30,6 +30,7 @@
#include <ddk/ntddk.h>
#include <internal/ke.h>
#include <internal/ps.h>
#include <internal/id.h>
#include <internal/debug.h>
@ -44,6 +45,8 @@ KeInitializeMutex(IN PKMUTEX Mutex,
InternalMutexType,
sizeof(KMUTEX) / sizeof(ULONG),
1);
Mutex->MutantListEntry.Flink = NULL;
Mutex->MutantListEntry.Blink = NULL;
Mutex->OwnerThread = NULL;
Mutex->Abandoned = FALSE;
Mutex->ApcDisable = 1;
@ -60,10 +63,18 @@ KeReleaseMutex(IN PKMUTEX Mutex,
IN BOOLEAN Wait)
{
KeAcquireDispatcherDatabaseLock(Wait);
if (Mutex->OwnerThread != KeGetCurrentThread())
{
DbgPrint("THREAD_NOT_MUTEX_OWNER: Mutex %p\n", Mutex);
KeBugCheck(0); /* THREAD_NOT_MUTEX_OWNER */
}
Mutex->Header.SignalState++;
assert(Mutex->Header.SignalState <= 1);
if (Mutex->Header.SignalState == 1)
{
Mutex->OwnerThread = NULL;
if (Mutex->MutantListEntry.Flink && Mutex->MutantListEntry.Blink)
RemoveEntryList(&Mutex->MutantListEntry);
KeDispatcherObjectWake(&Mutex->Header);
}
KeReleaseDispatcherDatabaseLock(Wait);
@ -71,11 +82,11 @@ KeReleaseMutex(IN PKMUTEX Mutex,
}
NTSTATUS STDCALL
KeWaitForMutexObject(PKMUTEX Mutex,
KWAIT_REASON WaitReason,
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout)
KeWaitForMutexObject(IN PKMUTEX Mutex,
IN KWAIT_REASON WaitReason,
IN KPROCESSOR_MODE WaitMode,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Timeout)
{
return(KeWaitForSingleObject(Mutex,WaitReason,WaitMode,Alertable,Timeout));
}
@ -85,16 +96,24 @@ VOID STDCALL
KeInitializeMutant(IN PKMUTANT Mutant,
IN BOOLEAN InitialOwner)
{
if (InitialOwner == TRUE)
{
KeInitializeDispatcherHeader(&Mutant->Header,
InternalMutexType,
sizeof(KMUTANT) / sizeof(ULONG),
1);
if (InitialOwner == TRUE)
{
0);
InsertTailList(&KeGetCurrentThread()->MutantListHead,
&Mutant->MutantListEntry);
Mutant->OwnerThread = KeGetCurrentThread();
}
else
{
KeInitializeDispatcherHeader(&Mutant->Header,
InternalMutexType,
sizeof(KMUTANT) / sizeof(ULONG),
1);
Mutant->MutantListEntry.Flink = NULL;
Mutant->MutantListEntry.Blink = NULL;
Mutant->OwnerThread = NULL;
}
Mutant->Abandoned = FALSE;
@ -109,17 +128,40 @@ KeReadStateMutant(IN PKMUTANT Mutant)
LONG STDCALL
KeReleaseMutant(IN PKMUTANT Mutant,
ULONG Param2,
ULONG Param3,
IN KPRIORITY Increment,
IN BOOLEAN Abandon,
IN BOOLEAN Wait)
{
KeAcquireDispatcherDatabaseLock(Wait);
if (Abandon == FALSE)
{
if (Mutant->OwnerThread != NULL && Mutant->OwnerThread != KeGetCurrentThread())
{
DbgPrint("THREAD_NOT_MUTEX_OWNER: Mutant->OwnerThread %p CurrentThread %p\n",
Mutant->OwnerThread,
KeGetCurrentThread());
KeBugCheck(0); /* THREAD_NOT_MUTEX_OWNER */
}
Mutant->Header.SignalState++;
assert(Mutant->Header.SignalState <= 1);
}
else
{
if (Mutant->OwnerThread != NULL)
{
Mutant->Header.SignalState = 1;
Mutant->Abandoned = TRUE;
}
}
if (Mutant->Header.SignalState == 1)
{
Mutant->OwnerThread = NULL;
if (Mutant->MutantListEntry.Flink && Mutant->MutantListEntry.Blink)
RemoveEntryList(&Mutant->MutantListEntry);
KeDispatcherObjectWake(&Mutant->Header);
}
KeReleaseDispatcherDatabaseLock(Wait);
return(0);
}

View file

@ -125,7 +125,19 @@ VOID KiSideEffectsBeforeWake(DISPATCHER_HEADER* hdr,
Mutex = CONTAINING_RECORD(hdr, KMUTEX, Header);
hdr->SignalState--;
assert(hdr->SignalState <= 1);
if (hdr->SignalState == 0)
{
if (Thread == NULL)
{
DPRINT1("Thread == NULL!\n")
// KeBugCheck(0);
}
if (Thread != NULL)
InsertTailList(&Thread->MutantListHead,
&Mutex->MutantListEntry);
Mutex->OwnerThread = Thread;
Mutex->Abandoned = FALSE;
}
}
break;
@ -376,7 +388,8 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
}
NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object,
NTSTATUS STDCALL
KeWaitForSingleObject(PVOID Object,
KWAIT_REASON WaitReason,
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
@ -500,7 +513,7 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object,
NTSTATUS STDCALL
KeWaitForMultipleObjects (ULONG Count,
KeWaitForMultipleObjects(ULONG Count,
PVOID Object[],
WAIT_TYPE WaitType,
KWAIT_REASON WaitReason,
@ -664,7 +677,7 @@ KeWaitForMultipleObjects (ULONG Count,
{
KeCancelTimer(&KeGetCurrentThread()->Timer);
}
if (Status == (STATUS_WAIT_63 + 1))
if (Status == (STATUS_WAIT_0 + Count))
{
Status = STATUS_TIMEOUT;
}
@ -677,7 +690,8 @@ VOID KeInitializeDispatcher(VOID)
KeInitializeSpinLock(&DispatcherDatabaseLock);
}
NTSTATUS STDCALL NtWaitForMultipleObjects(IN ULONG Count,
NTSTATUS STDCALL
NtWaitForMultipleObjects(IN ULONG Count,
IN HANDLE Object [],
IN CINT WaitType,
IN BOOLEAN Alertable,
@ -734,7 +748,8 @@ NTSTATUS STDCALL NtWaitForMultipleObjects(IN ULONG Count,
}
NTSTATUS STDCALL NtWaitForSingleObject (IN HANDLE Object,
NTSTATUS STDCALL
NtWaitForSingleObject(IN HANDLE Object,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Time)
{

View file

@ -33,6 +33,7 @@
#include <ntos/synch.h>
#include <internal/ob.h>
#define NDEBUG
#include <internal/debug.h>
POBJECT_TYPE ExMutantObjectType = NULL;
@ -52,7 +53,7 @@ NtpCreateMutant(PVOID ObjectBody,
PWSTR RemainingPath,
POBJECT_ATTRIBUTES ObjectAttributes)
{
DPRINT("NtpCreateEvent(ObjectBody %x, Parent %x, RemainingPath %S)\n",
DPRINT("NtpCreateMutant(ObjectBody %x, Parent %x, RemainingPath %S)\n",
ObjectBody, Parent, RemainingPath);
if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
@ -71,9 +72,11 @@ NtpCreateMutant(PVOID ObjectBody,
VOID STDCALL
NtpDeleteMutant(PVOID ObjectBody)
{
DPRINT("NtpDeleteMutant(ObjectBody %x)\n", ObjectBody);
KeReleaseMutant((PKMUTANT)ObjectBody,
0,
0,
MUTANT_INCREMENT,
TRUE,
FALSE);
}
@ -139,7 +142,7 @@ NtOpenMutant(OUT PHANDLE MutantHandle,
return(ObOpenObjectByName(ObjectAttributes,
ExMutantObjectType,
NULL,
UserMode,
ExGetPreviousMode(),
DesiredAccess,
NULL,
MutantHandle));
@ -168,7 +171,7 @@ NtQueryMutant(IN HANDLE MutantHandle,
Status = ObReferenceObjectByHandle(MutantHandle,
MUTANT_QUERY_STATE,
ExMutantObjectType,
UserMode,
ExGetPreviousMode(),
(PVOID*)&Mutant,
NULL);
if (!NT_SUCCESS(Status))
@ -197,7 +200,7 @@ NtReleaseMutant(IN HANDLE MutantHandle,
Status = ObReferenceObjectByHandle(MutantHandle,
MUTANT_ALL_ACCESS,
ExMutantObjectType,
UserMode,
ExGetPreviousMode(),
(PVOID*)&Mutant,
NULL);
if (!NT_SUCCESS(Status))
@ -206,7 +209,7 @@ NtReleaseMutant(IN HANDLE MutantHandle,
}
Count = KeReleaseMutant(Mutant,
0,
MUTANT_INCREMENT,
0,
FALSE);
ObDereferenceObject(Mutant);

View file

@ -1,4 +1,4 @@
/* $Id: kill.c,v 1.47 2001/08/27 01:22:21 ekohl Exp $
/* $Id: kill.c,v 1.48 2001/11/07 02:16:25 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -129,6 +129,9 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus)
{
KIRQL oldIrql;
PETHREAD CurrentThread;
PKTHREAD Thread;
PLIST_ENTRY current_entry;
PKMUTANT Mutant;
CurrentThread = PsGetCurrentThread();
@ -136,7 +139,22 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus)
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
CurrentThread->ExitStatus = ExitStatus;
KeCancelTimer(&KeGetCurrentThread()->Timer);
Thread = KeGetCurrentThread();
KeCancelTimer(&Thread->Timer);
/* abandon all owned mutants */
current_entry = Thread->MutantListHead.Flink;
while (current_entry != &Thread->MutantListHead)
{
Mutant = CONTAINING_RECORD(current_entry, KMUTANT,
MutantListEntry);
KeReleaseMutant(Mutant,
MUTANT_INCREMENT,
TRUE,
FALSE);
current_entry = Thread->MutantListHead.Flink;
}
KeAcquireDispatcherDatabaseLock(FALSE);
CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE;
KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader);