[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
thoughts about unwind_protect
From: |
John W. Eaton |
Subject: |
thoughts about unwind_protect |
Date: |
Mon, 4 Jan 2010 02:17:18 -0500 |
On 2-Jan-2010, Jaroslav Hajek wrote:
| one problem I see about the unwind_protect mechanism is that there is
| no automatic cleanup on function exit.
| Usually a function code goes like this
|
| unwind_protect_t frame = unwind_protect::begin_frame ();
|
| unwind_protect::protect_var (my_var);
| // do stuff
|
| unwind_protect::run_frame ();
|
| The problem is that the last line is not executed if an exception
| occurs in the function body, so the unwind_protect operation would be
| delayed until the next run_frame or run_all after catching the
| exception. Such a delay could have disastrous consequences, however,
| if local variables (which no longer exist) were somehow involved in
| the registered cleanup action.
I don't think local variables were intended to be handled by the
unwind_protect mechanism. Are there any cases where unwind_protect is
being used for local variables?
| To combat this problem, liboctave
| introduces the octave_interrupt_hook, which is hooked to a handler
| that doesn unwind_protect::run_all (). Hence, in case of interrupt
| exception, the *whole* unwind_protect stack is run before the
| exception is even thrown.
| Usually, this does the right thing, since the exception then
| propagates to the top level (main loop).
| However, it is not advisable to catch interrupt exceptions (for
| possible additional handling), because at that moment cleanup actions
| will be performed for the whole call stack, so thing may not be in
| feasible state (for instance, the octave_call_stack).
|
| what I suggest is to instead use this scheme:
|
| unwind_protect frame;
|
| frame.protect_var ();
|
| // do_stuff
|
| // frame.run () // can be done explicitly or at destruction time.
|
| This has a number of advantages, being simpler and cleaning up
| automatically. The only disadvantage is that exceptions should not
| occur in destructors, so if a cleanup action is registered that can
| throw exception (which is very rare), that action should be run
| explicitly (with possibly handling the exception).
|
| I think this is not too much of a hassle, especially considering that
| in fact now each frame is run explicitly. After this change, I think
| it may be possible to eliminate the octave_interrupt_hook.
This seems like an improvement to me, so I'd say go ahead and make the
changes.
jwe