Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

243 lines
5.5 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: eventlst.cpp
//
// Contents: Microsoft Internet Security Trust Provider
//
// Functions: InitializeListLock
// InitializeListEvent
// LockWaitToWrite
//
// *** local functions ***
// LockInitialize
//
// History: 29-May-1997 pberkman created
//
//--------------------------------------------------------------------------
#include "global.hxx"
#include "eventlst.h"
#define PCB_LIST_DEBUG 0
BOOL LockInitialize(LIST_LOCK *pListLock, DWORD dwDebugMask);
BOOL InitializeListLock(LIST_LOCK *psListLock, DWORD dwDebugMask)
{
return(LockInitialize(psListLock, dwDebugMask));
}
BOOL InitializeListEvent(HANDLE *phListEvent)
{
if (!(*phListEvent = CreateEvent(NULL, TRUE, TRUE, NULL)))
{
return(FALSE);
}
return(TRUE);
}
BOOL EventFree(HANDLE hListEvent)
{
if ((hListEvent) && (hListEvent != INVALID_HANDLE_VALUE))
{
CloseHandle(hListEvent);
return(TRUE);
}
return(FALSE);
}
BOOL LockInitialize(LIST_LOCK *pListLock, DWORD dwDebugMask)
{
//
// Initialize the variable that indicates the number of
// reader threads that are reading.
// Initially no reader threads are reading.
//
pListLock->dwDebugMask = dwDebugMask;
pListLock->NumReaders = 0;
pListLock->hMutexNoWriter = CreateMutex(NULL, FALSE, NULL);
if (!(pListLock->hMutexNoWriter))
{
return(FALSE);
}
//
// Create the manual-reset event that is signalled when
// no reader threads are reading. Initially no reader
// threads are reading.
//
pListLock->hEventNoReaders = CreateEvent(NULL, TRUE, TRUE, NULL);
if (pListLock->hEventNoReaders)
{
return(TRUE);
}
else
{
CloseHandle(pListLock->hMutexNoWriter);
pListLock->hMutexNoWriter = NULL;
return(FALSE);
}
}
BOOL LockFree(LIST_LOCK *pListLock)
{
if (pListLock->hEventNoReaders)
{
CloseHandle(pListLock->hEventNoReaders);
pListLock->hEventNoReaders = NULL;
}
if (pListLock->hMutexNoWriter)
{
CloseHandle(pListLock->hMutexNoWriter);
pListLock->hMutexNoWriter = NULL;
}
return(TRUE);
}
void LockWaitToWrite(LIST_LOCK *pListLock)
{
//
// We can write if the following are true:
//
// 1. The mutex guard is available and no
// other threads are writing.
//
// 2. No threads are reading.
//
// Note that, unlike an rtl resource, this attempt
// to write does not lock out other readers. We
// just have to wait patiently for our turn.
//
HANDLE ahObjects[2];
ahObjects[0] = pListLock->hMutexNoWriter;
ahObjects[1] = pListLock->hEventNoReaders;
WaitForMultipleObjects(2, ahObjects, TRUE, INFINITE);
# if (DBG) && (PCB_LIST_DEBUG)
DbgPrintf(pListLock->dwDebugMask, "Write Acquire: t:%04lX w:%p r:%p\n",
GetCurrentThreadId(), ahObjects[0], ahObjects[1]);
# endif
//
// Exit with the mutex, so as to prevent any more readers or writers
// from coming in.
//
}
void LockDoneWriting(LIST_LOCK *pListLock)
{
//
// We're done writing, release the mutex so that
// readers or other writers may come in.
//
# if (DBG) && (PCB_LIST_DEBUG)
DbgPrintf(pListLock->dwDebugMask, "Write Release: t:%04lX w:%p r:%p\n",
GetCurrentThreadId(), pListLock->hMutexNoWriter, pListLock->hEventNoReaders);
# endif
ReleaseMutex(pListLock->hMutexNoWriter);
}
void LockWaitToRead(LIST_LOCK *pListLock)
{
//
// Acquire the mutex that protects the list data.
//
WaitForSingleObject(pListLock->hMutexNoWriter, INFINITE);
# if (DBG) && (PCB_LIST_DEBUG)
DbgPrintf(pListLock->dwDebugMask, "Read Acquire: t:%04lX w:%p r:%p\n",
GetCurrentThreadId(), pListLock->hMutexNoWriter, pListLock->hEventNoReaders);
# endif
//
// Now that we have the mutex, we can modify list data without
// fear of corrupting anyone.
//
//
// Increment the number of reader threads.
//
if (++pListLock->NumReaders == 1)
{
//
// If this is the first reader thread, set our event to
// reflect this. This is so that anyone waiting to write
// will block until we're done.
//
ResetEvent(pListLock->hEventNoReaders);
}
//
// Allow other writer/reader threads to use
// the lock object.
//
ReleaseMutex(pListLock->hMutexNoWriter);
}
void LockDoneReading(LIST_LOCK *pListLock)
{
//
// Acquire the mutex that guards the list data so we can
// decrement the number of readers safely.
//
WaitForSingleObject(pListLock->hMutexNoWriter, INFINITE);
# if (DBG) && (PCB_LIST_DEBUG)
DbgPrintf(pListLock->dwDebugMask, "Read Release: t:%04lX w:%p r:%p\n",
GetCurrentThreadId(), pListLock->hMutexNoWriter, pListLock->hEventNoReaders);
# endif
if (--pListLock->NumReaders == 0)
{
//
// We were the last reader. Wake up any potential
// writers.
//
SetEvent(pListLock->hEventNoReaders);
}
//
// Allow other writer/reader threads to use
// the lock object.
//
ReleaseMutex(pListLock->hMutexNoWriter);
}