/*-------------------------------------------------------------------------
* src\fedsrv\SWMRG.H
*
* Single Writer, Multiple Reader w/ Guard
*
* Owner:
*
* Copyright 1986-1998 Microsoft Corporation, All Rights Reserved
*-----------------------------------------------------------------------*/
#define ARRAY_SIZE(Array) \
(sizeof(Array) / sizeof((Array)[0]))
// Create a BEGINTHREADEX macro that calls the C run-time's
// _beginthreadex function. The C run-time library doesn't
// want to have any reliance on Win32 data types such as
// HANDLE. This means that a Win32 programmer needs to cast
// the return value to a HANDLE. This is terribly inconvenient,
// so I have created this macro to perform the casting.
typedef unsigned (__stdcall *PTHREAD_START) (void *);
#define BEGINTHREADEX(lpsa, cbStack, lpStartAddr, \
lpvThreadParm, fdwCreate, lpIDThread) \
((HANDLE)_beginthreadex( \
(void *) (lpsa), \
(unsigned) (cbStack), \
(PTHREAD_START) (lpStartAddr), \
(void *) (lpvThreadParm), \
(unsigned) (fdwCreate), \
(unsigned *) (lpIDThread)))
// The single-writer/multiple-reader guard
// compound synchronization object
struct SWMRG
{
// This mutex guards access to the other objects
// managed by this data structure and also indicates
// whether any writer threads are writing.
HANDLE hMutexNoWriter;
// This manual-reset event is signaled when
// no reader threads are reading.
HANDLE hEventNoReaders;
// This semaphore is used simply as a counter that is
// accessible between multiple processes. It is NOT
// used for thread synchronization.
// The count is the number of reader threads reading.
HANDLE hSemNumReaders;
};
typedef SWMRG * PSWMRG;
// Initializes a SWMRG structure. This structure must be
// initialized before any writer or reader threads attempt
// to wait on it.
// The structure must be allocated by the application and
// the structure's address is passed as the first parameter.
// The lpszName parameter is the name of the object. Pass
// NULL if you do not want to share the object.
bool FSWMRGInitialize (PSWMRG pSWMRG, LPCTSTR lpszName);
// Deletes the system resources associated with a SWMRG
// structure. The structure must be deleted only when
// no writer or reader threads in the calling process
// will wait on it.
void SWMRGDelete (PSWMRG pSWMRG);
// A writer thread calls this function to know when
// it can successfully write to the shared data.
DWORD SWMRGWaitToWrite (PSWMRG pSWMRG, DWORD dwTimeout);
// A writer thread calls this function to let other threads
// know that it no longer needs to write to the shared data.
void SWMRGDoneWriting (PSWMRG pSWMRG);
// A reader thread calls this function to know when
// it can successfully read the shared data.
DWORD SWMRGWaitToRead (PSWMRG pSWMRG, DWORD dwTimeout);
// A reader thread calls this function to let other threads
// know when it no longer needs to read the shared data.
void SWMRGDoneReading (PSWMRG pSWMRG);