Re: [c++-pthreads] Re: thread-safety definition
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [c++-pthreads] Re: thread-safety definition



> I still think that uncatchable exceptions aren't the right answer.  
> Think
> about the scope of the modifications that would be required:
>  1. To a good first approximation, all code that catches and rethrows
>       exceptions, and that might be used in a cancellable thread, would
>       have to be modified.   (The basis of my claim: if you have to do
>       some cleanup whenever an exception passes through your code,
>       you'll still have to do it for cancellations too.)

>   1a. This isn't too different from saying that all code that catches
>          exceptions will have to be modified.  Most code that catches
>          an exception ends up rethrowing it.

>    2. Now think about what kind of modification we're talking about.
>        Again, to a good first approximation, cleanup is cleanup.  So
>        the example I've give above would be rewritten:

>        catch(...) {
>          do_some_partial_cleanup();
>          throw;
>        }
>        catch (CancellationException) {
>          do_some_partial_cleanup();
>          throw;
>        }
>       We don't really want that to become recommended C++ style,
>       do we?

Right, if you have code with catch(...)+throw for
general purpose cleanup, if catch(...) does not catch cancellation
you will miss the cleanup unless you put in explicit handler for
cancellation, and that means (ugly, bad) code changes.

On the other hand, if your style for providing cleanup code for
exceptions in general uses a local object with destructor to
achieve the cleanup (apparently the meaning of "RAII") then you
*don't* want catch(...) to catch cancellation.

{RAII protect;
   ... code that may be cancelled or throw other exceptions ...
}

class RAII {
   ...
   RAII () {
     ... allocate some stuff ...
   }
   ~RAII () {
     try {
       ... deallocate stuff ...
     } catch (...) {
       // want to give up quietly if deallocation causes an exception
       // but don't want to gobble up cancellation
     }
   }
   ...
};

It seems you can't have it both ways.  If catch(...) catches
cancellation, then destructors that are intended catch everything
without rethrowing can gobble up cancellation.  On the other hand,
if catch(...) does not catch cancellation, then destructors that
are intended to catch everything and rethrow will be bypassed.

I see better now why the idea of magically "reasserting"
cancellation is appealing.  That is, you can allow catch(...) to
catch cancellation, and if it is gobbled up you get it back again.
The only trick is to find exactly the right places to reassert the
cancellation.

--Ted