mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
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:
parent
7e8fb651af
commit
7a232306cc
7 changed files with 160 additions and 75 deletions
|
@ -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
|
||||
|
|
|
@ -266,8 +266,8 @@ LONG
|
|||
STDCALL
|
||||
KeReleaseMutant(
|
||||
IN PKMUTANT Mutant,
|
||||
ULONG Param2,
|
||||
ULONG Param3,
|
||||
IN KPRIORITY Increment,
|
||||
IN BOOLEAN Abandon,
|
||||
IN BOOLEAN Wait
|
||||
);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -59,23 +62,31 @@ LONG STDCALL
|
|||
KeReleaseMutex(IN PKMUTEX Mutex,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
KeAcquireDispatcherDatabaseLock(Wait);
|
||||
Mutex->Header.SignalState++;
|
||||
assert(Mutex->Header.SignalState <= 1);
|
||||
if (Mutex->Header.SignalState == 1)
|
||||
{
|
||||
KeDispatcherObjectWake(&Mutex->Header);
|
||||
}
|
||||
KeReleaseDispatcherDatabaseLock(Wait);
|
||||
return(0);
|
||||
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);
|
||||
return(0);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
KeInitializeDispatcherHeader(&Mutant->Header,
|
||||
InternalMutexType,
|
||||
sizeof(KMUTANT) / sizeof(ULONG),
|
||||
1);
|
||||
if (InitialOwner == TRUE)
|
||||
{
|
||||
KeInitializeDispatcherHeader(&Mutant->Header,
|
||||
InternalMutexType,
|
||||
sizeof(KMUTANT) / sizeof(ULONG),
|
||||
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);
|
||||
Mutant->Header.SignalState++;
|
||||
assert(Mutant->Header.SignalState <= 1);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -125,7 +125,19 @@ VOID KiSideEffectsBeforeWake(DISPATCHER_HEADER* hdr,
|
|||
Mutex = CONTAINING_RECORD(hdr, KMUTEX, Header);
|
||||
hdr->SignalState--;
|
||||
assert(hdr->SignalState <= 1);
|
||||
Mutex->OwnerThread = Thread;
|
||||
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,11 +388,12 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object,
|
||||
KWAIT_REASON WaitReason,
|
||||
KPROCESSOR_MODE WaitMode,
|
||||
BOOLEAN Alertable,
|
||||
PLARGE_INTEGER Timeout)
|
||||
NTSTATUS STDCALL
|
||||
KeWaitForSingleObject(PVOID Object,
|
||||
KWAIT_REASON WaitReason,
|
||||
KPROCESSOR_MODE WaitMode,
|
||||
BOOLEAN Alertable,
|
||||
PLARGE_INTEGER Timeout)
|
||||
/*
|
||||
* FUNCTION: Puts the current thread into a wait state until the
|
||||
* given dispatcher object is set to signalled
|
||||
|
@ -500,14 +513,14 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object,
|
|||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
KeWaitForMultipleObjects (ULONG Count,
|
||||
PVOID Object[],
|
||||
WAIT_TYPE WaitType,
|
||||
KWAIT_REASON WaitReason,
|
||||
KPROCESSOR_MODE WaitMode,
|
||||
BOOLEAN Alertable,
|
||||
PLARGE_INTEGER Timeout,
|
||||
PKWAIT_BLOCK WaitBlockArray)
|
||||
KeWaitForMultipleObjects(ULONG Count,
|
||||
PVOID Object[],
|
||||
WAIT_TYPE WaitType,
|
||||
KWAIT_REASON WaitReason,
|
||||
KPROCESSOR_MODE WaitMode,
|
||||
BOOLEAN Alertable,
|
||||
PLARGE_INTEGER Timeout,
|
||||
PKWAIT_BLOCK WaitBlockArray)
|
||||
{
|
||||
DISPATCHER_HEADER* hdr;
|
||||
PKWAIT_BLOCK blk;
|
||||
|
@ -586,7 +599,7 @@ KeWaitForMultipleObjects (ULONG Count,
|
|||
{
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
DPRINT("One object is already signaled!\n");
|
||||
return(STATUS_WAIT_0 + i);
|
||||
return(STATUS_WAIT_0 + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,11 +690,12 @@ VOID KeInitializeDispatcher(VOID)
|
|||
KeInitializeSpinLock(&DispatcherDatabaseLock);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL NtWaitForMultipleObjects(IN ULONG Count,
|
||||
IN HANDLE Object [],
|
||||
IN CINT WaitType,
|
||||
IN BOOLEAN Alertable,
|
||||
IN PLARGE_INTEGER Time)
|
||||
NTSTATUS STDCALL
|
||||
NtWaitForMultipleObjects(IN ULONG Count,
|
||||
IN HANDLE Object [],
|
||||
IN CINT WaitType,
|
||||
IN BOOLEAN Alertable,
|
||||
IN PLARGE_INTEGER Time)
|
||||
{
|
||||
KWAIT_BLOCK WaitBlockArray[EX_MAXIMUM_WAIT_OBJECTS];
|
||||
PVOID ObjectPtrArray[EX_MAXIMUM_WAIT_OBJECTS];
|
||||
|
@ -734,9 +748,10 @@ NTSTATUS STDCALL NtWaitForMultipleObjects(IN ULONG Count,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL NtWaitForSingleObject (IN HANDLE Object,
|
||||
IN BOOLEAN Alertable,
|
||||
IN PLARGE_INTEGER Time)
|
||||
NTSTATUS STDCALL
|
||||
NtWaitForSingleObject(IN HANDLE Object,
|
||||
IN BOOLEAN Alertable,
|
||||
IN PLARGE_INTEGER Time)
|
||||
{
|
||||
PVOID ObjectPtr;
|
||||
NTSTATUS Status;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue