Discussion:
Destroyng threads help
(too old to reply)
dushkin
2011-07-04 18:55:29 UTC
Permalink
Hi All,

(Sorry for bad english)

I am having some troubles with destroying threads (I guess...)
I will try to describe the architucture very generally, and if more
information will be needed, I will apply.

I have a dialog based application. When I press a button, I create a
socket and calls its Listen method.
Every time, a connection is accepted, I create a new thread containg
two major objects - Another (CAsyncSocket based) socket - which
receives packets from the connection source and pushes them into a
CStringArray, and a new thread which pops the next packet from this
CStringArray object and handles it.

Both connection thread and handler thread are created using
AfxBeginThread.

I also used CCrticalSection object to protect the strings array from
being accessed by both thread at the same time.

Now, this packets handler thread has a timer which schedules the
packet pop out and then handling.

There might be ofcourse several connection requests from several
sources.

Also The packet handler main job is actually send some response (1 or
more).

My problem is that sometimes the connection is being reset. The
question is what I do then? I am suppose to close the connection and
wait for a new one.

But then, after all the attempts I made according to my best
knowledge, I always got the application to crash on some invalid
pointer.

In general, whenever the socket OnClose message handler was called, I
first killed the handler thread timer, and then called AfxEndThread(0)
to kill the handler thread. Then I called Sockets' ShutDown() and
Close() methods. But then I was stucked with the question how do I
kill the connection thread? and where?

But the code continues to execute and the application crashes on
access violation or reading violation, as far as I understood on the
connection thread pointer (returned from AfxBeginThread), which is
usualy an abnormal pointer.

I tried to give the important details, but maybe you'ld need more.
Please tell me.

Many thanks!
dushkin
2011-07-04 19:11:41 UTC
Permalink
A clarification - the program crashes inside the handler thread code!
Despite or thanks to calling AfxEndThread for it (from within one of
its methods)
Joseph M. Newcomer
2011-07-04 22:35:35 UTC
Permalink
I have no idea what "the handler thread code" could possibly be. An access fault crash
happens on a specific instruction, which is in a specific subroutine, at a specfic
location.
joe
Post by dushkin
A clarification - the program crashes inside the handler thread code!
Despite or thanks to calling AfxEndThread for it (from within one of
its methods)
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Geoff
2011-07-04 19:40:49 UTC
Permalink
Post by dushkin
Hi All,
(Sorry for bad english)
I am having some troubles with destroying threads (I guess...)
I will try to describe the architucture very generally, and if more
information will be needed, I will apply.
I have a dialog based application. When I press a button, I create a
socket and calls its Listen method.
Every time, a connection is accepted, I create a new thread containg
two major objects - Another (CAsyncSocket based) socket - which
receives packets from the connection source and pushes them into a
CStringArray, and a new thread which pops the next packet from this
CStringArray object and handles it.
Why are you creating another thread to handle the packet? Why not
handle it in the first thread?
Post by dushkin
Both connection thread and handler thread are created using
AfxBeginThread.
I also used CCrticalSection object to protect the strings array from
being accessed by both thread at the same time.
Now, this packets handler thread has a timer which schedules the
packet pop out and then handling.
Bad design. You should not use timers or polling to see if a packet
needs work. It's a stream, handle it as such. Use only one thread to
process each stream.
Post by dushkin
There might be ofcourse several connection requests from several
sources.
Each connection should spawn a new thread to handle the request. Each
thread operates independently of the other threads and it doesn't need
a worker thread to do the job.
Post by dushkin
Also The packet handler main job is actually send some response (1 or
more).
My problem is that sometimes the connection is being reset. The
question is what I do then? I am suppose to close the connection and
wait for a new one.
Yes, clean up your objects call your Shutdown() and Close() and call
AfxEndThread from within the thread, its work is done.
Post by dushkin
But then, after all the attempts I made according to my best
knowledge, I always got the application to crash on some invalid
pointer.
In general, whenever the socket OnClose message handler was called, I
first killed the handler thread timer, and then called AfxEndThread(0)
to kill the handler thread. Then I called Sockets' ShutDown() and
Close() methods. But then I was stucked with the question how do I
kill the connection thread? and where?
But the code continues to execute and the application crashes on
access violation or reading violation, as far as I understood on the
connection thread pointer (returned from AfxBeginThread), which is
usualy an abnormal pointer.
I tried to give the important details, but maybe you'ld need more.
Please tell me.
Many thanks!
Joseph M. Newcomer
2011-07-04 22:33:54 UTC
Permalink
See below...
Post by dushkin
Hi All,
(Sorry for bad english)
I am having some troubles with destroying threads (I guess...)
I will try to describe the architucture very generally, and if more
information will be needed, I will apply.
I have a dialog based application. When I press a button, I create a
socket and calls its Listen method.
Every time, a connection is accepted, I create a new thread containg
two major objects - Another (CAsyncSocket based) socket - which
receives packets from the connection source and pushes them into a
CStringArray, and a new thread which pops the next packet from this
CStringArray object and handles it.
****
I find this whole architecture deeply suspect. I wouldn't touch it with a ten foot pole.
A CStringArray is so wrong for this. A CList of CStrings would possibly make sense, but
using an array for this purpose is just the wrong approach, the wrong structure.

