Thread and PostMessage and Pointer
-
Hi All! I have a Working Thread that send a message to the application by ::PostMessage, in parameter WPARAM a put it a pointer to a new class instace: SEND CODE
UINT CServerSocket::ThreadPipe(LPVOID pParam)
{
.
.
.
while(*bContinue) {EnterCriticalSection(&m_csPipeMsg);
.
.
.
pManageEventCommandData = new CGeneralData();pManageEventCommandData->SetSocketAddress(*pSocketAddress);
pManageEventCommandData->SetEvent(EventQCDReceiveSocketACK);
::PostMessage(aHwnd,WM_USER_MANAGE_EVENT_COMMAND,(WPARAM)pManageEventCommandData,(LPARAM)0);
.
.
.LeaveCriticalSection(&m_csPipeMsg);
::Sleep(200);
}
.
.
.
}RECEIVE CODE When I receive message the class instance is delete
LRESULT CMainFrame::OnManageEventCommand(WPARAM wParam, LPARAM lParam)
{
int nManageEventResult;
CString sMessage;// Puntatore dati generali
CGeneralData* pManageEventCommandData= reinterpret_cast(wParam);
if( pManageEventCommandData == NULL )
return 0;//<< Do somethings >>
if( pManageEventCommandData != NULL ) {
delete pManageEventCommandData;
pManageEventCommandData = NULL;
}return 0;
}This work fine, but the problem is......sometimes when I close the application I see memoryleaks, I think that the problem is legacy to the fact that the PostMessage does not come received and the class remains allotted...but I not sure... Any Idea :doh: Thanks in advance :)
Too many plans make the health badly!!
-
Hi All! I have a Working Thread that send a message to the application by ::PostMessage, in parameter WPARAM a put it a pointer to a new class instace: SEND CODE
UINT CServerSocket::ThreadPipe(LPVOID pParam)
{
.
.
.
while(*bContinue) {EnterCriticalSection(&m_csPipeMsg);
.
.
.
pManageEventCommandData = new CGeneralData();pManageEventCommandData->SetSocketAddress(*pSocketAddress);
pManageEventCommandData->SetEvent(EventQCDReceiveSocketACK);
::PostMessage(aHwnd,WM_USER_MANAGE_EVENT_COMMAND,(WPARAM)pManageEventCommandData,(LPARAM)0);
.
.
.LeaveCriticalSection(&m_csPipeMsg);
::Sleep(200);
}
.
.
.
}RECEIVE CODE When I receive message the class instance is delete
LRESULT CMainFrame::OnManageEventCommand(WPARAM wParam, LPARAM lParam)
{
int nManageEventResult;
CString sMessage;// Puntatore dati generali
CGeneralData* pManageEventCommandData= reinterpret_cast(wParam);
if( pManageEventCommandData == NULL )
return 0;//<< Do somethings >>
if( pManageEventCommandData != NULL ) {
delete pManageEventCommandData;
pManageEventCommandData = NULL;
}return 0;
}This work fine, but the problem is......sometimes when I close the application I see memoryleaks, I think that the problem is legacy to the fact that the PostMessage does not come received and the class remains allotted...but I not sure... Any Idea :doh: Thanks in advance :)
Too many plans make the health badly!!
This work fine, but the problem is......sometimes when I close the application I see memoryleaks, I think that the problem is legacy to the fact that the PostMessage does not come received and the class remains allotted...but I not sure... I guess you are right unless there are no other places where you do new/delete. To make yourself sure of what happening I advise you to put TRACEs inside CGeneralData's ctor and dtor, and observe them; they should have been called equally. Anyway, there is a synchronization gap in the way the two threads communicate. Another level of uncertainty is caused by PostMessage which simply enqueues the message which some time later it will have been processed [actually between this duration you close the app and the message will not've been processed; thus there'd be a leak]. Another issue is the looping inside ThreadPipe; this worker thread should exit when the UI thread exits. So use CEvent to inform to the worker thread from the UI one. See here[^] for more details. In this case, when you garrantee that the worker thread will get known about the fact app exits, it would be possible to overcome the memory leak by not posting but sending (using SendMessage). But this may harm the functional logic of the app. And I am pretty sure there is no obvious solution to this situation. If you redesign it, you could omit the 'new' inside the worker thread and do it inside the ui one; just post a message and let the ui thread do the new/delete part.
-- ===== Arman
-
This work fine, but the problem is......sometimes when I close the application I see memoryleaks, I think that the problem is legacy to the fact that the PostMessage does not come received and the class remains allotted...but I not sure... I guess you are right unless there are no other places where you do new/delete. To make yourself sure of what happening I advise you to put TRACEs inside CGeneralData's ctor and dtor, and observe them; they should have been called equally. Anyway, there is a synchronization gap in the way the two threads communicate. Another level of uncertainty is caused by PostMessage which simply enqueues the message which some time later it will have been processed [actually between this duration you close the app and the message will not've been processed; thus there'd be a leak]. Another issue is the looping inside ThreadPipe; this worker thread should exit when the UI thread exits. So use CEvent to inform to the worker thread from the UI one. See here[^] for more details. In this case, when you garrantee that the worker thread will get known about the fact app exits, it would be possible to overcome the memory leak by not posting but sending (using SendMessage). But this may harm the functional logic of the app. And I am pretty sure there is no obvious solution to this situation. If you redesign it, you could omit the 'new' inside the worker thread and do it inside the ui one; just post a message and let the ui thread do the new/delete part.
-- ===== Arman
-
Hi All! I have a Working Thread that send a message to the application by ::PostMessage, in parameter WPARAM a put it a pointer to a new class instace: SEND CODE
UINT CServerSocket::ThreadPipe(LPVOID pParam)
{
.
.
.
while(*bContinue) {EnterCriticalSection(&m_csPipeMsg);
.
.
.
pManageEventCommandData = new CGeneralData();pManageEventCommandData->SetSocketAddress(*pSocketAddress);
pManageEventCommandData->SetEvent(EventQCDReceiveSocketACK);
::PostMessage(aHwnd,WM_USER_MANAGE_EVENT_COMMAND,(WPARAM)pManageEventCommandData,(LPARAM)0);
.
.
.LeaveCriticalSection(&m_csPipeMsg);
::Sleep(200);
}
.
.
.
}RECEIVE CODE When I receive message the class instance is delete
LRESULT CMainFrame::OnManageEventCommand(WPARAM wParam, LPARAM lParam)
{
int nManageEventResult;
CString sMessage;// Puntatore dati generali
CGeneralData* pManageEventCommandData= reinterpret_cast(wParam);
if( pManageEventCommandData == NULL )
return 0;//<< Do somethings >>
if( pManageEventCommandData != NULL ) {
delete pManageEventCommandData;
pManageEventCommandData = NULL;
}return 0;
}This work fine, but the problem is......sometimes when I close the application I see memoryleaks, I think that the problem is legacy to the fact that the PostMessage does not come received and the class remains allotted...but I not sure... Any Idea :doh: Thanks in advance :)
Too many plans make the health badly!!
-
Catch the WM_CLOSE message in your mainframe class and use PeekMessage to find any unprocessed WM_USER_MANAGE_EVENT_COMMAND in the message queue. If / when you find one, don't do any processing, just delete the pointer in the message. Judy