00001 #if !defined(__MCTHREADGLOBAL_H_)
00002 #define __MCTHREADGLOBAL_H_
00003
00004 #ident "@(#)$Id: MCThreadGlobal.h,v 1.3 2004/12/02 07:05:20 mike Exp $"
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "mcllib/MCThreadData.h"
00026 #include "mcllib/MCThrow.h"
00027
00028 namespace mcllib
00029 {
00036 template<typename T>
00037 class MCThreadSingleton
00038 {
00039 private:
00041 class Inner : public MCThreadData
00042 {
00043 public:
00044 Inner()
00045 {
00046 m_pInstance = new T();
00047 }
00048 ~Inner()
00049 {
00050 if (m_pInstance)
00051 delete m_pInstance;
00052 }
00053 inline T* ptr()
00054 {
00055 return(m_pInstance);
00056 }
00057 private:
00058 T* m_pInstance;
00059 };
00060
00062 void initialize()
00063 {
00064 if (m_key == 0) {
00065 MCThrow("MCThreadSingleton: key not initialized");
00066 }
00067
00068 MCThreadData* pData = MCThread::getData(m_key);
00069 if (!pData) {
00070 m_pInner = new Inner();
00071 pData = m_pInner;
00072 MCThread::setData(m_key, (MCThreadData*)m_pInner);
00073 } else {
00074 m_pInner = static_cast<Inner*>(pData);
00075 }
00076 }
00077
00078 public:
00089 MCThreadSingleton(const MCString& key)
00090 {
00091 if (m_key == 0) {
00092
00093
00094 m_key = MCThread::getDataIndex(key);
00095 }
00096 initialize();
00097 }
00105 MCThreadSingleton()
00106 {
00107 initialize();
00108 }
00110 inline T* operator->()
00111 {
00112 return(m_pInner->ptr());
00113 }
00115 inline T& operator*()
00116 {
00117 return(*(m_pInner->ptr()));
00118 }
00119
00121 static mcthreaddatakey_t m_key;
00122
00124 MCRefPtr<Inner, MCThreadModel::THRMODELSINGLE> m_pInner;
00125 };
00126
00136 template<typename T>
00137 void MCThreadSingletonMaker(T* , const MCString& key)
00138 {
00139 MCThreadSingleton<T> t(key);
00140 (void)t.m_pInner;
00141 }
00142
00143 };
00144
00145 #endif