|(require ffi/unsafe/atomic)||package: base|
Atomic mode evaluates a Racket expression without switching among Racket threads and with limited support for events. An atomic computation in this sense is not atomic with respect to other places, but only to other threads within a place.
Atomic mode is unsafe, because the Racket scheduler is not able to operate while execution is in atomic mode; the scheduler cannot switch threads or poll certain kinds of events, which can lead to deadlock or starvation of other threads. Beware that many operations can involve such synchronization, such as writing to an output port.
the current exception handler is known to safely escape atomic mode, or else all possible escapes are through known continuation jumps or aborts (because breaks are disabled and no other exceptions are possible) that escape safely; and
exception constructions, if any, avoid printing values in the exception message, or else the error value conversion handler is always used and known to be safe for atomic mode.
Using call-as-atomic is somewhat safer than using start-atomic and end-atomic, because call-as-atomic catches exceptions and re-raises them after exiting atomic mode, and it wraps any call to the error value conversion handler with call-as-nonatomic. The latter is safe for a particular atomic region, however, only if the region can be safely interrupted by a non-atomic exception construction.
Besides obvious paths to unknown expressions that may not be safe for atomic mode, beware of printing an arbitrary value in any way other than the error value conversion handler, because values can have arbitrary printing procedures attached through prop:custom-write.