//============================================================================ // Copyright (c) 1995, Microsoft Corporation // // File: sync.h // // History: // Abolade Gbadegesin Aug-8-1995 Created. // // Contains structures and macros used to implement synchronization. //============================================================================ #ifndef _SYNC_H_ #define _SYNC_H_ // // type definition for multiple-reader/single-writer lock // Note: there is a similar facility provided by nturtl.h through the // structure RTL_RESOURCE and several functions. However, that // implementation has the potential for starving a thread trying to acquire // write accesss, if there are a large number of threads interested in // acquiring read access. Such a scenario is avoided in the implementation // given in this header. However, a mapping is also given to the // RTL_RESOURCE functionality, so that the protocol can be compiled to use // either form // #ifdef USE_RWL // // use IPRIP's definitions // typedef struct _READ_WRITE_LOCK { CRITICAL_SECTION RWL_ReadWriteBlock; LONG RWL_ReaderCount; HANDLE RWL_ReaderDoneEvent; } READ_WRITE_LOCK, *PREAD_WRITE_LOCK; DWORD CreateReadWriteLock(PREAD_WRITE_LOCK pRWL); VOID DeleteReadWriteLock(PREAD_WRITE_LOCK pRWL); VOID AcquireReadLock(PREAD_WRITE_LOCK pRWL); VOID ReleaseReadLock(PREAD_WRITE_LOCK pRWL); VOID AcquireWriteLock(PREAD_WRITE_LOCK pRWL); VOID ReleaseWriteLock(PREAD_WRITE_LOCK pRWL); // // macro functions for manipulating a read-write lock // #define CREATE_READ_WRITE_LOCK(pRWL) \ CreateReadWriteLock(pRWL) #define DELETE_READ_WRITE_LOCK(pRWL) \ DeleteReadWriteLock(pRWL) #define READ_WRITE_LOCK_CREATED(pRWL) \ ((pRWL)->RWL_ReaderDoneEvent != NULL) #define ACQUIRE_READ_LOCK(pRWL) \ AcquireReadLock(pRWL) #define RELEASE_READ_LOCK(pRWL) \ ReleaseReadLock(pRWL) #define ACQUIRE_WRITE_LOCK(pRWL) \ AcquireWriteLock(pRWL) #define RELEASE_WRITE_LOCK(pRWL) \ ReleaseWriteLock(pRWL) #define READ_LOCK_TO_WRITE_LOCK(pRWL) \ (ReleaseReadLock(pRWL), AcquireWriteLock(pRWL)) #define WRITE_LOCK_TO_READ_LOCK(pRWL) \ (ReleaseWriteLock(pRWL), AcquireReadLock(pRWL)) #else // i.e. !USE_RWL // // use the RTL_RESOURCE mechanism // typedef RTL_RESOURCE READ_WRITE_LOCK, *PREAD_WRITE_LOCK; #define CREATE_READ_WRITE_LOCK(pRWL) \ RtlInitializeResource((pRWL)) #define DELETE_READ_WRITE_LOCK(pRWL) \ RtlDeleteResource((pRWL)) #define READ_WRITE_LOCK_CREATED(pRWL) (TRUE) #define ACQUIRE_READ_LOCK(pRWL) \ RtlAcquireResourceShared((pRWL),TRUE) #define RELEASE_READ_LOCK(pRWL) \ RtlReleaseResource((pRWL)) #define ACQUIRE_WRITE_LOCK(pRWL) \ RtlAcquireResourceExclusive((pRWL),TRUE) #define RELEASE_WRITE_LOCK(pRWL) \ RtlReleaseResource((pRWL)) #define READ_LOCK_TO_WRITE_LOCK(pRWL) \ RtlConvertSharedToExclusive((pRWL)) #define WRITE_LOCK_TO_READ_LOCK(pRWL) \ RtlConvertExclusiveToShared((pRWL)) #endif // USE_RWL // // type definition for generic locked list // access is sychronized with a critical section // typedef struct _LOCKED_LIST { LIST_ENTRY LL_Head; CRITICAL_SECTION LL_Lock; DWORD LL_Created; } LOCKED_LIST, *PLOCKED_LIST; // // macro functions for manipulating the locked list // #define CREATE_LOCKED_LIST(pLL) \ InitializeListHead(&(pLL)->LL_Head); \ InitializeCriticalSection(&(pLL)->LL_Lock); \ (pLL)->LL_Created = 0x12345678 #define LOCKED_LIST_CREATED(pLL) \ ((pLL)->LL_Created == 0x12345678) #define DELETE_LOCKED_LIST(pLL,type,field) { \ PLIST_ENTRY _ple; \ (pLL)->LL_Created = 0; \ DeleteCriticalSection(&(pLL)->LL_Lock); \ while (!IsListEmpty(&(pLL)->LL_Head)) { \ _ple = RemoveHeadList(&(pLL)->LL_Head); \ FREE(CONTAINING_RECORD(_ple,type,field)); \ } \ } #define ACQUIRE_LIST_LOCK(pLL) \ EnterCriticalSection(&(pLL)->LL_Lock) #define RELEASE_LIST_LOCK(pLL) \ LeaveCriticalSection(&(pLL)->LL_Lock) #endif // _SYNC_H_