Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

130 lines
2.9 KiB

/* sem.c -- simple semaphores. */
/* Copyright 1995 Spyglass, Inc. All Rights Reserved. */
/* Jeff Hostetler, Spyglass, Inc. 1995. */
#include "all.h"
#define STATE_SEM_GOTSEMAPHORE (STATE_OTHER + 0)
Sem gModalDialogSemaphore;
void Sem_InitSem(Sem * sem)
{
memset((void *)sem,0,sizeof(*sem));
return;
}
BOOL Sem_CondWaitSem_Sync(Sem * sem)
{
/* conditionally take lock on simple semaphore object.
* (take lock if we can do so without blocking)
*
* Return TRUE iff we took the lock.
* Return FALSE if error or already locked.
*
*/
if (!sem)
return FALSE;
if (sem->bLocked)
return FALSE;
XX_Assert((sem->qHead==0),("Sem_WaitSem_Sync: qHead not zero -- not locked, but someone waiting...."));
sem->bLocked = TRUE;
XX_DMsg(DBG_SEM,("Sem_CondWaitSem_Sync: Taking Semaphore [0x%08lx]\n",sem));
return TRUE;
}
void Sem_SignalSem_Sync(Sem * sem)
{
/* release current lock on the given semaphore.
* if a thread is waiting, unblock the thread and give it the lock.
*/
if (!sem)
return;
if (!sem->bLocked)
return;
if (sem->qHead)
{
SemQueueEntry * sqe = sem->qHead;
XX_DMsg(DBG_SEM,("Sem_SignalSem_Sync: Giving Semaphore [0x%08lx] to window [%d]\n",sem,sqe->tw));
Async_UnblockByWindow(sqe->tw); /* release current threads */
if (sem->qTail == sqe)
{
XX_Assert((sqe->qNext==0),("Sem_SignalSem_Sync: qNext not zero -- when head == tail...."));
sem->qTail = sqe->qNext;
}
sem->qHead = sqe->qNext;
GTR_FREE(sqe);
}
/* no threads waiting */
sem->bLocked = FALSE;
XX_DMsg(DBG_SEM,("Sem_SignalSem_Sync: Releasing Semaphore [0x%08lx]\n",sem));
return;
}
int Sem_WaitSem_Async(struct Mwin * tw, int nState, void **ppInfo)
{
/* must be called from a thread context */
struct Params_SemData * pSemData = *ppInfo;
SemQueueEntry * sqe;
switch (nState)
{
case STATE_INIT:
if (tw == NULL)
{
*pSemData->pStatus = 0;
return STATE_DONE;
}
if (Sem_CondWaitSem_Sync(pSemData->semaphore))
{
/* no one holding it or in the queue waiting for
* it, so we just took it without blocking.
*/
*pSemData->pStatus = 1;
return STATE_DONE;
}
/* add us to end of FIFO waiting on this semaphore */
sqe = GTR_CALLOC(1,sizeof(*sqe));
if (!sqe)
{
*pSemData->pStatus = 0;
return STATE_DONE;
}
sqe->tw = tw;
if (pSemData->semaphore->qTail)
pSemData->semaphore->qTail->qNext = sqe;
pSemData->semaphore->qTail = sqe;
if (!pSemData->semaphore->qHead)
pSemData->semaphore->qHead = sqe;
Async_BlockByWindow(sqe->tw);
XX_DMsg(DBG_SEM,("Sem_WaitSem_Async: Queueing Window [%d] for Semaphore [0x%08lx]\n",sqe->tw,pSemData->semaphore));
return STATE_SEM_GOTSEMAPHORE;
case STATE_SEM_GOTSEMAPHORE:
*pSemData->pStatus = 1;
return STATE_DONE;
case STATE_ABORT:
*pSemData->pStatus = 0;
return STATE_DONE;
}
XX_Assert((0), ("Function called with illegal state: %d", nState));
return STATE_DONE;
}