⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sh_smem.cpp

📁 rsa算法打的一个包
💻 CPP
字号:
// SH_SMem.cpp: implementation of the SH_SMem class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SH_SMem.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#include <process.h>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

SH_SMem::SH_SMem()
{
	m_nOtherInstanceID	= 0;
	m_nInstanceID		= 0;
	m_hClosed		    = CreateEvent(NULL, TRUE, TRUE, NULL);
	m_hDataWrit[0]	    = NULL;
	m_hDataWrit[1]	    = NULL;
	m_hDataRead[0]	    = NULL;
	m_hDataRead[1]	    = NULL;
	m_hDataInQueue	    = NULL;
	m_hQueueMutex	    = NULL;
}

SH_SMem::~SH_SMem()
{
	Close();
	CloseHandle(m_hClosed);
}

BOOL SH_SMem::Open( const char* sName, int nDataSize, int nTimeOut/*= INFINITE*/)
{
	m_pFirst	= NULL;

	if (WaitForSingleObject(m_hClosed, 0) == WAIT_OBJECT_0)
	{
		if (strlen(sName) != 0 && strlen(sName) < MAX_PATH - 10)
		{
			if (nDataSize > 0)
			{
				char sMutex0	[MAX_PATH];
				char sMutex1	[MAX_PATH];
				strcpy(sMutex0	, sName);
				strcpy(sMutex1	, sName);
				strcat(sMutex0	, "Mutex0");
				strcat(sMutex1	, "Mutex1");
				m_hSMemMutex[0] = CreateMutex(NULL, FALSE, sMutex0);
				m_hSMemMutex[1] = CreateMutex(NULL, FALSE, sMutex1);
				if (m_hSMemMutex[0] && m_hSMemMutex[1])
				{
					HANDLE hWait[2] = {m_hSMemMutex[0], m_hSMemMutex[1]};
					DWORD dwResult = WaitForMultipleObjects(2, hWait, FALSE, 0);
					if (dwResult == WAIT_OBJECT_0 || dwResult == (WAIT_OBJECT_0 + 1))
					{
						if ((m_nInstanceID = dwResult - WAIT_OBJECT_0) == 0)
							m_nOtherInstanceID = 1;
						else
							m_nOtherInstanceID = 0;

						char sName0		[MAX_PATH];
						char sName1		[MAX_PATH];
						strcpy(sName0	, sName);
						strcpy(sName1	, sName);
						strcat(sName0	, "0");
						strcat(sName1	, "1");

						if ((m_hSMem[0]	= CreateFileMapping(	(HANDLE)0xFFFFFFFF,
																		NULL,
																		PAGE_READWRITE,
																		0,
																		sizeof(int) + nDataSize,
																		sName0)) != NULL
																		&&			
							(m_hSMem[1]	= CreateFileMapping(	(HANDLE)0xFFFFFFFF,
																		NULL,
																		PAGE_READWRITE,
																		0,
																		sizeof(int) + nDataSize,
																		sName1)) != NULL)
						{
							bool bFileMappingAlreadyExists = (GetLastError() == ERROR_ALREADY_EXISTS);

							m_pSize = (int*)MapViewOfFile(	m_hSMem[0],
																FILE_MAP_ALL_ACCESS,
																0,
																0,
																sizeof(int));
							if (m_pSize)
							{
								bool bSharedMemorySizeOk = false;
								if (bFileMappingAlreadyExists)
								{
									if (*m_pSize == nDataSize)
										bSharedMemorySizeOk = true;
								}
								else
								{
									*m_pSize = nDataSize;
									bSharedMemorySizeOk = true;
								}
								if (bSharedMemorySizeOk)
								{
									m_pSMem[0] = (BYTE*)MapViewOfFile(	m_hSMem[0],
																					FILE_MAP_ALL_ACCESS,
																					0,
																					0,
																					nDataSize);
									m_pSMem[1] = (BYTE*)MapViewOfFile(	m_hSMem[1],
																					FILE_MAP_ALL_ACCESS,
																					0,
																					0,
																					nDataSize);
									if (m_pSMem[0] && m_pSMem[1])
									{
										m_pSMem[0] += sizeof(int);
										m_pSMem[1] += sizeof(int);

										char sDataWrit0		[MAX_PATH];
										char sDataWrit1		[MAX_PATH];
										char sDataRead0		[MAX_PATH];
										char sDataRead1		[MAX_PATH];
										strcpy(sDataWrit0	, sName);
										strcpy(sDataWrit1	, sName);
										strcpy(sDataRead0	, sName);
										strcpy(sDataRead1	, sName);
										strcat(sDataWrit0	, "DataWrit0");
										strcat(sDataWrit1	, "DataWrit1");
										strcat(sDataRead0	, "DataRead0");
										strcat(sDataRead1	, "DataRead1");
										m_hDataWrit[0]	= CreateEvent(NULL, FALSE, FALSE,	sDataWrit0);
										m_hDataWrit[1]	= CreateEvent(NULL, FALSE, FALSE,	sDataWrit1);
										m_hDataRead[0]	= CreateEvent(NULL, FALSE, TRUE,	sDataRead0);
										m_hDataRead[1]	= CreateEvent(NULL, FALSE, TRUE,	sDataRead1);
										if (m_hDataWrit[0] && m_hDataWrit[1] && m_hDataRead[0] && m_hDataRead[1])
										{
											m_hSecondInstanceAvailable = CreateEvent(NULL, FALSE, FALSE, sName);
											if (m_hSecondInstanceAvailable)
											{
												if (m_nInstanceID == 0)
												{
													if (WaitForSingleObject(m_hSecondInstanceAvailable, nTimeOut) == WAIT_OBJECT_0)
													{
														CloseHandle(m_hSecondInstanceAvailable);
														ResetEvent(m_hClosed);
														m_hQueueMutex	= CreateMutex(NULL, FALSE, NULL);
														m_hDataInQueue	= CreateEvent(NULL, FALSE, FALSE, NULL);
														m_hQueueThread	= (HANDLE)_beginthread(QueueThread, 0, this);
														return true;
													}
												}
												else if (m_nInstanceID == 1)
												{
													SetEvent(m_hSecondInstanceAvailable);
													if (WaitForSingleObject(m_hSecondInstanceAvailable, 0) == WAIT_TIMEOUT)
													{
														CloseHandle(m_hSecondInstanceAvailable);
														ResetEvent(m_hClosed);
														m_hQueueMutex	= CreateMutex(NULL, FALSE, NULL);
														m_hDataInQueue	= CreateEvent(NULL, FALSE, FALSE, NULL);
														m_hQueueThread	= (HANDLE)_beginthread(QueueThread, 0, this);
														return true;
													}
												}
												CloseHandle(m_hSecondInstanceAvailable);
											}
										}
										UnmapViewOfFile(m_pSMem[0]);
										UnmapViewOfFile(m_pSMem[1]);
									}
								}
								UnmapViewOfFile(m_pSize);
							}
							CloseHandle(m_hSMem[0]);
							CloseHandle(m_hSMem[1]);
						}
					}
					CloseHandle(m_hSMemMutex[0]);
					CloseHandle(m_hSMemMutex[1]);
				}
			}
		}
	}
	return FALSE;
}
void SH_SMem::Close()
{
	if (WaitForSingleObject(m_hClosed, 0) == WAIT_TIMEOUT)
	{
		SetEvent(m_hClosed);

		ReleaseMutex(m_hSMemMutex[m_nInstanceID]);

		EmptyWriteQueue();

		WaitForSingleObject(m_hQueueThread, INFINITE);
		CloseHandle(m_hQueueMutex);
		CloseHandle(m_hDataInQueue);
		m_hQueueMutex	= NULL;
		m_hDataInQueue	= NULL;

		CloseHandle(m_hDataWrit[0]);
		CloseHandle(m_hDataWrit[1]);
		CloseHandle(m_hDataRead[0]);
		CloseHandle(m_hDataRead[1]);
		m_hDataWrit[0] = NULL;
		m_hDataWrit[1] = NULL;
		m_hDataRead[0] = NULL;
		m_hDataRead[1] = NULL;

		UnmapViewOfFile(m_pSize);

		m_pSMem[0] -= sizeof(int);
		m_pSMem[1] -= sizeof(int);
		UnmapViewOfFile(m_pSMem[0]);
		UnmapViewOfFile(m_pSMem[1]);
		
		CloseHandle(m_hSMem[0]);
		CloseHandle(m_hSMem[1]);

		CloseHandle(m_hSMemMutex[0]);
		CloseHandle(m_hSMemMutex[1]);

	}
}
int SH_SMem::Write(void *pData, int nDataSize, DWORD dwTimeOut)
{
	HANDLE	hWait[3];
	hWait[0]	= m_hClosed;
	hWait[1]	= m_hSMemMutex[m_nOtherInstanceID];
	hWait[2]	= m_hDataRead[m_nOtherInstanceID];
	DWORD	dwWaitResult = WaitForMultipleObjects(3, hWait, FALSE, dwTimeOut);
	switch(dwWaitResult)
	{
	case WAIT_OBJECT_0 + 2:
		if (nDataSize > *m_pSize)
			return SH_SMEM_ERROR_DATASIZE;
		memcpy(m_pSMem[m_nOtherInstanceID], pData, nDataSize);
		SetEvent(m_hDataWrit[m_nOtherInstanceID]);
		return SH_SMEM_SUCCESS;

	case WAIT_OBJECT_0:
		return SH_SMEM_ERROR_CLOSED;

	case WAIT_OBJECT_0 + 1:
		ReleaseMutex(m_hSMemMutex[m_nOtherInstanceID]);
		return SH_SMEM_ERROR_OTHERPARTY;

	case WAIT_ABANDONED_0 + 1:
		ReleaseMutex(m_hSMemMutex[m_nOtherInstanceID]);
		return SH_SMEM_ERROR_OTHERPARTY;

	case WAIT_FAILED:
		if (!m_hDataRead[m_nOtherInstanceID])
			return SH_SMEM_ERROR_CLOSED;
		return SH_SMEM_ERROR_UNKNOWN;

	case WAIT_TIMEOUT:
		return SH_SMEM_ERROR_TIMEOUT;
	}

	return SH_SMEM_ERROR_UNKNOWN;
}
int SH_SMem::WriteToQueue(void *pData, int nDataSize)
{
	HANDLE	hWait[3];
	hWait[0]	= m_hClosed;
	hWait[1]	= m_hSMemMutex[m_nOtherInstanceID];
	hWait[2]	= m_hQueueMutex;
	switch (WaitForMultipleObjects(3, hWait, FALSE, INFINITE))
	{
	case WAIT_OBJECT_0:
		return SH_SMEM_ERROR_CLOSED;

	case WAIT_OBJECT_0 + 2:
		{
			if (nDataSize > *m_pSize)
				return SH_SMEM_ERROR_DATASIZE;
			SH_WriteQue *pNew = new SH_WriteQue(*m_pSize);
			memcpy(pNew->pData, pData, *m_pSize);

			if (!m_pFirst)
				m_pFirst = pNew;
			else
			{
				SH_WriteQue *pCurrent = m_pFirst;
				while (pCurrent->pNext)
					pCurrent = pCurrent->pNext;
				pCurrent->pNext = pNew;
			}

			SetEvent(m_hDataInQueue);
			ReleaseMutex(m_hQueueMutex);
		}
		return SH_SMEM_SUCCESS;

	case WAIT_OBJECT_0 + 1:
		ReleaseMutex(m_hSMemMutex[m_nOtherInstanceID]);
		return SH_SMEM_ERROR_OTHERPARTY;

	case WAIT_ABANDONED_0 + 1:
		ReleaseMutex(m_hSMemMutex[m_nOtherInstanceID]);
		return SH_SMEM_ERROR_OTHERPARTY;

	case WAIT_FAILED:
		if (!m_hQueueMutex)
			return SH_SMEM_ERROR_CLOSED;
		return SH_SMEM_ERROR_UNKNOWN;

	}
	return SH_SMEM_ERROR_UNKNOWN;
}
int SH_SMem::Read(void *pData, int nDataSize, DWORD dwTimeOut)
{
	HANDLE	hWait[3];
	hWait[0]	= m_hDataWrit[m_nInstanceID];
	hWait[1]	= m_hClosed;
	hWait[2]	= m_hSMemMutex[m_nOtherInstanceID];
	DWORD	dwWaitResult = WaitForMultipleObjects(3, hWait, FALSE, dwTimeOut);
	switch(dwWaitResult)
	{
	case WAIT_OBJECT_0:
		if (nDataSize > *m_pSize)
			return SH_SMEM_ERROR_DATASIZE;
		memcpy(pData, m_pSMem[m_nInstanceID], nDataSize);
		SetEvent(m_hDataRead[m_nInstanceID]);
		return SH_SMEM_SUCCESS;

	case WAIT_OBJECT_0 + 1:
		return SH_SMEM_ERROR_CLOSED;

	case WAIT_OBJECT_0 + 2:
		ReleaseMutex(m_hSMemMutex[m_nOtherInstanceID]);
		return SH_SMEM_ERROR_OTHERPARTY;

	case WAIT_ABANDONED_0 + 2:
		ReleaseMutex(m_hSMemMutex[m_nOtherInstanceID]);
		return SH_SMEM_ERROR_OTHERPARTY;

	case WAIT_FAILED:
		if (!m_hDataWrit[m_nInstanceID])
			return SH_SMEM_ERROR_CLOSED;
		return SH_SMEM_ERROR_UNKNOWN;

	case WAIT_TIMEOUT:
		return SH_SMEM_ERROR_TIMEOUT;

	}
	return SH_SMEM_ERROR_UNKNOWN;
}

