Boost logo

Boost :

From: William Kempf (williamkempf_at_[hidden])
Date: 2002-08-12 07:50:23


>From: Darryl Green <green_at_[hidden]>
> > -----Original Message-----
> > From: William Kempf [mailto:williamkempf_at_[hidden]]
> > >From: Darryl Green <green_at_[hidden]>
>I want to something expected, not something unexpected (async exceptions).
>It depends what you mean by recover - I just don't want to die an
>uncontrolled death.

Sometimes you have to die, unfortunately. Sometimes there's simply no way
to actually recover from an exception. Granted this usually occurs because
code outside of your control failed to deal with the exception
appropriately, but this is the case with or without threads, and I believe
that forced terminate() is more likely to get programmers to put the
appropriate exception handling code in the place where it's most likely they
can deal with it correctly.

> > >The *library* started the thread. It would need to wrap it.
> > I agree it
> > >could. Which lib?
> >
> > Didn't you just say the lib that started the thread?
>
>Sorry. I should have been more explicit. I'm assuming here that this
>hypothetical lib I'm trying to use is *not* a lib that specifically deals
>with async function execution it is just a user of it and intends
>to/attempts to insulate the user from it, possibly by using some handy
>library(s) to do it. So the "Which lib?" was - can the database access
>library delegate this problem to some other lib and if so which lib.

The lib that creates the thread is the only one that's likely to have any
chance of correctly handling an exception on that thread. You are even less
likely to be able to do anything useful with a passed exceptions several
levels of libraries later.

> > >The
> > >library writer who uses any of these other libraries in
> > writing something
> > >that has nothing to do with threads as-such isn't the person
> > best placed to
> > >decide how to do this and/or how to implement it.
> >
> > Seems to me like they are.
>
>I hope you have lost me here. Surely it is reasonable for someone just to
>want to know how in a pretty superficial way (point me at the example, not
>understand the mechanism)?

Yes, rereading it I see that I did lose you. The library that starts the
thread is likely the only library prepared to deal with an exception thrown
out of that thread. Everyone else is likely left with having to terminate()
any way.

> > >The user just wants
> > >consistent behaviour.
> >
> > I don't see that that's precisely true. Put another way, I
> > see consistancy
> > where it should exist, and differences where it should not.
>
>So did I miss some difference? As I said, If there are lots of differences,
>consistency isn't viable.

Yes. Typical thread usage depends on the thread to be running between the
calls to create it and join it. Exception thrown in between in this
scenario are likely to result in deadlock or other erroneous behavior.
Either a universal mechanism for determining this needs to be applied (and
polling won't work as it causes race conditions), or case specific coding is
required. I can't envision a universal mechanism for this scenario, and
that's why I'm advocating terminate(), to force the user to write the
specific exception handling code to deal with this (or not, if they feel
terminate() is appropriate, which often is).

> > > > I understand why people think that async calls should throw,
> > > > but again,
> > > > threads are not async calls in the fashion that people
> > are thinking.
> > >
> > >No, but they underly them.
> >
> > Actually, they don't. There are numerous ways to make a call
> > asynchronous.
>
>I think before you can be that pedantic you are going to have to define
>what
>is and isn't an async call in this context ( rather than in some other
>thread :-) ).

An async call is a call in which you invoke the call, which returns
immediately, and you receive the response from the call at a later point
through some polling mechanism. This might be a little more liberal than
some definitions since it allows for things such as the Win32 message queue
to be viewed as a mechanism for performing asynchronous calls, while
technically since everything occurs within a single thread it's not truly
asynchronous. But even if you remove that I can still think of 3 truly
asynchronous calling conventions.

1) Within a single process, across thread boundaries.
2) Across process boundaries.
3) Across machines or other hardware boundaries.

> > >If it is your considered opinion that the issues above can
> > be, and are
> > >best,
> > >solved outside of boost:thread I'm quite prepared to stop
> > heckling. If you
> > >have already made such a claim I have missed it while
> > following in the
> > >standards related debate.
> >
> > I've made the claim before, and I reiterate now, async
> > behavior (including
> > error handling, which may or may not be in the form of
> > exceptions) belongs
> > in a function object wrapper. Threads, thread pools, RPCs, message
> > dispatching systems or other mechanisms I'm not thinking of
> > should only be
> > used as the means for making such calls (at least appear) to execute
> > asynchronously, while the function object provides a
> > consistent interface
> > for dealing with the complex issues of handling errors and exceptions.
>
>I think this is the nub of it. According to your claim I should be able to
>write appropriate function objects to produce similar results independent
>of
>the mechanism. This I agree with.

Actually, sometimes you have to deal with the mechanism as well. There are
implementation differences between the various mechanisms that are likely to
make a single universal solution impossible. But at least with the function
object wrappers you can achieve a universal interface for the various forms
of async calls. (Or there may well be a universal solution to this that I'm
not yet seeing.)

>I still find it perverse that the "safe thing to do" if a poorly written
>thread throws an exception is to crash the other threads (for the lack of a
>better term for the state of the system when terminate() is called).

This is the behavior of at least one thread today. Also, but reading the
rules for the underlying thread APIs (or lack there of in this case) it's
very possible, even probable, that there are implementations today that
behave the way I've suggested (i.e. they terminate() on uncaught exceptions
as well). So, even if I agreed, I can't gaurantee you that there won't be
some thread in your application that will cause your application to
terminate() in any event.

>However, it seems this is beyond the power of your lib to deal with, so
>I'll
>let you off :-)

Well, I believe it is, but I'm still open to be proven wrong.

Bill Kempf
williamkempf_at_[hidden]

_________________________________________________________________
Join the world’s largest e-mail service with MSN Hotmail.
http://www.hotmail.com


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk