Reputation: 43
void CADAPBatchView::AddMsgToStatusWindow(const CString& strMsg)
{
CString strTemp;
CString strEngineStatusEntry;
int nLinesToScrollPast = 0;
int nTrimPos = 0;
strEngineStatusEntry.Format(_T("%s %s\n"), CTime::GetCurrentTime().Format( _T( "%H:%M:%S" )), strMsg);
CSingleLock singleLock( &m_csStatusMsg );
singleLock.Lock();
if (m_wndEngineStatusMsgs.GetLineCount() > 200)
{
m_wndEngineStatusMsgs.SetReadOnly(FALSE); //remove readonly so SetSel will work
m_wndEngineStatusMsgs.SetSel(0, m_wndEngineStatusMsgs.LineIndex(100));
m_wndEngineStatusMsgs.Clear();
m_wndEngineStatusMsgs.SetReadOnly(TRUE); //put back readonly
}
int nBegin;
nBegin = m_wndEngineStatusMsgs.GetTextLength();
m_wndEngineStatusMsgs.SetSel(nBegin, nBegin); // Select last character
m_wndEngineStatusMsgs.ReplaceSel(strEngineStatusEntry); // Append, move cursor to end of text
//m_wndEngineStatusMsgs.SetSel(-1,0); // Remove Black selection bars
//nBegin = m_wndEngineStatusMsgs.GetTextLength(); // Get New Length
//m_wndEngineStatusMsgs.SetSel(nBegin,nBegin); // Cursor to End of new text
nLinesToScrollPast = m_wndEngineStatusMsgs.GetLineCount() - 9 - m_wndEngineStatusMsgs.GetFirstVisibleLine();
m_wndEngineStatusMsgs.LineScroll( nLinesToScrollPast );
if (m_wndChkStatusMsgLog.GetCheck() == 1)
{
WriteToLogFile(strEngineStatusEntry);
}
return;
}
I have attached the code showing the two threads. At the time of the crash from the dump files I see that The main thread is at the line just after the singlelock.Lock()
. The second thread is at the line starting with nLinesToScrollPast
. I'm thinking a deadlock situation has occurred but don't know how. Any help is appreciated, thanks.
Upvotes: 0
Views: 587
Reputation: 6556
The problem is that you are trying to make method AddMsToStatusWindow
thread-safe in order to call it from other threads. Your problem is that only the main application thread is allowed to interact with the GUI otherwise you'll end up having problems with your message pump (because you do lock SendMessage
). So your design is wrong. You should create guarded message queue based on CCriticalSection
. So the thread would put the message to a queue and then call PostMessage
to notify the main thread that data/message has been put to a queue. The main thread will populate the data from this queue in message handler.
Upvotes: 2