This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Re: how to wait for a thread to complete?
- From: Øyvind Harboe <oyvind dot harboe at zylin dot com>
- To: Nick Garnett <nickg at ecoscentric dot com>
- Cc: ecos-discuss at sources dot redhat dot com
- Date: Fri, 23 Jul 2004 11:55:07 +0200
- Subject: Re: [ECOS] how to wait for a thread to complete?
- References: <1090570864.17601.17.camel@famine> <m3hdrzkr16.fsf@xl5.calivar.com>
On Fri, 2004-07-23 at 11:32, Nick Garnett wrote:
> Øyvind Harboe <oyvind.harboe@zylin.com> writes:
>
> > I've tried and failed to find a reasonable way to wait for
> > a thread to run to completion in eCos. By "run to completion",
> > I mean that the thread might yet do useful work(including e.g.
> > network communication, processing, etc.).
> >
> > cyg_thread_delete() will break a thread out of its sleep, which
> > I don't want.
> >
> > Setting a flag just before I return from the thread entry fn is not
> > satisfactory, because it could cause me to reuse the stack
> > prematurely and a subsequent cyg_thread_delete() *could* fail.
> >
> > So, I propose that a new API fn in eCos is called for. Something along
> > the lines in the attached patch.
>
> This patch also suffers from the same problem. What happens if the
> memory for the thread object has been reused before the call to
> cyg_thread_wait_exited()?
Thats just a bug in the calling code just as it would be for any other
cyg_thread_xxx() call.
> Any system that might cause you to reuse the
> stack prematurely would cause you to reuse the thread object
> prematurely too.
The idea is not to reuse the stack/thread object until
cyg_thread_wait_exited() returns.
> Also, the function may never terminate if the target thread never gets
> to run and put itself into EXITED state.
As is intended.
> You may need to do more than
> just wait to get the thread to exit -- like boost its priority for
> example.
or set a flag, etc.
> > With regards to the implementation, I would have liked for the
> > cyg_thread_delay() to be replaced by something that caused
> > cyg_thread_wait_exited() to wake up *immediately* after the thread has
> > entered the exited state, but I couldn't find an obvious and simple way
> > to do so.
>
> Any mechanism to do this in a generic manner is rather complicated.
> More complicated that we wanted to build into the basic kernel or
> API. The intention behind the kernel API was that it should be
> minimal, offloading the more sophisticated things to higher levels, or
> to the user.
>
> The POSIX library has pthread_join() to do this job. It was always
> expected that if a user needed these sorts facilities then they would
> use POSIX rather than the bare kernel.
I really feel that the current API encourages code that make my skin
crawl. If you feel the same way, perhaps you would agree that the bare
cyg_thread API could do with this tiny addition.
Take a look at this tftp code below. It will pass all tests you can
throw at it in the lab and break as soon as you deploy it.
cyg_thread_kill(server->thread_handle);
cyg_thread_set_priority(server->thread_handle, 0);
cyg_thread_delay(1); // Make sure it gets to die...
if (cyg_thread_delete(server->thread_handle)) {
// Success shutting down the thread. Close all its sockets.
int i;
for (i = 0 ; i < CYGNUM_NET_MAX_INET_PROTOS; i++) {
if (server->s[i]) {
close (server->s[i]);
}
}
freeaddrinfo(server->res);
free(server); // Give up memory
return 1;
}
> However, combining the exit flag and cyg_thread_delete() seems to be a
> reasonable user-level solution:
>
> volatile bool my_thread_exited = false;
>
> void my_thread( CYG_ADDRWORD arg )
> {
> my_thread_exited = true;
> return;
> }
>
> void wait_for_my_thread()
> {
> for(;;)
> {
> if( my_thread_exited )
> if( cyg_thread_delete( my_thread )
> return;
> cyg_thread_delay(1);
> }
> }
Looks correct to me.
--
Øyvind Harboe
http://www.zylin.com
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss