mirror of
https://github.com/reactos/reactos.git
synced 2024-11-10 00:34:39 +00:00
6afbc8f483
svn path=/branches/reactos-yarotows/; revision=45219
157 lines
4.2 KiB
C
157 lines
4.2 KiB
C
/*
|
|
* PROJECT: ReactOS Kernel
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
* FILE: ntoskrnl/io/remlock.c
|
|
* PURPOSE: Remove Lock Support
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
|
* Filip Navara (navaraf@reactos.org)
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include <ntoskrnl.h>
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
VOID
|
|
NTAPI
|
|
IoInitializeRemoveLockEx(IN PIO_REMOVE_LOCK RemoveLock,
|
|
IN ULONG AllocateTag,
|
|
IN ULONG MaxLockedMinutes,
|
|
IN ULONG HighWatermark,
|
|
IN ULONG RemlockSize)
|
|
{
|
|
PEXTENDED_IO_REMOVE_LOCK Lock = (PEXTENDED_IO_REMOVE_LOCK)RemoveLock;
|
|
PAGED_CODE();
|
|
|
|
/* Check if this is a debug lock */
|
|
if (RemlockSize == sizeof(IO_REMOVE_LOCK_DBG_BLOCK))
|
|
{
|
|
/* Clear the lock */
|
|
RtlZeroMemory(Lock, RemlockSize);
|
|
|
|
/* Setup debug parameters */
|
|
Lock->Dbg.HighWatermark = HighWatermark;
|
|
Lock->Dbg.MaxLockedTicks = MaxLockedMinutes * 600000000;
|
|
Lock->Dbg.AllocateTag = AllocateTag;
|
|
KeInitializeSpinLock(&Lock->Dbg.Spin);
|
|
}
|
|
else
|
|
{
|
|
/* Otherwise, setup a free block */
|
|
Lock->Common.Removed = FALSE;
|
|
Lock->Common.IoCount = 1;
|
|
KeInitializeEvent(&Lock->Common.RemoveEvent,
|
|
SynchronizationEvent,
|
|
FALSE);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
NTSTATUS
|
|
NTAPI
|
|
IoAcquireRemoveLockEx(IN PIO_REMOVE_LOCK RemoveLock,
|
|
IN OPTIONAL PVOID Tag,
|
|
IN LPCSTR File,
|
|
IN ULONG Line,
|
|
IN ULONG RemlockSize)
|
|
{
|
|
PEXTENDED_IO_REMOVE_LOCK Lock = (PEXTENDED_IO_REMOVE_LOCK)RemoveLock;
|
|
|
|
/* Increase the lock count */
|
|
InterlockedIncrement(&Lock->Common.IoCount);
|
|
if (!Lock->Common.Removed)
|
|
{
|
|
/* Check what kind of lock this is */
|
|
if (RemlockSize == sizeof(IO_REMOVE_LOCK_DBG_BLOCK))
|
|
{
|
|
/* FIXME: Not yet supported */
|
|
DPRINT1("UNIMPLEMENTED\n");
|
|
ASSERT(FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Otherwise, decrement the count and check if it's gone */
|
|
if (!InterlockedDecrement(&Lock->Common.IoCount))
|
|
{
|
|
/* Signal the event */
|
|
KeSetEvent(&Lock->Common.RemoveEvent, IO_NO_INCREMENT, FALSE);
|
|
}
|
|
|
|
/* Return pending delete */
|
|
return STATUS_DELETE_PENDING;
|
|
}
|
|
|
|
/* Otherwise, return success */
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
VOID
|
|
NTAPI
|
|
IoReleaseRemoveLockEx(IN PIO_REMOVE_LOCK RemoveLock,
|
|
IN PVOID Tag,
|
|
IN ULONG RemlockSize)
|
|
{
|
|
PEXTENDED_IO_REMOVE_LOCK Lock = (PEXTENDED_IO_REMOVE_LOCK)RemoveLock;
|
|
|
|
/* Check what kind of lock this is */
|
|
if (RemlockSize == sizeof(IO_REMOVE_LOCK_DBG_BLOCK))
|
|
{
|
|
/* FIXME: Not yet supported */
|
|
DPRINT1("UNIMPLEMENTED\n");
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
/* Decrement the lock count */
|
|
if (!InterlockedDecrement(&Lock->Common.IoCount))
|
|
{
|
|
/* Signal the event */
|
|
KeSetEvent(&Lock->Common.RemoveEvent, IO_NO_INCREMENT, FALSE);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
VOID
|
|
NTAPI
|
|
IoReleaseRemoveLockAndWaitEx(IN PIO_REMOVE_LOCK RemoveLock,
|
|
IN PVOID Tag,
|
|
IN ULONG RemlockSize)
|
|
{
|
|
PEXTENDED_IO_REMOVE_LOCK Lock = (PEXTENDED_IO_REMOVE_LOCK)RemoveLock;
|
|
PAGED_CODE();
|
|
|
|
/* Remove the lock and decrement the count */
|
|
Lock->Common.Removed = TRUE;
|
|
if (InterlockedDecrement(&Lock->Common.IoCount) > 0)
|
|
{
|
|
/* Wait for it */
|
|
KeWaitForSingleObject(&Lock->Common.RemoveEvent,
|
|
Executive,
|
|
KernelMode,
|
|
FALSE,
|
|
NULL);
|
|
}
|
|
|
|
/* Check what kind of lock this is */
|
|
if (RemlockSize == sizeof(IO_REMOVE_LOCK_DBG_BLOCK))
|
|
{
|
|
/* FIXME: Not yet supported */
|
|
DPRINT1("UNIMPLEMENTED\n");
|
|
ASSERT(FALSE);
|
|
}
|
|
}
|
|
|
|
/* EOF */
|