spShareMemoryBase.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. #include "precompile.h"
  2. #include "spShareMemoryBase.h"
  3. #include <strstream>
  4. #include <Shlwapi.h>
  5. #include "sp_dir.h"
  6. #define MAX_ENTITY_NUM 20
  7. #define ENTITY_LOCK_NAME "Entity_Connect_Lock"
  8. #define LOG_LOCK_NAME "Entity_Log_Lock"
  9. #pragma data_seg("CONNECT_INFO")
  10. ENTITY_CONNECT_INFO m_connectInfo[MAX_ENTITY_NUM] = {ENTITY_CONNECT_INFO()};
  11. int m_priorLink = -1;
  12. bool m_infoInit = false;
  13. #pragma data_seg()
  14. #pragma comment(linker,"/section:CONNECT_INFO,rws")
  15. CMyLogFile m_log;
  16. BOOL connectControl::Lock(DWORD dwTime)
  17. {
  18. if (!m_hLock)
  19. {
  20. std::string strLockName = ENTITY_LOCK_NAME;
  21. m_hLock = ::CreateMutex(NULL, FALSE, strLockName.c_str());
  22. if (!m_hLock)
  23. return FALSE;
  24. }
  25. // whose priority is higher, when occupies this lock.
  26. DWORD dwRet = ::WaitForSingleObject(m_hLock, dwTime);
  27. return (dwRet == WAIT_OBJECT_0 || dwRet == WAIT_ABANDONED);
  28. }
  29. void connectControl::Unlock()
  30. {
  31. if (m_hLock)
  32. ::ReleaseMutex(m_hLock);
  33. }
  34. connectControl::connectControl()
  35. :m_hLock(NULL)
  36. {
  37. if (!m_infoInit)
  38. {
  39. for (int i = 0; i < MAX_ENTITY_NUM; i++)
  40. m_connectInfo[i].clear();
  41. m_infoInit = true;
  42. }
  43. }
  44. connectControl::~connectControl()
  45. {
  46. if (m_hLock != NULL)
  47. CloseHandle(m_hLock);
  48. }
  49. connectControl* connectControl::getInstance()
  50. {
  51. static connectControl* Instance = NULL;
  52. if (NULL == Instance)
  53. Instance = new connectControl();
  54. return Instance;
  55. }
  56. int connectControl::getEntityNum()
  57. {
  58. int entityNum = 0;
  59. for (int i = 0; i < MAX_ENTITY_NUM; i++)
  60. {
  61. if (0 != strlen(m_connectInfo[i].m_EntityName))
  62. entityNum++;
  63. else
  64. break;
  65. }
  66. return entityNum;
  67. }
  68. int connectControl::getPriorLink(int lastLink)
  69. {
  70. static int diffTimes = 0;
  71. if (-1 == lastLink)
  72. return m_priorLink;
  73. else if (lastLink != m_priorLink)
  74. {
  75. int tempLink = (0 == ++diffTimes % 5) ? m_priorLink : lastLink;
  76. m_log.LOGERROR("Try to link to %d", tempLink);
  77. return tempLink;
  78. }
  79. return lastLink;
  80. }
  81. void connectControl::setLastLink(int link){
  82. if (-1 == link || -1 == m_priorLink)
  83. {
  84. m_priorLink = link;
  85. return;
  86. }
  87. else if (link != m_priorLink)
  88. {
  89. int entityNum = getEntityNum();
  90. int diffNum = 0;
  91. for (int i = 0; i < entityNum; i++)
  92. {
  93. if (m_priorLink != m_connectInfo[i].m_lastLink)
  94. diffNum++;
  95. }
  96. if (diffNum >(entityNum / 2))
  97. m_priorLink = link;//change prior Link when half of the connection links to another connection
  98. }
  99. }
  100. bool connectControl::getSuccessDual(ENTITY_CONNECT_INFO *entityInfo)
  101. {
  102. if (NULL == entityInfo)
  103. return false;
  104. int entityNum = getEntityNum();
  105. for (int i = 0; i < entityNum; i++)
  106. {
  107. if (1 == m_connectInfo[i].m_DualActive && -1 != m_connectInfo[i].m_currentLink)
  108. {
  109. memcpy(entityInfo, &(m_connectInfo[i]), sizeof(ENTITY_CONNECT_INFO));
  110. return true;
  111. }
  112. }
  113. return false;
  114. }
  115. bool connectControl::getEntityInfo(const char *entityName, ENTITY_CONNECT_INFO *entityInfo)
  116. {
  117. if (NULL == entityName || NULL == entityInfo)
  118. return false;
  119. int entityNum = getEntityNum();
  120. for (int i = 0; i < entityNum; i++)
  121. {
  122. if (!strcmp(entityName, m_connectInfo[i].m_EntityName))
  123. {
  124. memcpy(entityInfo, &(m_connectInfo[i]), sizeof(ENTITY_CONNECT_INFO));
  125. return true;
  126. }
  127. }
  128. return false;
  129. }
  130. bool connectControl::setEntityInfo(const ENTITY_CONNECT_INFO *entityInfo)
  131. {
  132. if (NULL == entityInfo)
  133. return false;
  134. Lock(INFINITE);
  135. __try
  136. {
  137. int entityNum = getEntityNum();
  138. for (int i = 0; i < entityNum; i++)
  139. {
  140. if (!strcmp(entityInfo->m_EntityName, m_connectInfo[i].m_EntityName))
  141. {
  142. m_connectInfo[i].setParam(entityInfo->m_EntityName, entityInfo->m_ServerIP, entityInfo->m_ServerPort,
  143. entityInfo->m_Server_BackupIP, entityInfo->m_Server_BackupPort, entityInfo->m_DualActive, entityInfo->m_currentLink);
  144. return true;
  145. }
  146. }
  147. if (MAX_ENTITY_NUM == entityNum)
  148. return false;
  149. m_connectInfo[entityNum].setParam(entityInfo->m_EntityName, entityInfo->m_ServerIP, entityInfo->m_ServerPort,
  150. entityInfo->m_Server_BackupIP, entityInfo->m_Server_BackupPort, entityInfo->m_DualActive, entityInfo->m_currentLink);
  151. return true;
  152. }
  153. __finally
  154. {
  155. Unlock();
  156. }
  157. return false;
  158. }
  159. CMyLogFile::CMyLogFile()
  160. : m_cOutFile(NULL), m_hLock(nullptr)
  161. {
  162. }
  163. CMyLogFile::~CMyLogFile()
  164. {
  165. }
  166. void CMyLogFile::Output(const TCHAR *data)
  167. {
  168. if (NULL != m_cOutFile)
  169. m_cOutFile->write(data, strlen(data));
  170. }
  171. bool checkDirExist(char *filePath)
  172. {
  173. bool b = CreateDirectoryA(filePath, NULL);
  174. if (b || (GetLastError() == ERROR_ALREADY_EXISTS))
  175. return true;
  176. return false;
  177. }
  178. void CMyLogFile::Init()
  179. {
  180. if (!m_cOutFile)
  181. {
  182. char m_dirPath[_MAX_PATH] = "", drivePath[_MAX_DRIVE] = "";
  183. sp_dir_get_cur_drive(drivePath);
  184. sprintf_s(m_dirPath, _MAX_PATH, "%s\\rvc\\dbg\\DualActive", drivePath);
  185. if (!checkDirExist(m_dirPath))
  186. return;
  187. SYSTEMTIME cur;
  188. GetSystemTime(&cur);
  189. sprintf(m_dirPath, "%s\\%4d%.2d%.2d.log", m_dirPath, cur.wYear, cur.wMonth,
  190. cur.wDay);
  191. m_cOutFile = new ofstream(m_dirPath, ios_base::app);
  192. if (m_cOutFile->is_open())
  193. return;
  194. delete m_cOutFile;
  195. m_cOutFile = NULL;
  196. }
  197. }
  198. void CMyLogFile::Release()
  199. {
  200. if (NULL != m_cOutFile)
  201. {
  202. m_cOutFile->close();
  203. delete m_cOutFile;
  204. m_cOutFile = NULL;
  205. }
  206. }
  207. BOOL CMyLogFile::Lock(DWORD dwTime)
  208. {
  209. if (!m_hLock)
  210. {
  211. std::string strLockName = LOG_LOCK_NAME;
  212. m_hLock = ::CreateMutex(NULL, FALSE, strLockName.c_str());
  213. if (!m_hLock)
  214. return FALSE;
  215. }
  216. DWORD dwRet = ::WaitForSingleObject(m_hLock, dwTime);
  217. return (dwRet == WAIT_OBJECT_0 || dwRet == WAIT_ABANDONED);
  218. }
  219. void CMyLogFile::Unlock()
  220. {
  221. if (m_hLock)
  222. ::ReleaseMutex(m_hLock);
  223. }
  224. bool CMyLogFile::GetRootDir(char *dirPath)
  225. {
  226. char pathbuf[1024] = "";
  227. int pathlen = ::GetModuleFileNameA(NULL, pathbuf, 1024);//���GuiConsole·��
  228. // �滻������
  229. int times = 0;
  230. while (pathlen > 0)
  231. {
  232. if (pathbuf[pathlen--] == '\\')
  233. times++;
  234. if (2 == times)
  235. break;
  236. }
  237. pathbuf[++pathlen] = '\0';
  238. memcpy(dirPath, pathbuf, (pathlen + 1 > 1024 ? 1024 : pathlen + 1));
  239. return pathlen;
  240. }
  241. void CMyLogFile::PrintCurTime()
  242. {
  243. TCHAR dateString[52];
  244. SYSTEMTIME cur;
  245. GetLocalTime(&cur);
  246. sprintf(dateString, "[%4d-%.2d-%.2d,%.2d:%.2d:%.2d] ", cur.wYear, cur.wMonth,
  247. cur.wDay, cur.wHour, cur.wMinute, cur.wSecond);
  248. Output(dateString);
  249. }
  250. CMyLogFile& CMyLogFile::operator <<(unsigned int unVal)
  251. {
  252. strstream tmp;
  253. tmp << unVal;
  254. tmp << '\0';
  255. TCHAR* output = tmp.str();
  256. Output(output);
  257. tmp.freeze(false);
  258. return *this;
  259. }
  260. CMyLogFile& CMyLogFile::operator <<(long lVal)
  261. {
  262. strstream tmp;
  263. tmp << lVal;
  264. tmp << '\0';
  265. TCHAR* output = tmp.str();
  266. Output(output);
  267. tmp.freeze(false);
  268. return *this;
  269. }
  270. CMyLogFile& CMyLogFile::operator <<(const TCHAR* str)
  271. {
  272. Output(str);
  273. return *this;
  274. }
  275. CMyLogFile& CMyLogFile::operator <<(TCHAR tch)
  276. {
  277. TCHAR szCh[2];
  278. szCh[0] = tch;
  279. szCh[1] = '\0';
  280. Output(szCh);
  281. return *this;
  282. }
  283. CMyLogFile& CMyLogFile::operator <<(int nVal)
  284. {
  285. strstream tmp;
  286. tmp << nVal;
  287. tmp << '\0';
  288. TCHAR* output = tmp.str();
  289. Output(output);
  290. tmp.freeze(false);
  291. return *this;
  292. }
  293. CMyLogFile& CMyLogFile::operator <<(unsigned long ulVal)
  294. {
  295. strstream tmp;
  296. tmp << ulVal;
  297. tmp << '\0';
  298. TCHAR* output = tmp.str();
  299. Output(output);
  300. tmp.freeze(false);
  301. return *this;
  302. }
  303. CMyLogFile& CMyLogFile::operator <<(double dVal)
  304. {
  305. strstream tmp;
  306. tmp << dVal;
  307. tmp << '\0';
  308. TCHAR* output = tmp.str();
  309. Output(output);
  310. tmp.freeze(false);
  311. return *this;
  312. }
  313. CMyLogFile& CMyLogFile::operator <<(u__int64_t unllVal)
  314. {
  315. strstream tmp;
  316. tmp << unllVal;
  317. tmp << '\0';
  318. TCHAR* output = tmp.str();
  319. Output(output);
  320. tmp.freeze(false);
  321. return *this;
  322. }
  323. void CMyLogFile::LOGERROR(TCHAR* formatString, ...)
  324. {
  325. Lock(INFINITE);
  326. Init();
  327. __try{
  328. if (NULL != m_cOutFile && !m_cOutFile->is_open())
  329. return;
  330. /*
  331. ** Insert the current time..
  332. */
  333. PrintCurTime();
  334. /*
  335. ** Parse the format string and write to the file
  336. */
  337. if (formatString == NULL)
  338. {
  339. /*
  340. ** No point in continuiing
  341. */
  342. return;
  343. }
  344. va_list argList;
  345. /*
  346. ** Set va_list to the beginning of optional arguments
  347. */
  348. va_start(argList, formatString);
  349. TCHAR* ptr = formatString;
  350. while (*ptr != '\0')
  351. {
  352. TCHAR* str = NULL;
  353. int nInteger = 0;
  354. unsigned int unInt = 0;
  355. long lLong = 0;
  356. unsigned long ulLong = 0;
  357. double dDoub = 0;
  358. u__int64_t ullLong = 0;
  359. if (*ptr == '%')
  360. {
  361. switch (*(ptr + 1))
  362. {
  363. case 's':
  364. str = va_arg(argList, TCHAR*);
  365. if (NULL == str)
  366. break;
  367. *this << str;
  368. ptr++;
  369. break;
  370. case 'd':
  371. nInteger = va_arg(argList, int);
  372. *this << nInteger;
  373. ptr++;
  374. break;
  375. case 'u':
  376. unInt = va_arg(argList, unsigned int);
  377. *this << unInt;
  378. ptr++;
  379. break;
  380. case 'l':
  381. ptr++;
  382. if (*(ptr + 1) == 'd')
  383. {
  384. lLong = va_arg(argList, long);
  385. *this << lLong;
  386. ptr++;
  387. }
  388. else if (*(ptr + 1) == 'u')
  389. {
  390. ulLong = va_arg(argList, unsigned long);
  391. *this << ulLong;
  392. ptr++;
  393. }
  394. else if (*(ptr + 1) == 'q')
  395. {
  396. ullLong = va_arg(argList, u__int64_t);
  397. *this << ullLong;
  398. ptr++;
  399. }
  400. break;
  401. case 'f':
  402. dDoub = va_arg(argList, double);
  403. *this << dDoub;
  404. ptr++;
  405. break;
  406. default:
  407. *this << *ptr;
  408. }
  409. } // if(*ptr == '%')
  410. else
  411. {
  412. *this << *ptr;
  413. }
  414. /*
  415. ** Increment pointer..
  416. */
  417. ptr++;
  418. }
  419. va_end(argList); //va_end missing.
  420. *this << '\n';
  421. }
  422. __finally
  423. {
  424. Release();
  425. Unlock();
  426. }
  427. }