亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? afxtls.cpp

?? MFC的線程局部存儲的源代碼,主要講述MFC的線程局部存儲。需要的可以下載。
?? CPP
字號:
///////////////////////////////////////////////////////
// AFXTLS.CPP文件



#include "_AFXTLS_.H"


//---------------------------------------

void CSimpleList::AddHead(void* p)
{
	*GetNextPtr(p) = m_pHead;
	m_pHead = p;
}

BOOL CSimpleList::Remove(void* p)
{
	if(p == NULL)	// 檢查參數
		return FALSE;
	
	BOOL bResult = FALSE; // 假設移除失敗
	if(p == m_pHead)
	{
	// 要移除頭元素
		m_pHead = *GetNextPtr(p);
		bResult = TRUE;
	}
	else
	{
		// 試圖在表中查找要移除的元素
		void* pTest = m_pHead;
		while(pTest != NULL && *GetNextPtr(pTest) != p)
			pTest = *GetNextPtr(pTest);

		// 如果找到,就將元素移除
		if(pTest != NULL)
		{
			*GetNextPtr(pTest) = *GetNextPtr(p);
			bResult = TRUE;
		}
	}
	return bResult;
}

//-------------------CThreadSlotData類----------------------//
BYTE __afxThreadData[sizeof(CThreadSlotData)];	// 為下面的_afxThreadData變量提供內存
CThreadSlotData* _afxThreadData; // 定義全局變量_afxThreadData來為全局變量分配空間

struct CSlotData
{
	DWORD dwFlags;	// 槽的使用標志(被分配/未被分配)
	HINSTANCE hInst;// 占用此槽的模塊句柄
};

struct CThreadData : public CNoTrackObject
{
	CThreadData* pNext; // CSimpleList類要使用此成員
	int nCount;	    // 數組元素的個數
	LPVOID* pData;      // 數組的首地址
};

#define SLOT_USED 0x01		// CSlotData結構中dwFlags成員的值為0x01時表示該槽已被使用

CThreadSlotData::CThreadSlotData()
{
	m_list.Construct(offsetof(CThreadData, pNext)); // 初始化CTypedSimpleList對象

	m_nMax = 0;
	m_nAlloc = 0;
	m_nRover = 1;	// 我們假定Slot1還未被分配(第一個槽(Slot0)總是保留下來不被使用)
	m_pSlotData = NULL;

	m_tlsIndex = ::TlsAlloc();	// 使用系統的TLS申請一個索引
	::InitializeCriticalSection(&m_cs);	// 初始化關鍵段變量
}

int CThreadSlotData::AllocSlot()
{
	::EnterCriticalSection(&m_cs);	// 進入臨界區(也叫關鍵段)
	int nAlloc = m_nAlloc;
	int nSlot = m_nRover;

	if(nSlot >= nAlloc || m_pSlotData[nSlot].dwFlags & SLOT_USED)
	{
		// 搜索m_pSlotData,查找空槽(SLOT)
		for(nSlot = 1; nSlot < nAlloc && m_pSlotData[nSlot].dwFlags & SLOT_USED; nSlot ++) ;

		// 如果不存在空槽,申請更多的空間
		if(nSlot >= nAlloc)
		{
			// 增加全局數組的大小,分配或再分配內存以創建新槽
			int nNewAlloc = nAlloc + 32;

			HGLOBAL hSlotData;
			if(m_pSlotData == NULL)	// 第一次使用
			{
				hSlotData = ::GlobalAlloc(GMEM_MOVEABLE, nNewAlloc*sizeof(CSlotData));
			}
			else
			{
				hSlotData = ::GlobalHandle(m_pSlotData);
				::GlobalUnlock(hSlotData);
				hSlotData = ::GlobalReAlloc(hSlotData, 
					nNewAlloc*sizeof(CSlotData), GMEM_MOVEABLE);
			}
			CSlotData* pSlotData = (CSlotData*)::GlobalLock(hSlotData);
	
			// 將新申請的空間初始化為0
			memset(pSlotData + m_nAlloc, 0, (nNewAlloc - nAlloc)*sizeof(CSlotData));
			m_nAlloc = nNewAlloc;
			m_pSlotData = pSlotData;
		}
	}

	// 調整m_nMax的值,以便為各線程的私有數據分配內存
	if(nSlot >= m_nMax)
		m_nMax = nSlot + 1;

	m_pSlotData[nSlot].dwFlags |= SLOT_USED;
	// 更新m_nRover的值(我們假設下一個槽未被使用)
	m_nRover = nSlot + 1;

	::LeaveCriticalSection(&m_cs);
	return nSlot; // 返回的槽號可以被FreeSlot, GetThreadValue, SetValue函數使用了
}

