mirror of
https://github.com/reactos/reactos.git
synced 2024-11-03 21:34:00 +00:00
88c9e7c6e8
svn path=/branches/reactos-yarotows/; revision=47117
172 lines
3.4 KiB
C
172 lines
3.4 KiB
C
#include <win32k.h>
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HSEMAPHORE
|
|
APIENTRY
|
|
EngCreateSemaphore ( VOID )
|
|
{
|
|
// www.osr.com/ddk/graphics/gdifncs_95lz.htm
|
|
PERESOURCE psem = ExAllocatePoolWithTag( NonPagedPool, sizeof(ERESOURCE), TAG_GSEM );
|
|
if ( !psem )
|
|
return NULL;
|
|
if ( !NT_SUCCESS(ExInitializeResourceLite ( psem )) )
|
|
{
|
|
ExFreePoolWithTag ( psem, TAG_GSEM );
|
|
return NULL;
|
|
}
|
|
return (HSEMAPHORE)psem;
|
|
}
|
|
|
|
VOID
|
|
FASTCALL
|
|
IntGdiAcquireSemaphore ( HSEMAPHORE hsem )
|
|
{
|
|
KeEnterCriticalRegion();
|
|
ExAcquireResourceExclusiveLite ( (PERESOURCE)hsem, TRUE );
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
VOID
|
|
APIENTRY
|
|
EngAcquireSemaphore ( IN HSEMAPHORE hsem )
|
|
{
|
|
// www.osr.com/ddk/graphics/gdifncs_14br.htm
|
|
PTHREADINFO W32Thread;
|
|
ASSERT(hsem);
|
|
IntGdiAcquireSemaphore ( hsem );
|
|
W32Thread = PsGetThreadWin32Thread(PsGetCurrentThread());
|
|
if (W32Thread) W32Thread->dwEngAcquireCount++;
|
|
}
|
|
|
|
|
|
VOID
|
|
FASTCALL
|
|
IntGdiReleaseSemaphore ( HSEMAPHORE hsem )
|
|
{
|
|
ExReleaseResourceLite ( (PERESOURCE)hsem );
|
|
KeLeaveCriticalRegion();
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
VOID
|
|
APIENTRY
|
|
EngReleaseSemaphore ( IN HSEMAPHORE hsem )
|
|
{
|
|
// www.osr.com/ddk/graphics/gdifncs_5u3r.htm
|
|
PTHREADINFO W32Thread;
|
|
ASSERT(hsem);
|
|
W32Thread = PsGetThreadWin32Thread(PsGetCurrentThread());
|
|
if (W32Thread) --W32Thread->dwEngAcquireCount;
|
|
IntGdiReleaseSemaphore ( hsem );
|
|
}
|
|
|
|
VOID
|
|
NTAPI
|
|
EngAcquireSemaphoreShared(
|
|
IN HSEMAPHORE hsem)
|
|
{
|
|
PTHREADINFO pti;
|
|
|
|
ASSERT(hsem);
|
|
ExEnterCriticalRegionAndAcquireResourceShared((PERESOURCE)hsem);
|
|
pti = PsGetThreadWin32Thread(PsGetCurrentThread());
|
|
if (pti) ++pti->dwEngAcquireCount;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
VOID
|
|
APIENTRY
|
|
EngDeleteSemaphore ( IN HSEMAPHORE hsem )
|
|
{
|
|
// www.osr.com/ddk/graphics/gdifncs_13c7.htm
|
|
ASSERT ( hsem );
|
|
|
|
ExDeleteResourceLite((PERESOURCE)hsem);
|
|
|
|
ExFreePoolWithTag( (PVOID)hsem, TAG_GSEM);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
APIENTRY
|
|
EngIsSemaphoreOwned ( IN HSEMAPHORE hsem )
|
|
{
|
|
// www.osr.com/ddk/graphics/gdifncs_6wmf.htm
|
|
ASSERT(hsem);
|
|
return (((PERESOURCE)hsem)->ActiveCount > 0);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
APIENTRY
|
|
EngIsSemaphoreOwnedByCurrentThread ( IN HSEMAPHORE hsem )
|
|
{
|
|
// www.osr.com/ddk/graphics/gdifncs_9yxz.htm
|
|
ASSERT(hsem);
|
|
return ExIsResourceAcquiredExclusiveLite ( (PERESOURCE)hsem );
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL APIENTRY
|
|
EngInitializeSafeSemaphore(
|
|
OUT ENGSAFESEMAPHORE *Semaphore)
|
|
{
|
|
HSEMAPHORE hSem;
|
|
|
|
if (InterlockedIncrement(&Semaphore->lCount) == 1)
|
|
{
|
|
/* Create the semaphore */
|
|
hSem = EngCreateSemaphore();
|
|
if (hSem == 0)
|
|
{
|
|
InterlockedDecrement(&Semaphore->lCount);
|
|
return FALSE;
|
|
}
|
|
/* FIXME - not thread-safe! Check result of InterlockedCompareExchangePointer
|
|
and delete semaphore if already initialized! */
|
|
(void)InterlockedExchangePointer((volatile PVOID *)&Semaphore->hsem, hSem);
|
|
}
|
|
else
|
|
{
|
|
/* Wait for the other thread to create the semaphore */
|
|
ASSERT(Semaphore->lCount > 1);
|
|
ASSERT_IRQL_LESS_OR_EQUAL(PASSIVE_LEVEL);
|
|
while (Semaphore->hsem == NULL);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
VOID APIENTRY
|
|
EngDeleteSafeSemaphore(
|
|
IN OUT ENGSAFESEMAPHORE *Semaphore)
|
|
{
|
|
if (InterlockedDecrement(&Semaphore->lCount) == 0)
|
|
{
|
|
/* FIXME - not thread-safe! Use result of InterlockedCompareExchangePointer! */
|
|
EngDeleteSemaphore(Semaphore->hsem);
|
|
(void)InterlockedExchangePointer((volatile PVOID *)&Semaphore->hsem, NULL);
|
|
}
|
|
}
|
|
|
|
|