Browse Source

关闭句和WaitNamPipe连接时,添加临界保护

JeffWang 3 years ago
parent
commit
e06ffe6a11

+ 84 - 0
Source/OGCAssist/OGCAssist/CritSection.h

@@ -0,0 +1,84 @@
+#ifndef __CRITSECTION_20160221__
+#define __CRITSECTION_20160221__
+
+// ÁÙ½çÖµ;
+class ThreadSection
+{
+public:
+	ThreadSection(){
+		HRESULT hr = Init();
+		(hr);
+	}
+
+	~ThreadSection(){
+		DeleteCriticalSection(&_CriticalSection);
+	}
+
+	bool Lock()
+	{
+		bool result = false;
+		__try
+		{
+			EnterCriticalSection(&_CriticalSection);
+			result = true;
+		}
+		__except (STATUS_NO_MEMORY == GetExceptionCode())
+		{
+		}
+		return result;
+	}
+
+	bool Unlock()
+	{
+		bool result = false;
+		__try
+		{
+			LeaveCriticalSection(&_CriticalSection);
+			result = true;
+		}
+		__except (STATUS_NO_MEMORY == GetExceptionCode())
+		{
+		}
+		return result;
+	}
+
+private:
+	HRESULT Init() throw()
+	{
+		HRESULT hRes = E_FAIL;
+		__try
+		{
+			InitializeCriticalSection(&_CriticalSection);
+			hRes = S_OK;
+		}
+		__except (STATUS_NO_MEMORY == GetExceptionCode())
+		{
+			hRes = E_OUTOFMEMORY;
+		}
+		return hRes;
+	}
+
+	ThreadSection(const ThreadSection & tSection);
+	ThreadSection &operator=(const ThreadSection & tSection);
+	CRITICAL_SECTION _CriticalSection;
+};
+
+
+class AutoThreadSection
+{
+public:
+	AutoThreadSection(IN ThreadSection* pSection){
+		_pSection = pSection;
+		_pSection->Lock();
+	}
+
+	~AutoThreadSection(){
+		_pSection->Unlock();
+	}
+private:
+	AutoThreadSection(const AutoThreadSection & tSection);
+	AutoThreadSection &operator=(const AutoThreadSection & tSection);
+	ThreadSection * _pSection;
+};
+
+#endif //__CRITSECTION_20160221__

+ 4 - 0
Source/OGCAssist/OGCAssist/OGCAssist.vcproj

@@ -327,6 +327,10 @@
 		<Filter
 			Name="Core"
 			>
+			<File
+				RelativePath=".\CritSection.h"
+				>
+			</File>
 			<File
 				RelativePath=".\OGCAssist.cpp"
 				>

+ 24 - 1
Source/OGCAssist/OGCAssist/PipeClient.cpp

@@ -6,6 +6,7 @@
 std::string CPipeClient::m_LastData;
 PER_IO_CONTEXT CPipeClient::m_IoRead;
 PER_IO_CONTEXT CPipeClient::m_IoWrite;
+ThreadSection CPipeClient::m_cs;
 
 CPipeClient::CPipeClient(LPCTSTR lpPipeName, DWORD dwMode)
 {
@@ -63,6 +64,7 @@ DWORD CPipeClient::ConnectThread(LPVOID lpParam)
         }
 
         // 等待10秒;
+		AutoThreadSection acs(&m_cs);
         if ( !WaitNamedPipe(pInstance->m_szPipeName, 10000) )
         {// 如果管道不存在,会立即返回而不考虑超时值,所以此处仍要Sleep;
             Utility::dprintf(_T("<%ld> WaitNamedPipe 失败\n"), Utility::g_WndInfo.dwProcessId);
@@ -174,6 +176,7 @@ DWORD CPipeClient::ReadMsgThread(LPVOID lpParam)
             if ( !WaitFinish(pInstance->m_hPipeInst, &m_IoRead) )
             {
                 // 出现错误;
+				AutoThreadSection acs(&m_cs);
                 Utility::dprintf(_T("CloseHandle\n"));
                 CloseHandle(pInstance->m_hPipeInst);
                 pInstance->m_hPipeInst = INVALID_HANDLE_VALUE;
@@ -419,7 +422,27 @@ BOOL CPipeClient::SendData(LPBYTE lpData, DWORD dwDataLen)
 	// 发送数据使用同步模式;
 	DWORD dwNumberOfBytesWritten = 0;
 	BOOL fWrite = WriteFile(m_hPipeInst, lpData, dwDataLen, &dwNumberOfBytesWritten, NULL);
-	Utility::dprintf(_T("SendData:Error=%ld, %d\n"), GetLastError(), fWrite);
+	DWORD dwLastError = GetLastError();
+	if ( dwLastError != 0 )
+		HandleError(dwLastError);
+	Utility::dprintf(_T("SendData:Error=%ld, %d\n"), dwLastError, fWrite);
 
 	return fWrite;
+}
+
+void CPipeClient::HandleError(DWORD dwError)
+{
+	switch(dwError)
+	{
+	case ERROR_NO_DATA:
+		{
+			AutoThreadSection acs(&m_cs);
+			CloseHandle(m_hPipeInst);
+			m_hPipeInst = INVALID_HANDLE_VALUE;
+			Utility::dprintf(_T("HandleError:Error=%ld\n"), dwError);
+		}
+		break;
+	default:
+		break;
+	}
 }

+ 3 - 1
Source/OGCAssist/OGCAssist/PipeClient.h

@@ -1,5 +1,6 @@
 #pragma once
 #include "Protocol.h"
+#include "CritSection.h"
 
 #define BUFSIZE 4096
 typedef struct _PER_IO_CONTEXT
@@ -48,6 +49,7 @@ private:
 
 	static std::string m_LastData;
 	static PER_IO_CONTEXT m_IoRead;
+	static ThreadSection m_cs;
 	// Write使用同步方式;
 	static PER_IO_CONTEXT m_IoWrite;
 public:
@@ -64,7 +66,7 @@ public:
 	// 发送消息给服务端;
 	BOOL SendPackage(PACKAGE &pak);
 	BOOL SendPackage(DATAHEADER &head, MSG_INFO &msg);
-
+	void HandleError(DWORD dwError);
 protected:
 	BOOL SendData(LPBYTE lpData, DWORD dwDataLen);
 };