#include "stdafx.h" #include "CircleBuff.h" #include "FileManager.h" #include "LogFileSaveThread.h" #define WRITECACHE (1024 * 512) #define THELOGTIMEOUT (2000) LogFileSaveThread::LogFileSaveThread() { printf("==========LogFileSaveThread::LogFileSaveThread this: 0x%08x 0X%08X \n", (DWORD)this, GetCurrentThreadId()); m_pWriteCache = new char[WRITECACHE]; SetName("CcosLogger"); } LogFileSaveThread::~LogFileSaveThread() { StopThread(); delete[]m_pWriteCache; } bool LogFileSaveThread::Exec() { DWORD wait = 0; //loop HANDLE evt[2] = { m_ExitFlag, m_WorkFlag }; while (1) { wait = WaitForMultipleObjects(2, evt, FALSE, THELOGTIMEOUT); if (wait == WAIT_TIMEOUT) { //1.timeout,dosave DoSaveProcedure(); } else if (wait == WAIT_OBJECT_0 + 1) { //2.notify,dosave DoSaveProcedure(); } else if (wait == WAIT_OBJECT_0) { //3.exit,do the save and exit DoSaveProcedure(); return false; } else { //unexpected event } } return true; } bool LogFileSaveThread::DoSaveProcedure() { if (g_Circle.m_UsedSize == 0) { return true; } //lock all g_BlockMap.Thread_Lock(); g_Circle.Thread_Lock(); //copy map&clear map BlockMap = g_BlockMap.m_Block; g_BlockMap.ClearMapInfo(); //copy circle info DWORD UsedSize = g_Circle.m_UsedSize; DWORD BasePos = g_Circle.m_BasePos; DWORD HeadPos = g_Circle.m_HeadPos; //unlock all g_Circle.Thread_UnLock(); g_BlockMap.Thread_UnLock(); //loop map map::iterator iter = BlockMap.begin(); while (iter != BlockMap.end()) { //check context if (iter->second.m_TotalSize == 0) { ++iter; continue; } //prep file if (g_Filemanager.PrepLogFile(iter->second.m_FileStatus, iter->second.m_FileName.c_str()) == false) { ++iter; continue; } //open file 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); if (filehandle == INVALID_HANDLE_VALUE) { ++iter; continue; } if (LockFile(filehandle, 0, 0, 1, 0) == FALSE) { CloseHandle(filehandle); ++iter; continue; } DWORD dwPos = SetFilePointer(filehandle, 0, 0, FILE_END); if (dwPos != INVALID_SET_FILE_POINTER) { DWORD copiedLen = 0; DWORD returnedLenth = 0; //loop mapid vector::iterator fileIter = iter->second.m_Block.begin(); while (fileIter != iter->second.m_Block.end()) { //assemble pices to writecache if (g_Circle.CopyContext(&(m_pWriteCache[copiedLen]), WRITECACHE - copiedLen, fileIter->Offset, fileIter->Size)) { copiedLen += fileIter->Size; } else { //full //write file if (WriteFile(filehandle, m_pWriteCache, copiedLen, &returnedLenth, 0) == FALSE) { break; } //init copiedLen = 0; continue;//without fileIter++ } ++fileIter; } if (copiedLen > 0) { //write file if (WriteFile(filehandle, m_pWriteCache, copiedLen, &returnedLenth, 0) == FALSE) { //log here } } } UnlockFile(filehandle, 0, 0, 1, 0); //close file CloseHandle(filehandle); ++iter; } //lock circle g_Circle.Thread_Lock(); //update circle info g_Circle.m_UsedSize -= UsedSize; g_Circle.m_BasePos = HeadPos; //unlock g_Circle.Thread_UnLock(); return true; } LogFileSaveThread g_LogThread;