RAII / handling failures during destruction - advice required

M

MikeB

Hi,



Recently I was asked to look at some code where RAII is used to ensure
automatic cleanup of a resource. Unfortunately, cleaning up the resource
requires that the destructor make a call to an API which can (albeit under
dire circumstances) fail. As it stands, in the presence of a failed call to
the API, the destructor does nothing more than record the event in the
system log.



I'm uncomfortable with the fact that code further up the stack is unaware of
the failure but I'm also aware of the issues surrounding the throwing /
propagation of exceptions from destructors.



In view of this, I'm left wondering whether or not RAII is acceptable as a
means of managing this type of resource.



I'd appreciate others views on this.



Thanks in anticipation.

MikeB
 
A

Alf P. Steinbach

* MikeB:
Recently I was asked to look at some code where RAII is used to ensure
automatic cleanup of a resource. Unfortunately, cleaning up the resource
requires that the destructor make a call to an API which can (albeit under
dire circumstances) fail. As it stands, in the presence of a failed call to
the API, the destructor does nothing more than record the event in the
system log.

I'm uncomfortable with the fact that code further up the stack is unaware of
the failure but I'm also aware of the issues surrounding the throwing /
propagation of exceptions from destructors.

In view of this, I'm left wondering whether or not RAII is acceptable as a
means of managing this type of resource.

Do whatever is appropriate.

I.e., does the failed API call have an effect, and if so at what level
(thread, process, system, network), and who (computerwise, userwise)
should do something about that, if anything?
 
M

MikeB

Alf P. Steinbach said:
Do whatever is appropriate.

I.e., does the failed API call have an effect, and if so at what level
(thread, process, system, network), and who (computerwise, userwise)
should do something about that, if anything?

I'm not sure that the details are that relevant, but for the sake of
completeness, the failure of the API indicates that a lock which was at some
point acquired could not, for whatever reason, be released. Furthermore, the
class which manages the lock is a component from a 'generic' library, so in
the great tradition of error handling, I'm not convinced that it can know
how to 'do whatever is appropriate'.



I'd appreciate your input on how to 'do whatever is appropriate' in a
flexible manner.



Rgds,

MikeB
 
A

Alf P. Steinbach

* MikeB:
I'm not sure that the details are that relevant, but for the sake of
completeness, the failure of the API indicates that a lock which was at some
point acquired could not, for whatever reason, be released. Furthermore, the
class which manages the lock is a component from a 'generic' library, so in
the great tradition of error handling, I'm not convinced that it can know
how to 'do whatever is appropriate'.

I'd appreciate your input on how to 'do whatever is appropriate' in a
flexible manner.

If it doesn't have any measurable effect, just log it (from the program)
and report it in whatever error reporting system is used (e.g. Bugzilla).

Otherwise if it can be easily dealt with at some level (e.g. terminating a
tread, process, system), do that also.

Otherwise leave it to the user to decide.
 
O

Owen Jacobson

* MikeB:

If it doesn't have any measurable effect, just log it (from the program)
and report it in whatever error reporting system is used (e.g. Bugzilla).

Otherwise if it can be easily dealt with at some level (e.g. terminating a
tread, process, system), do that also.

Otherwise leave it to the user to decide.

To add to Alf Steinbach's good advice, I'd be inclined to test that the
lock is actually released using an assertion. The general case is that,
if you can acquire the lock, you should always be able to release it, and
if you can't there's likely a problem somewhere more fundamental than your
code.

So, if you're working with a "debug" version with assertions enabled,
it'll let you know when it happens, and at runtime a "mostly useless"
check goes away.

I'd be inclined to implement that in the header file, so that clients of
your library can enable and disable assertions themselves, even if the
rest of the library implementation is in the actual sources.

Owen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top