diff options
author | Andy Wingo <wingo@pobox.com> | 2016-10-18 21:24:01 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2016-10-18 21:24:01 +0200 |
commit | 51d322b2d4a0ea90510087427dfa92d8384c9b76 (patch) | |
tree | e4f37d0e1cb961383f2b904a4ddf37198c70f950 /doc/ref/api-scheduling.texi | |
parent | 728068113df3294624498531cd0cc1c8714c8eff (diff) | |
download | guile-51d322b2d4a0ea90510087427dfa92d8384c9b76.tar.gz |
Update "Asyncs" section of manual.
* doc/ref/api-scheduling.texi (Asyncs): Update.
Diffstat (limited to 'doc/ref/api-scheduling.texi')
-rw-r--r-- | doc/ref/api-scheduling.texi | 83 |
1 files changed, 46 insertions, 37 deletions
diff --git a/doc/ref/api-scheduling.texi b/doc/ref/api-scheduling.texi index 6048776d4..1fb9ec774 100644 --- a/doc/ref/api-scheduling.texi +++ b/doc/ref/api-scheduling.texi @@ -8,7 +8,7 @@ @section Threads, Mutexes, Asyncs and Dynamic Roots @menu -* Asyncs:: Asynchronous procedure invocation. +* Asyncs:: Asynchronous interrupts. * Atomics:: Atomic references. * Threads:: Multiple threads of execution. * Mutexes and Condition Variables:: Synchronization primitives. @@ -22,31 +22,48 @@ @node Asyncs -@subsection Asyncs +@subsection Asynchronous Interrupts @cindex asyncs +@cindex asynchronous interrupts +@cindex interrupts -Asyncs are a means of deferring the execution of Scheme code until it is -safe to do so. +Every Guile thread can be interrupted. Threads running Guile code will +periodically check if there are pending interrupts and run them if +necessary. To interrupt a thread, call @code{system-async-mark} on that +thread. -Asyncs are integrated into the core of Guile. A running Guile program -will periodically check if there are asyncs to run, invoking them as -needed. For example, it is not possible to execute Scheme code in a -POSIX signal handler, but in Guile a signal handler can enqueue a system -async to be executed in the near future, when it is safe to do so. - -Asyncs can also be queued for threads other than the current one. This -way, you can cause threads to asynchronously execute arbitrary code. - -To cause the future asynchronous execution of a procedure in a given -thread, use @code{system-async-mark}. +@deffn {Scheme Procedure} system-async-mark proc [thread] +@deffnx {C Function} scm_system_async_mark (proc) +@deffnx {C Function} scm_system_async_mark_for_thread (proc, thread) +Enqueue @var{proc} (a procedure with zero arguments) for future +execution in @var{thread}. When @var{proc} has already been enqueued +for @var{thread} but has not been executed yet, this call has no effect. +When @var{thread} is omitted, the thread that called +@code{system-async-mark} is used. +@end deffn -Automatic invocation of asyncs can be temporarily disabled by calling -@code{call-with-blocked-asyncs}. This function works by temporarily -increasing the @emph{async blocking level} of the current thread while a -given procedure is running. The blocking level starts out at zero, and -whenever a safe point is reached, a blocking level greater than zero -will prevent the execution of queued asyncs. +Note that @code{scm_system_async_mark_for_thread} is not +``async-signal-safe'' and so cannot be called from a C signal handler. +(Indeed in general, @code{libguile} functions are not safe to call from +C signal handlers.) + +Though an interrupt procedure can have any side effect permitted to +Guile code, asynchronous interrupts are generally used either for +profiling or for prematurely cancelling a computation. The former case +is mostly transparent to the program being run, by design, but the +latter case can introduce bugs. Like finalizers (@pxref{Foreign Object +Memory Management}), asynchronous interrupts introduce concurrency in a +program. An asyncronous interrupt can run in the middle of some +mutex-protected operation, for example, and potentially corrupt the +program's state. + +If some bit of Guile code needs to temporarily inhibit interrupts, it +can use @code{call-with-blocked-asyncs}. This function works by +temporarily increasing the @emph{async blocking level} of the current +thread while a given procedure is running. The blocking level starts +out at zero, and whenever a safe point is reached, a blocking level +greater than zero will prevent the execution of queued asyncs. Analogously, the procedure @code{call-with-unblocked-asyncs} will temporarily decrease the blocking level of the current thread. You @@ -59,22 +76,6 @@ In addition to the C versions of @code{call-with-blocked-asyncs} and inside a @dfn{dynamic context} (@pxref{Dynamic Wind}) to block or unblock asyncs temporarily. -@deffn {Scheme Procedure} system-async-mark proc [thread] -@deffnx {C Function} scm_system_async_mark (proc) -@deffnx {C Function} scm_system_async_mark_for_thread (proc, thread) -Mark @var{proc} (a procedure with zero arguments) for future execution -in @var{thread}. When @var{proc} has already been marked for -@var{thread} but has not been executed yet, this call has no effect. -When @var{thread} is omitted, the thread that called -@code{system-async-mark} is used. - -As we mentioned above, Scheme signal handlers are already called within -an async and so can run any Scheme code. However, note that the C -function is not safe to be called from C signal handlers. Use -@code{scm_sigaction} or @code{scm_sigaction_for_thread} to install -signal handlers. -@end deffn - @deffn {Scheme Procedure} call-with-blocked-asyncs proc @deffnx {C Function} scm_call_with_blocked_asyncs (proc) Call @var{proc} and block the execution of asyncs by one level for the @@ -113,6 +114,14 @@ one level. This function must be used inside a pair of calls to Wind}). @end deftypefn +Finally, note that threads can also be interrupted via POSIX signals. +@xref{Signals}. As an implementation detail, signal handlers will +effectively call @code{system-async-mark} in a signal-safe way, +eventually running the signal handler using the same async mechanism. +In this way you can temporarily inhibit signal handlers from running +using the above interfaces. + + @node Atomics @subsection Atomics |