The point of critical regions in your code is that sometimes you have data-base updates or other operations that, once started, must be completed in order to avoid an inconsistent state. In particular, such operations should not be interrupted by a ^C from the keyboard.
In releases of Quintus Prolog prior to release 3.0, library(critical)
was
provided to allow critical regions to be specified using the predicates
begin_critical/0
and end_critical/0
. These predicates are still
provided, but they should be regarded as obsolete since they do not interact
well with exception handling. An exception occurring in between the
begin_critical
and the end_critical
could cause two problems:
To avoid these problems, you should use the new predicates
critical(Goal) critical_on_exception(ErrorCode, Goal, Handler)
which library(critical)
now provides.
critical/1
runs the specified goal inside a critical region. It
solves (2) by catching any exceptions that are
raised and taking care to close the critical region before re-raising the
exception.
critical_on_exception/3
allows you to solve
(1) by specifying appropriate clean-up actions in
Handler.
If an exception occurs during Goal, and the exception code unifies with
ErrorCode, critical_on_exception/3
acts as if you had
written
critical(Handler)
instead. That is, the Handler will still be inside the critical region, and only the first solution it returns will be taken.
These forms also have the effect of committing to the first solution of Goal. Since the point of a critical region is to ensure that some operation with side-effects is completed, Goal should be determinate anyway, so this should be no problem.