void CThreadSlotData::FreeSlot(int nSlot)
{
	::EnterCriticalSection(&m_cs);	

	// 刪除所有線程中的數據
	CThreadData* pData = m_list;
	while(pData != NULL)
	{
		if(nSlot < pData->nCount)
		{
			delete (CNoTrackObject*)pData->pData[nSlot];
			pData->pData[nSlot] = NULL;
		}
		pData = pData->pNext;
	}

	// 將此槽號標識為未被使用
	m_pSlotData[nSlot].dwFlags &= ~SLOT_USED;
	::LeaveCriticalSection(&m_cs);
}

inline void* CThreadSlotData::GetThreadValue(int nSlot)
{
	CThreadData* pData = (CThreadData*)::TlsGetValue(m_tlsIndex);
	if(pData == NULL || nSlot >= pData->nCount)
		return NULL;
	return pData->pData[nSlot];
}

void CThreadSlotData::SetValue(int nSlot, void* pValue)
{
	// 通過TLS索引得到我們為線程安排的私有存儲空間
	CThreadData* pData = (CThreadData*)::TlsGetValue(m_tlsIndex);

	// 為線程私有數據申請內存空間
	if((pData == NULL || nSlot >= pData->nCount) && pValue != NULL)
	{
		// pData的值為空,表示該線程第一次訪問線程私有數據
		if(pData == NULL)
		{
			pData = new CThreadData;
			pData->nCount = 0;
			pData->pData = NULL;

			// 將新申請的內存的地址添加到全局列表中
			::EnterCriticalSection(&m_cs);
			m_list.AddHead(pData);
			::LeaveCriticalSection(&m_cs);
		}

		// pData->pData指向真正的線程私有數據,下面的代碼將私有數據占用的空間增長到m_nMax指定的大小
		if(pData->pData == NULL)
			pData->pData = (void**)::GlobalAlloc(LMEM_FIXED, m_nMax*sizeof(LPVOID));
		else
			pData->pData = (void**)::GlobalReAlloc(pData->pData, m_nMax*sizeof(LPVOID), LMEM_MOVEABLE);
		
		// 將新申請的內存初始話為0
		memset(pData->pData + pData->nCount, 0, 
			(m_nMax - pData->nCount) * sizeof(LPVOID));
		pData->nCount = m_nMax;
		::TlsSetValue(m_tlsIndex, pData);
	}

	// 設置線程私有數據的值
	pData->pData[nSlot] = pValue;
}

void CThreadSlotData::DeleteValues(HINSTANCE hInst, BOOL bAll)
{
	::EnterCriticalSection(&m_cs);
	if(!bAll)
	{
		// 僅僅刪除當前線程的線程局部存儲占用的空間
		CThreadData* pData = (CThreadData*)::TlsGetValue(m_tlsIndex);
		if(pData != NULL)
			DeleteValues(pData, hInst);
	}
	else
	{
		// 刪除所有線程的線程局部存儲占用的空間
		CThreadData* pData = m_list.GetHead();
		while(pData != NULL)
		{
			CThreadData* pNextData = pData->pNext;
			DeleteValues(pData, hInst);
			pData = pNextData;
		}
	}
	::LeaveCriticalSection(&m_cs);
}

void CThreadSlotData::DeleteValues(CThreadData* pData, HINSTANCE hInst)
{
	// 釋放表中的每一個元素
	BOOL bDelete = TRUE;
	for(int i=1; i<pData->nCount; i++)
	{
		if(hInst == NULL || m_pSlotData[i].hInst == hInst)
		{
			// hInst匹配,刪除數據
			delete (CNoTrackObject*)pData->pData[i];
			pData->pData[i] = NULL;
		}
		else
		{
			// 還有其它模塊在使用,不要刪除數據
			if(pData->pData[i] != NULL)
			bDelete = FALSE;
		}
	}

	if(bDelete)
	{
		// 從列表中移除
		::EnterCriticalSection(&m_cs);
		m_list.Remove(pData);
		::LeaveCriticalSection(&m_cs);
		::LocalFree(pData->pData);
		delete pData;

		// 清除TLS索引,防止重用
		::TlsSetValue(m_tlsIndex, NULL);
	}
}

CThreadSlotData::~CThreadSlotData()
{
	CThreadData *pData = m_list;
	while(pData != NULL)
	{
		CThreadData* pDataNext = pData->pNext;
		DeleteValues(pData, NULL);
		pData = pData->pNext;
	}

	if(m_tlsIndex != (DWORD)-1)
		::TlsFree(m_tlsIndex);

	if(m_pSlotData != NULL)
	{
		HGLOBAL hSlotData = ::GlobalHandle(m_pSlotData);
		::GlobalUnlock(hSlotData);
		::GlobalFree(m_pSlotData);
	}

	::DeleteCriticalSection(&m_cs);
}

//---------------------------------------

void* CNoTrackObject::operator new(size_t nSize)
{
	// 申請一塊帶有GMEM_FIXED和GMEM_ZEROINIT標志的內存
	void* p = ::GlobalAlloc(GPTR, nSize);
	return p;
}

void CNoTrackObject::operator delete(void* p)
{
	if(p != NULL)
		::GlobalFree(p);
}

//----------------------------CThreadLocalObject 類--------------------------------//

CNoTrackObject* CThreadLocalObject::GetData(CNoTrackObject* (*pfnCreateObject)())
{
	if(m_nSlot == 0)
	{
		if(_afxThreadData == NULL)
			_afxThreadData = new(__afxThreadData) CThreadSlotData;
		m_nSlot = _afxThreadData->AllocSlot();
	}
 
	CNoTrackObject* pValue = (CNoTrackObject*)_afxThreadData->GetThreadValue(m_nSlot);
	if(pValue == NULL)
	{
		// 創建一個數據項
		pValue = (*pfnCreateObject)();

		// 使用線程私有數據保存新創建的對象
		_afxThreadData->SetValue(m_nSlot, pValue);	
	}
	
	return pValue;
}

CNoTrackObject* CThreadLocalObject::GetDataNA()
{
	if(m_nSlot == 0 || _afxThreadData == 0)
		return NULL;
	return (CNoTrackObject*)_afxThreadData->GetThreadValue(m_nSlot);
}

CThreadLocalObject::~CThreadLocalObject()
{
	if(m_nSlot != 0 && _afxThreadData != NULL)
		_afxThreadData->FreeSlot(m_nSlot);
	m_nSlot = 0;
}

//------------------------------------------

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品女主播在线观看| 国内精品免费在线观看| 精品一区二区在线免费观看| www..com久久爱| 欧美高清一级片在线| 国产精品视频观看| 日韩成人精品视频| 一本色道久久综合狠狠躁的推荐| 精品国产第一区二区三区观看体验| 亚洲精品国产一区二区精华液| 极品少妇xxxx精品少妇| 欧美日韩你懂的| 中文字幕综合网| 久久精品国产久精国产爱| 在线一区二区观看| 国产精品视频线看| 国产东北露脸精品视频| 日韩一级免费一区| 天堂资源在线中文精品| 91官网在线观看| 亚洲精品国产精华液| 色综合久久久久久久久| 亚洲欧洲精品一区二区三区| 国产成人高清视频| 国产午夜精品一区二区| 看片的网站亚洲| 日韩欧美中文字幕精品| 麻豆免费看一区二区三区| 91精品国产品国语在线不卡| 天堂成人免费av电影一区| 欧美日韩国产电影| 亚洲国产精品久久人人爱| 欧美午夜片在线观看| 婷婷综合五月天| 日韩一区二区在线观看| 激情欧美一区二区| 国产日韩欧美激情| 99精品国产99久久久久久白柏 | 欧美一级欧美三级在线观看| 日韩精品电影一区亚洲| 日韩午夜在线观看视频| 久久99热这里只有精品| 国产色综合一区| 国产不卡视频一区| 中文字幕一区二区三区四区不卡| 97超碰欧美中文字幕| 亚洲国产一区二区视频| 欧美一区二区三区在线电影 | 亚洲制服丝袜在线| 欧美伦理影视网| 免费在线观看一区| 久久久国产午夜精品| 色综合天天综合网国产成人综合天| 亚洲男人天堂av网| 日韩欧美二区三区| a级精品国产片在线观看| 国产制服丝袜一区| 1024亚洲合集| 日韩女优av电影在线观看| 国产成人在线视频网站| 亚洲午夜久久久| 久久久综合精品| 欧美在线综合视频| 精品无人区卡一卡二卡三乱码免费卡 | 亚洲成人激情社区| 2019国产精品| 欧美亚洲禁片免费| 国产精品资源在线看| 亚洲中国最大av网站| 久久久久久久久久电影| 欧美午夜电影网| 国产盗摄女厕一区二区三区| 午夜精品久久久久| 欧美国产成人精品| 欧美大片国产精品| 在线欧美一区二区| 国产超碰在线一区| 青青青爽久久午夜综合久久午夜| 自拍偷拍亚洲欧美日韩| 久久久国产精品麻豆| 这里是久久伊人| 日本韩国欧美在线| 国产精品小仙女| 男女男精品视频| 亚洲综合视频在线观看| 欧美极品另类videosde| 日韩欧美二区三区| 欧美日韩精品电影| 在线观看91精品国产入口| 欧美成人欧美edvon| 97久久久精品综合88久久| 激情图片小说一区| 日本中文字幕一区二区有限公司| 亚洲视频精选在线| 国产精品色一区二区三区| 337p粉嫩大胆噜噜噜噜噜91av| 欧美日韩综合在线免费观看| 91女神在线视频| 成人福利在线看| 丁香激情综合五月| 丁香天五香天堂综合| 国内一区二区视频| 精品中文字幕一区二区小辣椒| 一区二区三区在线视频免费观看| 国产精品伦一区二区三级视频| 久久久久久久久岛国免费| 精品黑人一区二区三区久久| 欧美一区二区视频在线观看2022| 欧美色偷偷大香| 欧美日韩国产乱码电影| 欧美午夜精品一区二区蜜桃| 在线免费观看视频一区| 欧美做爰猛烈大尺度电影无法无天| 成人av动漫在线| 91在线免费播放| 欧美专区在线观看一区| 欧美影院精品一区| 亚洲在线中文字幕| 亚洲已满18点击进入久久| 一卡二卡三卡日韩欧美| 一区二区三区日韩精品视频| 亚洲自拍偷拍九九九| 水蜜桃久久夜色精品一区的特点 | 亚洲精品高清在线| 亚洲韩国一区二区三区| 性做久久久久久久免费看| 日本在线不卡视频| 国产一区二区美女诱惑| 成人伦理片在线| 色又黄又爽网站www久久| 欧美久久久久久久久久| 欧美成人精品福利| 久久精品一区蜜桃臀影院| 国产精品麻豆一区二区| 亚洲自拍另类综合| 加勒比av一区二区| 91老师片黄在线观看| 在线电影院国产精品| 久久久国产精品午夜一区ai换脸| 中文字幕在线观看一区| 亚洲成a人片在线不卡一二三区| 久久电影网站中文字幕 | 国产免费久久精品| 亚洲欧洲精品一区二区精品久久久| 夜色激情一区二区| 蜜桃视频第一区免费观看| 国产一区免费电影| www.色精品| 欧美一级欧美三级在线观看| 国产精品无人区| 日日欢夜夜爽一区| 成人国产一区二区三区精品| 欧美日韩在线播放三区四区| 精品日韩欧美在线| 亚洲综合在线五月| 国产一区视频导航| 欧美视频在线一区| 久久精品网站免费观看| 亚洲成在线观看| 处破女av一区二区| 日韩午夜激情电影| 亚洲免费看黄网站| 国产suv一区二区三区88区| 精品视频1区2区3区| 国产精品伦理在线| 国产一区欧美一区| 91精品国产色综合久久| 亚洲欧美日本韩国| 国产成人精品aa毛片| 精品久久久久久久久久久久久久久| 一区二区高清视频在线观看| 高清国产一区二区| 26uuu精品一区二区| 午夜精品久久久久久| 91美女片黄在线观看91美女| 国产午夜一区二区三区| 免费观看久久久4p| 欧美日韩亚洲综合一区二区三区| 国产精品美女久久久久aⅴ| 久久er精品视频| 日韩欧美一级精品久久| 日韩不卡免费视频| 欧美色倩网站大全免费| 一区二区三区日韩欧美精品 | 国产精品白丝jk黑袜喷水| 日韩欧美黄色影院| 日韩激情中文字幕| 在线一区二区三区做爰视频网站| 亚洲欧美综合网| 97se狠狠狠综合亚洲狠狠| 国产精品无人区| av中文字幕在线不卡| 国产精品国产a| 不卡影院免费观看| 中文字幕人成不卡一区| 91香蕉视频在线| 一区二区三区加勒比av| 91福利国产成人精品照片| 亚洲综合成人在线| 在线不卡a资源高清|