#include "stdafx.h" typedef struct _MSG_ITEM{ SLIST_ENTRY ListEntry; char * strText; } MSG_ITEM, *PMSG_ITEM; HANDLE hEvent; SLIST_HEADER ListHead; void InitLogWriting(){ InitializeSListHead(&ListHead); // manual reset must be turned off hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); } void EndLogWriting(){ char * ptr = new char[sizeof(MSG_ITEM)]; PMSG_ITEM pListItem = (PMSG_ITEM) ptr; pListItem->strText = NULL; //insert new item into the list InterlockedPushEntrySList(&ListHead, &pListItem->ListEntry); //Signal emtpy message SetEvent(hEvent); } void WriteLogMessage(char * strMessage){ //allocate memory for text and for list item //+1 is needed for zero at the end of the string UINT iBufferLength = sizeof(MSG_ITEM) + strlen(strMessage) + 1; char * ptr = new char[iBufferLength]; PMSG_ITEM pListItem = (PMSG_ITEM) ptr; pListItem->strText = ptr + sizeof(MSG_ITEM); strcpy(pListItem->strText, strMessage); //insert new item into the list InterlockedPushEntrySList(&ListHead, &pListItem->ListEntry); //signal to log writer thread SetEvent(hEvent); } void ReverseSList(PSLIST_ENTRY * pHead){ SLIST_ENTRY * pPrev = NULL; SLIST_ENTRY * pThis = *pHead; SLIST_ENTRY * pNext = (*pHead)->Next; while(pThis->Next){ pNext = pThis->Next; pThis->Next = pPrev; pPrev = pThis; pThis = pNext; } //list tail pThis->Next = pPrev; *pHead = pThis; } DWORD LogWritingThreadRoutine(LPVOID lpParam){ PMSG_ITEM pListItem; PMSG_ITEM pPrevItem; char * pszText; while(WAIT_OBJECT_0==WaitForSingleObject(hEvent, INFINITE)){ //fetch all items from the list pListItem = (PMSG_ITEM) InterlockedFlushSList(&ListHead); //reverse fetched sub list to get FIFO order if (pListItem) ReverseSList(&pListItem); //process all fetched items while(pListItem){ pszText = pListItem->strText; //exit thread if an empty message is received if (!pszText){ //do not forget to call CloseHandle(hEvent) when //the entire process is exiting return 0; } //process message text //contained in pszText // for example, AfxMessageBox(pszText, 0, 0); MessageBox(NULL, pszText, NULL, 0); pPrevItem = pListItem; pListItem = (PMSG_ITEM) pListItem->ListEntry.Next; //now we can delete the entire list item //including message text delete [] (pPrevItem); } } return GetLastError(); }