Boost logo

Boost :

From: Eric D Crahen (crahen_at_[hidden])
Date: 2002-08-14 05:45:35

Hillel Y. Sims wrote:

> I just thought of another one:
> 4. The standard library already throws exceptions inherited from
> std::exception, and you don't want to introduce another completely
> orthogonal hierarchy just for the sake of being contrary.

The biggest use of moving exception from one thread to another, as I see
it, would probably in creating Futures, Active Objects or other variants
of that idea (I think that all uses of a thread returning a result
essentially boil down to one of those patterns). For this you'd want
non-std:exeception based exceptions,

The example you usually see would be something like a function that
starts a thread to load an image. Below, ImageFuture would contain
a thread that it uses to actually load the image in.

// Just a rough outline of how it might be used with a library
// like ImageMagik++ ( It incomplete,
// I'm just trying to show one kind of use.

ImageFutue f("somefile"); // Start loading an image in another thread

// .. // Do some other things for a while, setup the
                          // frame to display it, find the matching
                          // thumbnail that won't take as long to
                          // load image, whatever

try {

  Image& img = f.getImage(); // Get the ImageFuture threads result.

  // paint it, print it, etc

} catch(ErrorCorruptImage&) { // not derived from std::exception
  // ... Handle one error one way
} catch(ErrorFileOpen&) { // not derived from std::exception
  // ... Handle the other error another

This particular library has its own exception hierarchy, alot of libraries
do (off the top of my head, CORBA ORBs are another that come to mind). If
the thread is able to propogate exceptions automagically from one thread
to another, it works out very nicely; using the thread based future or
using something else like it becomes simpler (from the ImageFuture users
point of view). Its easier to replace the Future class with one that
isn't based on a thread if you need to. It also makes it easier to
introduce some thread use into a program that already handles the
exceptions that existing functions (like might throw. If
you only have the ability to use std::exception based exceptions, it
makes it more difficult to use threads in this way with libraries that
don't use std::exception.

This next part is just my thought in general about some of the things in
the whole discussion.

I don't think having the threads exception unwind another stack is that
big of a problem for something like this. If I called
directly, I'd be catching those ErrorXXX exceptions anyway. All thats
happening is the function runs concurrently instead of synchronously, the
exceptions wouldn't be unexpected in a case like this. If it threw an
exception that I didn't catch that the function be threaded would have
thrown anyway if I called it directly the problem is that I didn't catch
the exception, not so much that the exception came from another thread.

The real problem I think is that you can't write something to do this in
C++ for all exceptions. Even if you require the exception to be copyable,
there are still exceptions that could inherit from others - then you need
to catch in the right order (someone mentioned this, but don't have thier
post handy).

I implemented something that propogates some exceptions:
but the approach I took was to create a task class that had a
setException() function that can rethrow copyable exceptions in other
threads. It works out alright for that, the major drawback is that a user
has to write a wrapper class for each threaded task, you couldn't just
give it a function pointer and say go nuts.

- Eric

Boost list run by bdawes at, gregod at, cpdaniel at, john at