#include "precompile.h" #include "spShareMemoryBase.h" #include #include #include "sp_dir.h" #define MAX_ENTITY_NUM 20 #define ENTITY_LOCK_NAME "Entity_Connect_Lock" #define LOG_LOCK_NAME "Entity_Log_Lock" #pragma data_seg("CONNECT_INFO") ENTITY_CONNECT_INFO m_connectInfo[MAX_ENTITY_NUM] = {ENTITY_CONNECT_INFO()}; int m_priorLink = -1; bool m_infoInit = false; #pragma data_seg() #pragma comment(linker,"/section:CONNECT_INFO,rws") CMyLogFile m_log; BOOL connectControl::Lock(DWORD dwTime) { if (!m_hLock) { std::string strLockName = ENTITY_LOCK_NAME; m_hLock = ::CreateMutex(NULL, FALSE, strLockName.c_str()); if (!m_hLock) return FALSE; } // whose priority is higher, when occupies this lock. DWORD dwRet = ::WaitForSingleObject(m_hLock, dwTime); return (dwRet == WAIT_OBJECT_0 || dwRet == WAIT_ABANDONED); } void connectControl::Unlock() { if (m_hLock) ::ReleaseMutex(m_hLock); } connectControl::connectControl() :m_hLock(NULL) { if (!m_infoInit) { for (int i = 0; i < MAX_ENTITY_NUM; i++) m_connectInfo[i].clear(); m_infoInit = true; } } connectControl::~connectControl() { if (m_hLock != NULL) CloseHandle(m_hLock); } connectControl* connectControl::getInstance() { static connectControl* Instance = NULL; if (NULL == Instance) Instance = new connectControl(); return Instance; } int connectControl::getEntityNum() { int entityNum = 0; for (int i = 0; i < MAX_ENTITY_NUM; i++) { if (0 != strlen(m_connectInfo[i].m_EntityName)) entityNum++; else break; } return entityNum; } int connectControl::getPriorLink(int lastLink) { static int diffTimes = 0; if (-1 == lastLink) return m_priorLink; else if (lastLink != m_priorLink) { int tempLink = (0 == ++diffTimes % 5) ? m_priorLink : lastLink; m_log.LOGERROR("Try to link to %d", tempLink); return tempLink; } return lastLink; } void connectControl::setLastLink(int link){ if (-1 == link || -1 == m_priorLink) { m_priorLink = link; return; } else if (link != m_priorLink) { int entityNum = getEntityNum(); int diffNum = 0; for (int i = 0; i < entityNum; i++) { if (m_priorLink != m_connectInfo[i].m_lastLink) diffNum++; } if (diffNum >(entityNum / 2)) m_priorLink = link;//change prior Link when half of the connection links to another connection } } bool connectControl::getSuccessDual(ENTITY_CONNECT_INFO *entityInfo) { if (NULL == entityInfo) return false; int entityNum = getEntityNum(); for (int i = 0; i < entityNum; i++) { if (1 == m_connectInfo[i].m_DualActive && -1 != m_connectInfo[i].m_currentLink) { memcpy(entityInfo, &(m_connectInfo[i]), sizeof(ENTITY_CONNECT_INFO)); return true; } } return false; } bool connectControl::getEntityInfo(const char *entityName, ENTITY_CONNECT_INFO *entityInfo) { if (NULL == entityName || NULL == entityInfo) return false; int entityNum = getEntityNum(); for (int i = 0; i < entityNum; i++) { if (!strcmp(entityName, m_connectInfo[i].m_EntityName)) { memcpy(entityInfo, &(m_connectInfo[i]), sizeof(ENTITY_CONNECT_INFO)); return true; } } return false; } bool connectControl::setEntityInfo(const ENTITY_CONNECT_INFO *entityInfo) { if (NULL == entityInfo) return false; Lock(INFINITE); __try { int entityNum = getEntityNum(); for (int i = 0; i < entityNum; i++) { if (!strcmp(entityInfo->m_EntityName, m_connectInfo[i].m_EntityName)) { m_connectInfo[i].setParam(entityInfo->m_EntityName, entityInfo->m_ServerIP, entityInfo->m_ServerPort, entityInfo->m_Server_BackupIP, entityInfo->m_Server_BackupPort, entityInfo->m_DualActive, entityInfo->m_currentLink); return true; } } if (MAX_ENTITY_NUM == entityNum) return false; m_connectInfo[entityNum].setParam(entityInfo->m_EntityName, entityInfo->m_ServerIP, entityInfo->m_ServerPort, entityInfo->m_Server_BackupIP, entityInfo->m_Server_BackupPort, entityInfo->m_DualActive, entityInfo->m_currentLink); return true; } __finally { Unlock(); } return false; } CMyLogFile::CMyLogFile() : m_cOutFile(NULL), m_hLock(nullptr) { } CMyLogFile::~CMyLogFile() { } void CMyLogFile::Output(const TCHAR *data) { if (NULL != m_cOutFile) m_cOutFile->write(data, strlen(data)); } bool checkDirExist(char *filePath) { bool b = CreateDirectoryA(filePath, NULL); if (b || (GetLastError() == ERROR_ALREADY_EXISTS)) return true; return false; } void CMyLogFile::Init() { if (!m_cOutFile) { char m_dirPath[_MAX_PATH] = "", drivePath[_MAX_DRIVE] = ""; sp_dir_get_cur_drive(drivePath); sprintf_s(m_dirPath, _MAX_PATH, "%s\\rvc\\dbg\\DualActive", drivePath); if (!checkDirExist(m_dirPath)) return; SYSTEMTIME cur; GetSystemTime(&cur); sprintf(m_dirPath, "%s\\%4d%.2d%.2d.log", m_dirPath, cur.wYear, cur.wMonth, cur.wDay); m_cOutFile = new ofstream(m_dirPath, ios_base::app); if (m_cOutFile->is_open()) return; delete m_cOutFile; m_cOutFile = NULL; } } void CMyLogFile::Release() { if (NULL != m_cOutFile) { m_cOutFile->close(); delete m_cOutFile; m_cOutFile = NULL; } } BOOL CMyLogFile::Lock(DWORD dwTime) { if (!m_hLock) { std::string strLockName = LOG_LOCK_NAME; m_hLock = ::CreateMutex(NULL, FALSE, strLockName.c_str()); if (!m_hLock) return FALSE; } DWORD dwRet = ::WaitForSingleObject(m_hLock, dwTime); return (dwRet == WAIT_OBJECT_0 || dwRet == WAIT_ABANDONED); } void CMyLogFile::Unlock() { if (m_hLock) ::ReleaseMutex(m_hLock); } bool CMyLogFile::GetRootDir(char *dirPath) { char pathbuf[1024] = ""; int pathlen = ::GetModuleFileNameA(NULL, pathbuf, 1024);//���GuiConsole·�� // �滻������ int times = 0; while (pathlen > 0) { if (pathbuf[pathlen--] == '\\') times++; if (2 == times) break; } pathbuf[++pathlen] = '\0'; memcpy(dirPath, pathbuf, (pathlen + 1 > 1024 ? 1024 : pathlen + 1)); return pathlen; } void CMyLogFile::PrintCurTime() { TCHAR dateString[52]; SYSTEMTIME cur; GetLocalTime(&cur); sprintf(dateString, "[%4d-%.2d-%.2d,%.2d:%.2d:%.2d] ", cur.wYear, cur.wMonth, cur.wDay, cur.wHour, cur.wMinute, cur.wSecond); Output(dateString); } CMyLogFile& CMyLogFile::operator <<(unsigned int unVal) { strstream tmp; tmp << unVal; tmp << '\0'; TCHAR* output = tmp.str(); Output(output); tmp.freeze(false); return *this; } CMyLogFile& CMyLogFile::operator <<(long lVal) { strstream tmp; tmp << lVal; tmp << '\0'; TCHAR* output = tmp.str(); Output(output); tmp.freeze(false); return *this; } CMyLogFile& CMyLogFile::operator <<(const TCHAR* str) { Output(str); return *this; } CMyLogFile& CMyLogFile::operator <<(TCHAR tch) { TCHAR szCh[2]; szCh[0] = tch; szCh[1] = '\0'; Output(szCh); return *this; } CMyLogFile& CMyLogFile::operator <<(int nVal) { strstream tmp; tmp << nVal; tmp << '\0'; TCHAR* output = tmp.str(); Output(output); tmp.freeze(false); return *this; } CMyLogFile& CMyLogFile::operator <<(unsigned long ulVal) { strstream tmp; tmp << ulVal; tmp << '\0'; TCHAR* output = tmp.str(); Output(output); tmp.freeze(false); return *this; } CMyLogFile& CMyLogFile::operator <<(double dVal) { strstream tmp; tmp << dVal; tmp << '\0'; TCHAR* output = tmp.str(); Output(output); tmp.freeze(false); return *this; } CMyLogFile& CMyLogFile::operator <<(u__int64_t unllVal) { strstream tmp; tmp << unllVal; tmp << '\0'; TCHAR* output = tmp.str(); Output(output); tmp.freeze(false); return *this; } void CMyLogFile::LOGERROR(TCHAR* formatString, ...) { Lock(INFINITE); Init(); __try{ if (NULL != m_cOutFile && !m_cOutFile->is_open()) return; /* ** Insert the current time.. */ PrintCurTime(); /* ** Parse the format string and write to the file */ if (formatString == NULL) { /* ** No point in continuiing */ return; } va_list argList; /* ** Set va_list to the beginning of optional arguments */ va_start(argList, formatString); TCHAR* ptr = formatString; while (*ptr != '\0') { TCHAR* str = NULL; int nInteger = 0; unsigned int unInt = 0; long lLong = 0; unsigned long ulLong = 0; double dDoub = 0; u__int64_t ullLong = 0; if (*ptr == '%') { switch (*(ptr + 1)) { case 's': str = va_arg(argList, TCHAR*); if (NULL == str) break; *this << str; ptr++; break; case 'd': nInteger = va_arg(argList, int); *this << nInteger; ptr++; break; case 'u': unInt = va_arg(argList, unsigned int); *this << unInt; ptr++; break; case 'l': ptr++; if (*(ptr + 1) == 'd') { lLong = va_arg(argList, long); *this << lLong; ptr++; } else if (*(ptr + 1) == 'u') { ulLong = va_arg(argList, unsigned long); *this << ulLong; ptr++; } else if (*(ptr + 1) == 'q') { ullLong = va_arg(argList, u__int64_t); *this << ullLong; ptr++; } break; case 'f': dDoub = va_arg(argList, double); *this << dDoub; ptr++; break; default: *this << *ptr; } } // if(*ptr == '%') else { *this << *ptr; } /* ** Increment pointer.. */ ptr++; } va_end(argList); //va_end missing. *this << '\n'; } __finally { Release(); Unlock(); } }