On Feb 6, 6:49 pm, "David Ching" <d...@remove-this.dcsoft.com> wrote:
"Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp> wrote in messagenews:uyHRcTOaIHA.3828@TK2MSFTNGP06.phx.gbl...
"David Ching" <d...@remove-this.dcsoft.com> wrote in message
news:Uqlqj.3900$uE.272@newssvr22.news.prodigy.net...
...The reader thread is a worker thread and has no CWinThread object to
delete.
That's not correct. Creating a worker thread does create a CWinThread,
and a pointer to it is returned. It should be deleted after it exits
(assuming m_bAutoDelete has been set FALSE).
Yes, you're right, thanks. I think it would be helpful to see ALL the
relevant code since I've long ago forgotten even why m_bAutoDelete needs to
be FALSE in the first place! ;)
-- David
Ok, finally I think I solved it...
I added a
delete pMySerial;
After WFSO in OnDestroy so I have no memory leaks now! Thank you.
About pReaderThread, I didn't set its m_bAutoDelete to FALSE, so I
suppose that I just need to WFSO for its m_hThread, isn't it?
This is my updated code with some comments:
First, creating the object:
(MySerial*) pMySerial = (MySerial*)
AfxBeginThread( RUNTIME_CLASS( MySerial ), THREAD_PRIORITY_NORMAL, 0,
CREATE_SUSPENDED );
That's ok. Then I call:
pMySerial->ResumeThread();
pMySerial->openPort( port_number );
Here is my class (serial port related code ommited)
//Open_port(), here I crete the pReaderThread, a worker thread that
reads serial port
BOOL MySerial::openPort( int port )
{
opened = TRUE;
ShutdownEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
pReaderThread = AfxBeginThread( ReaderThread, this,
THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED );
//pReaderThread->m_bAutoDelete = FALSE;
//pReaderThread->ResumeThread();
return TRUE;
}
//This is the famous ReaderThread, a worker thread that exits when
ShutDownEvent is signaled
UINT ReaderThread( LPVOID cT )
{
MySerial* SerialHandler = (MySerial*)cT;
HANDLE waiters[2];
waiters[0] = SerialHandler->ShutdownEvent;
waiters[1] = SerialHandler->ovReader.hEvent;
while( reading )
{
unsigned char buffer[MAX_BUFFER_SIZE];
BOOL ok = ::ReadFile( SerialHandler->hComm, buffer, MAX_BUFFER_SIZE
-1, &bytesRead, &SerialHandler->ovReader );
if( !ok )
{
//Some code...
DWORD result = ::WaitForMultipleObjects( 2, waiters, FALSE,
INFINITE );
switch( result )
{
case WAIT_OBJECT_0: //Event shutdown
reading = FALSE; //Here loop
quits
continue;
//More code
}
}
//More code to read
}
TRACE("\nREADER THREAD STOPPED.\n");
return 0;
}
//And finally, the closePort()
void MySerial::closePort( WPARAM wparam, LPARAM lparam)
{
TRACE("Hi!");
if( opened )
{
SetEvent( ShutdownEvent );
TRACE("closing pReaderThread.\n");
WaitForSingleObject( pReaderThread->m_hThread, INFINITE );
//If I set in openPort() pReader->Thread->m_bAutodelete = FALSE...
// CloseHandle( pReaderThread->m_hThread ); //...Here I've
got an Exception error
// delete pReaderThread; //
BOOL ok = PurgeComm( hComm, PURGE_RXABORT|PURGE_RXCLEAR );
::CloseHandle( WriteEvent );
::CloseHandle( ShutdownEvent );
::CloseHandle( ReadEvent );
::CloseHandle( hComm );
PostQuitMessage(0);
//PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0, 0);
opened = FALSE;
TRACE("THREAD STOPPED\n");
}
else
{
TRACE("Not opened.");
PostQuitMessage(0);
//PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0, 0);
}
}
And in my OnDestroy I do this:
void CUart3DEMODlg::OnDestroy()
{
CDialog::OnDestroy();
TRACE("closing port.\n");
if( serial_created ) //<<---Note this flag
{
TRACE("We have to kill pMySerial.\n");
pMySerial->ResumeThread();
pMySerial->PostThreadMessage( WM_MYSERIAL_CLOSE, 0, 0 );
WaitForSingleObject( pMySerial->m_hThread, INFINITE );
delete pMySerial;
TRACE("Port closed.\n");
}
}
I have to thank all people that helped me to find the solution,
But... one last thing (sorry):
The flag serial_created is true when I create pMySerial. When
serial_created is true at the moment of exit App, I must close it
properly.
But you'll agree with me that's shoddy... Is there a better way to
detect that pMySerial exists??
And again, thank you.
I have to correct the code posted above. In OnDestroy obviously the