Discussion:
detached thread deletion problem
(too old to reply)
Selçuk Cihan
2009-05-09 16:09:24 UTC
Permalink
Hi all, i am puzzled with the behaviour of my multithreaded application.

I start a detached wxThread for a certain event, and there is at most one
such thread at any time. After the worker thread starts, it starts doing its
task corresponding to the event. And then, if another such event is caught,
the code checks if the thread is running and if it is running it pushes the
new task(corresponding to the new event) to the task queue of the thread.
Access to the task queue is protected via a critical section.

To be able to push new tasks to the queue, GUI thread needs to control
deletion of the worker thread. For that, i post a "delete me" event to GUI
as soon as there are no jobs on the task queue and then GUI calls
thread->Delete() in the "delete me" event handler.

The thread has the main loop while(!TestDestroy()) { get task; do task; }

GUI's "delete me" event handler just does this:
thread->Delete();
thread = 0; /* to be able to determine later if the thread is running or not
*/

Now, the problem is, the execution never arrives at the above line that sets
thread to zero.

Having explained the problem, i wrote a minimal implementation for the above
thread behaviour and guess what, the execution does arrive at thread = 0
line, no problems. So i figure out the problem is not related to the
behaviour / logic explained in the beginning.
I am messing things up somewhere but i haven't been able to detect the cause
of the problem yet.

What would be the reason that, execution does not reach the line after
thread->Delete() ? By the way, the gui is not blocking after Delete() and
other things seem to go fine (gui catches events just fine).
Also, the thread actually gets destroyed and i can see its TestDestroy()
return false and its OnExit() function being reached.

Any ideas truely appreciated
Vadim Zeitlin
2009-05-09 23:14:39 UTC
Permalink
On Sat, 9 May 2009 19:09:24 +0300 Selçuk Cihan <***@gmail.com> wrote:

SC> The thread has the main loop while(!TestDestroy()) { get task; do task; }
SC>
SC> GUI's "delete me" event handler just does this:
SC> thread->Delete();
SC> thread = 0; /* to be able to determine later if the thread is running or not */
SC>
SC> Now, the problem is, the execution never arrives at the above line that sets
SC> thread to zero.

This can only happen if wither TestDestroy() is not executed in the thread
and so it never even attempts to terminate or it is and thread shutdown
starts but then a deadlock occurs and so it never finishes. It's really
hard to know what exactly happens in your case but if you're lucky enough
to be able to reproduce the problem you should be able to debug it fairly
easily by just looking at what the thread is doing when it hangs.

Good luck,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
Selçuk Cihan
2009-05-10 16:26:37 UTC
Permalink
By the way, i am using wxWidgets 2.8.10.
Post by Vadim Zeitlin
or it is and thread shutdown
starts but then a deadlock occurs and so it never finishes.
How can i be sure that there is indeed a deadlock? The main gui thread does
not hang, it just does not come out of thread->Delete() call so that the
next line does not execute. On the other hand, the thread's execution
reaches its OnExit() function.
Post by Vadim Zeitlin
you should be able to debug it fairly
easily by just looking at what the thread is doing when it hangs.
I tried to trace the execution, but could not figure out the problem. I will
try to explain the execution, hoping that you can help further.
when thread->Delete() is called, m_internal->WaitForTerminate(m_critsect,
pRc, this); call finds out shouldResume as "false"; that is, m_state is
STATE_PAUSED. shouldDelete is "true". Next, m_state becomes STATE_CANCELED.
Next, execution arrives at the "else" part of the following ifelse

if ( !wxRunningEventLoopCount )
{
// don't ask for Windows messages if we don't have a running
event
// loop to process them as otherwise we'd enter an infinite loop
// with MsgWaitForMultipleObjects() always returning
WAIT_OBJECT_0
// + 1 because the message would remain forever in the queue
result = ::WaitForSingleObject(m_hThread, INFINITE);
}
else // wait for thread termination without blocking the GUI
{
result = ::MsgWaitForMultipleObjects
(
1, // number of objects to wait for
&m_hThread, // the objects
false, // don't wait for all objects
INFINITE, // no timeout
QS_ALLINPUT | // return as soon as there are any
events
QS_ALLPOSTMESSAGE
);
}
and result becomes 1, corresponding to case WAIT_OBJECT_0 + 1: of following
switch
a call to traits->DoMessageFromThreadWait() returns true in that case of
switch
we continue with do while iteration, this time again result becomes 1.
However, this time when i step the call traits->DoMessageFromThreadWait()
the execution hits the breakpoint set at my thread's Entry function's return
statement. Anyway, traits->DoMessageFromThreadWait() returns true again and
do while continues two more times, in the last one result becomes 0 and do
while loop is exited.

Next an empty for loop comes
for( ;; )
in which
if ( (DWORD)rc != STILL_ACTIVE )
break;
the condition holds and we break out of the loop

pRc is 0
next Free() is called and the handle is freed successfully
WaitForTerminate function returns wxTHREAD_NO_ERROR finally. But a step over
in visual studio at the return statement does not act as i expect. Normally
i would expect it to become again to the call line
m_internal->WaitForTerminate(m_critsect, pRc, this); and then another step
would take me to thread->Delete() call and then i would be more than happy
to set thread = 0 safely
Selçuk Cihan
2009-05-10 21:17:22 UTC
Permalink
Hi, i have finally located the source of error. It is related to xerces-c,
xml library i am using. I still could not comprehend the problem exactly,
however i am glad that i got rid of the problem.

DOMDocument * doc;

doc->release() was my problem, it seems that i should not release the doc
which was created by doc = parser->getDocument()
it seems to me that the problem must be related to some weird stuff. I don't
see a reason for having troubles when releasing a resource that will
eventually be released by the library. If it were the other way around it
would have made sense. Anyways, i learned a lesson, i will try to stay away
from xercesc.

Thanks for help

Continue reading on narkive:
Search results for 'detached thread deletion problem' (Questions and Answers)
6
replies
what is the basic concept of God in Hinduism?
started 2006-10-20 20:34:20 UTC
religion & spirituality
Loading...