/*++ Copyright (c) 1996 Microsoft Corporation All rights reserved. Module Name: sharedat.hxx Abstract: Fixed size single writer (only by creater of object), multiple readers. Assumes rare writes, and utilizes dual incrementing counters to ensure consistent read access to data. Reader retries when its read occurs at the same time as a write. Creator ensures there is a single writer. Usage: // // Create simple data object (no vbtl/virtual functions). // struct TObject { DWORD dwData1; DWORD dwData2; }; Writer: TShareData::TReadWrite Object( TEXT( "NamedSharedData" ), sizeof( TObject ), NULL ); TObject *pObject = (TObject*)Object.pData(); // // WriteBegin indicates that a group update has begun. This must be // done even for single data writes unless you can guarantee that the // data write appears atomic. // Object.vWriteBegin(); // // Modify the data here. // pObject->dwData1 = 1; pObject->dwData2 = 2; // // WriteEnd is called when all writes to the data are complete. // Object.vWriteEnd(); Reader: TShareData::TRead Object( TEXT( "NamedSharedData" )); TObject *pObject = (TObject*)Object.pData(); TShareData::TReadSync RS( Object ); DWORD dwData; do { RS.vReadBegin(); dwData1 = pObject->dwData1; dwData2 = pObject->dwData2; } while( RS.vReadEnd( )); Implementation detail: Write: Increment Count[1] Modify data Increment Count[0] Read: do { c1 = Count[0] Read data and copy into separate buffer c2 = Count[1] } while ( c1 != c2 ) Overactive writer can starve readers. Author: Albert Ting (AlbertT) 5-Oct-97 Revision History: --*/ #ifndef SHAREDAT_HXX #define SHAREDAT_HXX #define SZ_SUFFIX_FILE (TEXT( "_shrDatF" )) class TShareData { private: class TReadSync; class TBase { friend class TReadSync; protected: typedef struct TData { DWORD cbSize; DWORD dwReserved; LONG lCount1; LONG lCount2; } *pTData; HANDLE m_hMap; pTData m_pData; public: PVOID pData( VOID ) { return (PBYTE)m_pData + sizeof( TData ); } BOOL bValid( VOID ) { return m_pData != NULL; } protected: enum { kNameBufferMax = MAX_PATH + COUNTOF( SZ_SUFFIX_FILE ) }; TBase( VOID ); ~TBase( VOID ); VOID vCleanup( VOID ); BOOL bGetFullName( LPCTSTR pszName, LPTSTR pszFullName ); }; public: class TReadWrite : public TBase { public: TReadWrite( LPCTSTR pszName, DWORD cbSize, PSECURITY_ATTRIBUTES pSA ); VOID vWriteFirst( VOID ); VOID vWriteBegin( VOID ); VOID vWriteEnd( VOID ); }; class TRead : public TBase { public: TRead( LPCTSTR pszName, DWORD cbSize ); }; class TReadSync { public: TReadSync( TRead& Read ); BOOL bValid( VOID ) { return TRUE; } VOID vReadBegin( VOID ); BOOL bReadEnd( VOID ); private: TRead& m_Read; LONG m_lCount; }; }; #endif // ifndef SHAREDAT_HXX