void SH_SMem::EmptyWriteQueue()
{
	while (m_pFirst && WaitForSingleObject(m_hQueueMutex, INFINITE) == WAIT_OBJECT_0)
	{
		if (m_pFirst)
		{
			SH_WriteQue *pQueue = m_pFirst;
			m_pFirst = pQueue->pNext;
			delete pQueue;
		}
		ReleaseMutex(m_hQueueMutex);
	}
}
void SH_SMem::QueueThread(void *pArg)
{
	SH_SMem	*pThis = (SH_SMem*)pArg;
	HANDLE hWait[2] = {pThis->m_hClosed, pThis->m_hDataInQueue};
	bool bQuit = false;
	while (!bQuit)
	{
		switch (WaitForMultipleObjects(2, hWait, FALSE, INFINITE))
		{
		case WAIT_OBJECT_0 + 1:
			{
				BYTE *pData = NULL;
				while (pThis->m_pFirst && WaitForSingleObject(pThis->m_hQueueMutex, INFINITE) == WAIT_OBJECT_0)
				{
					if (pThis->m_pFirst)
					{
						// First get the first element of the queue
						SH_WriteQue *pQueue = pThis->m_pFirst;
						pData = new BYTE[*pThis->m_pSize];
						memcpy(pData, pThis->m_pFirst->pData, *pThis->m_pSize);
						pThis->m_pFirst = pQueue->pNext;
						delete pQueue;
						ReleaseMutex(pThis->m_hQueueMutex);
			
						pThis->Write(pData, *pThis->m_pSize, INFINITE);
						delete [] pData;
					}
					else
						ReleaseMutex(pThis->m_hQueueMutex);
				}
			}
			break;

		case WAIT_OBJECT_0:
			bQuit = true;
			break;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -