LogFileSaveThread.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include "stdafx.h"
  2. #include "CircleBuff.h"
  3. #include "FileManager.h"
  4. #include "LogFileSaveThread.h"
  5. #define WRITECACHE (1024 * 512)
  6. #define THELOGTIMEOUT (2000)
  7. LogFileSaveThread::LogFileSaveThread()
  8. {
  9. printf("==========LogFileSaveThread::LogFileSaveThread this: 0x%08x 0X%08X \n", (DWORD)this, GetCurrentThreadId());
  10. m_pWriteCache = new char[WRITECACHE];
  11. SetName("CcosLogger");
  12. }
  13. LogFileSaveThread::~LogFileSaveThread()
  14. {
  15. StopThread();
  16. delete[]m_pWriteCache;
  17. }
  18. bool LogFileSaveThread::Exec()
  19. {
  20. DWORD wait = 0;
  21. //loop
  22. HANDLE evt[2] = { m_ExitFlag, m_WorkFlag };
  23. while (1)
  24. {
  25. wait = WaitForMultipleObjects(2, evt, FALSE, THELOGTIMEOUT);
  26. if (wait == WAIT_TIMEOUT)
  27. {
  28. //1.timeout,dosave
  29. DoSaveProcedure();
  30. }
  31. else if (wait == WAIT_OBJECT_0 + 1)
  32. {
  33. //2.notify,dosave
  34. DoSaveProcedure();
  35. }
  36. else if (wait == WAIT_OBJECT_0)
  37. {
  38. //3.exit,do the save and exit
  39. DoSaveProcedure();
  40. return false;
  41. }
  42. else
  43. {
  44. //unexpected event
  45. }
  46. }
  47. return true;
  48. }
  49. bool LogFileSaveThread::DoSaveProcedure()
  50. {
  51. if (g_Circle.m_UsedSize == 0)
  52. {
  53. return true;
  54. }
  55. //lock all
  56. g_BlockMap.Thread_Lock();
  57. g_Circle.Thread_Lock();
  58. //copy map&clear
  59. map<DWORD, BlockInfo> BlockMap = g_BlockMap.m_Block;
  60. g_BlockMap.ClearMapInfo();
  61. //copy circle info
  62. DWORD UsedSize = g_Circle.m_UsedSize;
  63. DWORD BasePos = g_Circle.m_BasePos;
  64. DWORD HeadPos = g_Circle.m_HeadPos;
  65. //unlock all
  66. g_Circle.Thread_UnLock();
  67. g_BlockMap.Thread_UnLock();
  68. //loop map
  69. map<DWORD, BlockInfo>::iterator iter = BlockMap.begin();
  70. while (iter != BlockMap.end())
  71. {
  72. //check context
  73. if (iter->second.m_TotalSize == 0)
  74. {
  75. ++iter;
  76. continue;
  77. }
  78. //prep file
  79. if (g_Filemanager.PrepLogFile(iter->second.m_FileStatus, iter->second.m_FileName.c_str()) == false)
  80. {
  81. ++iter;
  82. continue;
  83. }
  84. //open file
  85. HANDLE filehandle = CreateFile(iter->second.m_FileName.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  86. if (filehandle == INVALID_HANDLE_VALUE)
  87. {
  88. ++iter;
  89. continue;
  90. }
  91. if (LockFile(filehandle, 0, 0, 1, 0) == FALSE)
  92. {
  93. CloseHandle(filehandle);
  94. ++iter;
  95. continue;
  96. }
  97. DWORD dwPos = SetFilePointer(filehandle, 0, 0, FILE_END);
  98. if (dwPos != INVALID_SET_FILE_POINTER)
  99. {
  100. DWORD copiedLen = 0;
  101. DWORD returnedLenth = 0;
  102. //loop mapid
  103. vector<BLOCKID>::iterator fileIter = iter->second.m_Block.begin();
  104. while (fileIter != iter->second.m_Block.end())
  105. {
  106. //assemble pices to writecache
  107. if (g_Circle.CopyContext(&(m_pWriteCache[copiedLen]), WRITECACHE - copiedLen, fileIter->Offset, fileIter->Size))
  108. {
  109. copiedLen += fileIter->Size;
  110. }
  111. else
  112. {
  113. //full
  114. //write file
  115. if (WriteFile(filehandle, m_pWriteCache, copiedLen, &returnedLenth, 0) == FALSE)
  116. {
  117. break;
  118. }
  119. //init
  120. copiedLen = 0;
  121. continue;//without fileIter++
  122. }
  123. ++fileIter;
  124. }
  125. if (copiedLen > 0)
  126. {
  127. //write file
  128. if (WriteFile(filehandle, m_pWriteCache, copiedLen, &returnedLenth, 0) == FALSE)
  129. {
  130. //log here
  131. }
  132. }
  133. }
  134. UnlockFile(filehandle, 0, 0, 1, 0);
  135. //close file
  136. CloseHandle(filehandle);
  137. ++iter;
  138. }
  139. //lock circle
  140. g_Circle.Thread_Lock();
  141. //update circle info
  142. g_Circle.m_UsedSize -= UsedSize;
  143. g_Circle.m_BasePos = HeadPos;
  144. //unlock
  145. g_Circle.Thread_UnLock();
  146. return true;
  147. }
  148. LogFileSaveThread g_LogThread;