Also, are you aware that you cannot pass a CAsyncSocket into a thread? You have to Detch
the SOCKET object, then re-Attach it in the secondary thread, which must be a UI thread.
****
Post by dushkin
Both connection thread and handler thread are created using
AfxBeginThread.
****
There are two forms of AfxBeginThread. Therefore, it is critical to know which form you
are using.
****
Post by dushkin
I also used CCrticalSection object to protect the strings array from
being accessed by both thread at the same time.
Now, this packets handler thread has a timer which schedules the
packet pop out and then handling.
****
This sounds completely wrong. It should be responding to OnReceive notifications, and a
timer would not enter into the algorithm at all.
****
Post by dushkin
There might be ofcourse several connection requests from several
sources.
****
Yes, this would be correct.
Post by dushkin
Also The packet handler main job is actually send some response (1 or
more).
My problem is that sometimes the connection is being reset. The
question is what I do then? I am suppose to close the connection and
wait for a new one.
****
Well, what you do then is up to you. I have no idea what you mean by the connection being
"reset", since this is not a concept that TCP/IP actually has. Perhaps you meant it was
disconnected? In that case, you have no choice; you have to close your socket and wait
for a reconnection.
****
Post by dushkin
But then, after all the attempts I made according to my best
knowledge, I always got the application to crash on some invalid
pointer.
****
Not surprising. But, of course, it would be absolutely essential to know WHERE it
crashed, and have a backtrace, and some idea of what the variables involved were, and of
course, it is essential to distinguish between a hardware exception and an ASSERT failure
about an invalid pointer, which are completely different issues.
****
Post by dushkin
In general, whenever the socket OnClose message handler was called, I
first killed the handler thread timer, and then called AfxEndThread(0)
to kill the handler thread. Then I called Sockets' ShutDown() and
Close() methods. But then I was stucked with the question how do I
kill the connection thread? and where?
****
Calling AfxEndThread is always a mistake, no exceptions, no excuses. It is always an
error. Since the thread owns the socket, it is not clear how you can call Shutdown
*after* you call AfxEndThread.

What you do, is in the OnClose handler, you shutdown and close the socket. You then have
to purge any pending messages from your message queue. Then, and only then, you would
begin to shut down the thread. This would involve doing a PostQuitMessage (since it has
to be a UI thread), and handling any remaining cleanup in the ExitInstance handler. Never,
ever, for any reason imaginable, terminate a thread with AfxEndThread or any similar
ExitThread call disguise. This is always an error. Why? Because the thread STOPS. And
this means that any objects on the stack are not cleaned up, and you leak storage like
crazy.
****
Post by dushkin
But the code continues to execute and the application crashes on
access violation or reading violation, as far as I understood on the
connection thread pointer (returned from AfxBeginThread), which is
usualy an abnormal pointer.
****
OK, so you finally reveal the failure mode. But it happened SOMEWHERE, and that SOMEWHERE
is important to tell us. Why do you have a thread object around? What are you using it
for? Actually, given the serious design error of calling AfxEndThread, nothing else would
suprise me. You have to fix the shutdown sequencing FIRST before worrying about anything
else.
****
Post by dushkin
I tried to give the important details, but maybe you'ld need more.
Please tell me.
****
You gave the most critical detail: you are calling AfxEndThread, and THEN you are trying
to kill objects owned by the thread. This is not possible, and will almost certainly
fail. You have to delete the objects owned by the thread BEFORE the thread terminates.
joe
****
Post by dushkin
Many thanks!
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Loading...