|
Boost : |
From: Eric Woodruff (Eric.Woodruff_at_[hidden])
Date: 2002-08-05 10:48:26
My complaints on the ifdefs were on the underside of the thread. C++ alone provides plenty of mechanisms for mapping the common interface to different platforms, with typesafety (instead of the reinterpret_casts<>!)--again, the topic of a different discussion, at which point it would be easier just to submit a replacement as example.
Anyhow, I didn't outline the entire interface to advanced_thread (or just thread if it is to replace it). The design of the interface is certainly open to public debate, maybe with a public check_exceptions () that the thread user can call at any point to initiate throwing. Don't take the example too literally.
"On which thread will the bad_exception be thrown? I'm not aware of a
mechanism that can catch an exception in another thread (the thread
encapsulated by your advanced_thread), and cause it to be thrown in another
thread..."
bad_exception is thrown, if inside the users thread, an exception that was not listed to advanced_thread in the thread_exceptions (tuple, but aliased for clarity) was caught. the advanced_thread stores the exception that was thrown, using a very simple technique, and when the advanced_thread interface is accessed, the exception is rethrown.
There are of course questions to be answered. It is up to the user to decide which thread should now receive the exceptions, however, there could be some support added to ensure that only a designated thread process allows the exception to be rethrown, and none other. But this could be tricky to implement, and in this case, the user probably shouldn't be manipulating the advanced thread from a thread that isn't responsible for catching the exceptions, so it seems to fit naturally that the object responsible for the advanced_thread is responsible for its exceptions as well.
There is no reason to make users of thread handle their own exceptions because there is only one mechanism to do it, and every user will have to repeat this code in their implementation. Exceptions in thread processes have always been ambiguous to me, it seems that no framework out there supportws them properly and just expects them to be caught and sometimes ignored.
If you'll take note of the advanced_thread usage, it not provides a generic way to run any boost::function asynchronously, get its return value and deal with exceptions it may throw--a complete solution and something currently not yet available. Of course one could take the perspective that advanced_thread is really an asynchronous function adapter, but that deprecates the need to support what is currently offered by boost::thread--which is why I suggested a possible replacement.
----- Original Message -----
From: Moore, Dave
Newsgroups: gmane.comp.lib.boost.devel
Sent: Monday, 2002:August:05 11:01 AM
Subject: RE: Threads & Exceptions
>I've developed a way to support user exceptions in threads that I would
like
>to contribute to boost. In my opinion, it can replace/extend (in the
literal
>sense) the existing thread class (I also think the existing manor to
provide
>platform neutrality with ifndefs is unacceptable, but that is for a new
>message thread.).
If you look carefully, you'll see that the public -interface- to
Boost.Threads is homogenous and doesn't involve #ifdefs. The #ifdefs are
used to map this common interface onto three very different threading
platforms, pthreads, win32 threads, and Mac Carbon.
>
> Upon access to any (most -- debatable) of the public methods of the
> advanced_thread, a user exception may be thrown. Exceptions
> not listed to
> the class will cause std::bad_exception to be thrown (I
> believe that is
> appropriate). Of course, advanced_thread<void> does not provide
> getReturnValue () {or return_value () to follow STL naming}.
On which thread will the bad_exception be thrown? I'm not aware of a
mechanism that can catch an exception in another thread (the thread
encapsulated by your advanced_thread), and cause it to be thrown in another
thread...
>From your example, it seems like you may be passing information about thrown
exceptions during your call to testThread.getReturnValue(). Is this the
case? This approach may work for threads which are to be joined, but for
threads which are detached or not joined, I don't see a way for this
mechanism to work.
It seems to me that it's cleaner to let the user's main thread function
manage exceptions as it sees fit.
Regards,
Dave
>
> For instance:
>
> #include <boost/advanced_thread.hpp>
> #include <boost/bind.hpp>
>
> int testFunction () {
> throw 16;
> return 11;
> }
>
> int main () {
>
> typedef boost::advanced_thread<int,
> thread_exceptions<int, std::string>
> > Thread;
>
> try {
> Thread testThead (boost::bind (testFunction));
> int const returnValue = testThread.getReturnValue ();
> // implicit
> join
> }
> catch (int number) {
> std::cout << number << " was thrown!" << std::endl;
> }
> catch (std::bad_exception& exception) {
> std::cout << "An invalid exception was thrown by the
> thread user
> function. " << std::endl;
> }
> }
>
> _______________________________________________
> Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk