blob: db327e2cb63da33d7c7c52e61879a6e2ff5ceb93 (
plain) (
tree)
|
|
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1995 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#ifndef __AFXTLS_H__
#define __AFXTLS_H__
#ifdef _AFX_PACKING
#pragma pack(push, _AFX_PACKING)
#endif
#undef AFX_DATA
#define AFX_DATA AFX_CORE_DATA
// Classes declared in this file
class CSimpleList;
class CThreadSlotData; // for manipulationg thread local storage
class CThreadLocalObject; // for storing thread/process local data
class CProcessLocalObject;
class CNoTrackObject;
// template class CTypedSimpleList<>
// template class CThreadLocal<>
// template class CProcessLocal<>
/////////////////////////////////////////////////////////////////////////////
// CSimpleList (simple/small subset of CList)
class CSimpleList
{
public:
CSimpleList(int nNextOffset = 0);
void Construct(int nNextOffset);
// Operations
BOOL IsEmpty() const;
void AddHead(void* p);
void RemoveAll();
void* GetHead() const;
void* GetNext(void* p) const;
BOOL Remove(void* p);
// Implementation
void* m_pHead;
size_t m_nNextOffset;
void** GetNextPtr(void* p) const; // somewhat trusting...
};
inline CSimpleList::CSimpleList(int nNextOffset)
{ m_pHead = NULL; m_nNextOffset = nNextOffset; }
inline void CSimpleList::Construct(int nNextOffset)
{ ASSERT(m_pHead == NULL); m_nNextOffset = nNextOffset; }
inline BOOL CSimpleList::IsEmpty() const
{ return m_pHead == NULL; }
inline void** CSimpleList::GetNextPtr(void* p) const
{ ASSERT(p != NULL); return (void**)((BYTE*)p+m_nNextOffset); }
inline void CSimpleList::RemoveAll()
{ m_pHead = NULL; }
inline void* CSimpleList::GetHead() const
{ return m_pHead; }
inline void* CSimpleList::GetNext(void* prevElement) const
{ return *GetNextPtr(prevElement); }
template<class TYPE>
class CTypedSimpleList : public CSimpleList
{
public:
CTypedSimpleList(int nNextOffset = 0)
: CSimpleList(nNextOffset) { }
void AddHead(TYPE p)
{ CSimpleList::AddHead(p); }
TYPE GetHead()
{ return (TYPE)CSimpleList::GetHead(); }
TYPE GetNext(TYPE p)
{ return (TYPE)CSimpleList::GetNext(p); }
BOOL Remove(TYPE p)
{ return CSimpleList::Remove((TYPE)p); }
operator TYPE()
{ return (TYPE)CSimpleList::GetHead(); }
};
/////////////////////////////////////////////////////////////////////////////
// CThreadSlotData - manages owned array of "slots" for thread local storage
struct CThreadData; // private to implementation
struct CSlotData; // private to implementation
class CThreadSlotData
{
public:
CThreadSlotData(BOOL bThreadLocal);
// Operations
int AllocSlot();
void FreeSlot(int nSlot);
void* GetValue(int nSlot);
void SetValue(int nSlot, void* pValue);
void DeleteValues(HINSTANCE hInst); // delete all values in process/thread
void AssignInstance(HINSTANCE hInst);
// Implementation
DWORD m_tlsIndex; // used if bThreadLocal == TRUE
CThreadData* m_pData; // used if bThreadLocal == FALSE
int m_nAlloc; // number of slots allocated (in UINTs)
int m_nRover; // (optimization) for quick finding of free slots
int m_nMax; // size of slot table below (in bits)
CSlotData* m_pSlotData; // state of each slot (allocated or not)
CTypedSimpleList<CThreadData*> m_list; // list of CThreadData structures
CRITICAL_SECTION m_sect;
void* GetThreadValue(int nSlot); // special version for threads only!
void* PASCAL operator new(size_t, void* p)
{ return p; }
~CThreadSlotData();
};
class CNoTrackObject
{
public:
void* PASCAL operator new(size_t nSize);
void PASCAL operator delete(void*);
#if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)
void* PASCAL operator new(size_t nSize, LPCSTR, int);
#endif
virtual ~CNoTrackObject() { }
};
class CThreadLocalObject
{
public:
// Attributes
CNoTrackObject* GetData(CNoTrackObject* (AFXAPI* pfnCreateObject)());
CNoTrackObject* GetDataNA();
// Implementation
int m_nSlot;
~CThreadLocalObject();
};
class CProcessLocalObject
{
public:
// Attributes
CNoTrackObject* GetData(CNoTrackObject* (AFXAPI* pfnCreateObject)());
CNoTrackObject* GetDataNA();
// Implementation
int m_nSlot;
~CProcessLocalObject();
};
template<class TYPE>
class CThreadLocal : public CThreadLocalObject
{
// Attributes
public:
inline TYPE* GetData()
{
TYPE* pData = (TYPE*)CThreadLocalObject::GetData(&CreateObject);
ASSERT(pData != NULL);
return pData;
}
inline TYPE* GetDataNA()
{
TYPE* pData = (TYPE*)CThreadLocalObject::GetDataNA();
return pData;
}
inline operator TYPE*()
{ return GetData(); }
inline TYPE* operator->()
{ return GetData(); }
// Implementation
public:
static CNoTrackObject* AFXAPI CreateObject()
{ return new TYPE; }
};
#define THREAD_LOCAL(class_name, ident_name) \
AFX_DATADEF CThreadLocal<class_name> ident_name;
#define EXTERN_THREAD_LOCAL(class_name, ident_name) \
extern AFX_DATA THREAD_LOCAL(class_name, ident_name)
template<class TYPE>
class CProcessLocal : public CProcessLocalObject
{
// Attributes
public:
inline TYPE* GetData()
{
TYPE* pData = (TYPE*)CProcessLocalObject::GetData(&CreateObject);
ASSERT(pData != NULL);
return pData;
}
inline TYPE* GetDataNA()
{
TYPE* pData = (TYPE*)CProcessLocalObject::GetDataNA();
return pData;
}
inline operator TYPE*()
{ return GetData(); }
inline TYPE* operator->()
{ return GetData(); }
// Implementation
public:
static CNoTrackObject* AFXAPI CreateObject()
{ return new TYPE; }
};
#define PROCESS_LOCAL(class_name, ident_name) \
AFX_DATADEF CProcessLocal<class_name> ident_name;
#define EXTERN_PROCESS_LOCAL(class_name, ident_name) \
extern AFX_DATA PROCESS_LOCAL(class_name, ident_name)
/////////////////////////////////////////////////////////////////////////////
void AFXAPI AfxInitLocalData(HINSTANCE hInstInit);
void AFXAPI AfxTermLocalData(HINSTANCE hInstTerm);
void AFXAPI AfxTlsAddRef();
void AFXAPI AfxTlsRelease();
#ifdef _AFX_PACKING
#pragma pack(pop)
#endif
#undef AFX_DATA
#define AFX_DATA
#endif //__AFXTLS_H__
/////////////////////////////////////////////////////////////////////////////
|