3 @chapter Threads, Mutexes, Asyncs and Dynamic Roots
5 [FIXME: This is pasted in from Tom Lord's original guile.texi chapter
6 plus the Cygnus programmer's manual; it should be *very* carefully
7 reviewed and largely reorganized.]
21 @c docstring begin (texi-doc-string "guile" "make-arbiter")
22 @deffn primitive make-arbiter name
23 Return an object of type arbiter and name @var{name}. Its
24 state is initially unlocked. Arbiters are a way to achieve
25 process synchronization.
28 @c docstring begin (texi-doc-string "guile" "try-arbiter")
29 @deffn primitive try-arbiter arb
30 Return @code{#t} and lock the arbiter @var{arb} if the arbiter
31 was unlocked. Otherwise, return @code{#f}.
34 @c docstring begin (texi-doc-string "guile" "release-arbiter")
35 @deffn primitive release-arbiter arb
36 Return @code{#t} and unlock the arbiter @var{arb} if the
37 arbiter was locked. Otherwise, return @code{#f}.
44 @c docstring begin (texi-doc-string "guile" "async")
45 @deffn primitive async thunk
46 Create a new async for the procedure @var{thunk}.
49 @c docstring begin (texi-doc-string "guile" "system-async")
50 @deffn primitive system-async thunk
51 Create a new async for the procedure @var{thunk}. Also
52 add it to the system's list of active async objects.
55 @c docstring begin (texi-doc-string "guile" "async-mark")
56 @deffn primitive async-mark a
57 Mark the async @var{a} for future execution.
60 @c docstring begin (texi-doc-string "guile" "system-async-mark")
61 @deffn primitive system-async-mark a
62 Mark the async @var{a} for future execution.
65 @c docstring begin (texi-doc-string "guile" "run-asyncs")
66 @deffn primitive run-asyncs list_of_a
67 Execute all thunks from the asyncs of the list @var{list_of_a}.
70 @c docstring begin (texi-doc-string "guile" "noop")
71 @deffn primitive noop . args
72 Do nothing. When called without arguments, return @code{#f},
73 otherwise return the first argument.
76 @c docstring begin (texi-doc-string "guile" "unmask-signals")
77 @deffn primitive unmask-signals
78 Unmask signals. The returned value is not specified.
81 @c docstring begin (texi-doc-string "guile" "mask-signals")
82 @deffn primitive mask-signals
83 Mask signals. The returned value is not specified.
88 @section Dynamic Roots
91 A @dfn{dynamic root} is a root frame of Scheme evaluation.
92 The top-level repl, for example, is an instance of a dynamic root.
94 Each dynamic root has its own chain of dynamic-wind information. Each
95 has its own set of continuations, jump-buffers, and pending CATCH
96 statements which are inaccessible from the dynamic scope of any
99 In a thread-based system, each thread has its own dynamic root. Therefore,
100 continuations created by one thread may not be invoked by another.
102 Even in a single-threaded system, it is sometimes useful to create a new
103 dynamic root. For example, if you want to apply a procedure, but to
104 not allow that procedure to capture the current continuation, calling
105 the procedure under a new dynamic root will do the job.
107 @c docstring begin (texi-doc-string "guile" "call-with-dynamic-root")
108 @deffn primitive call-with-dynamic-root thunk handler
109 Evaluate @code{(thunk)} in a new dynamic context, returning its value.
111 If an error occurs during evaluation, apply @var{handler} to the
112 arguments to the throw, just as @code{throw} would. If this happens,
113 @var{handler} is called outside the scope of the new root -- it is
114 called in the same dynamic context in which
115 @code{call-with-dynamic-root} was evaluated.
117 If @var{thunk} captures a continuation, the continuation is rooted at
118 the call to @var{thunk}. In particular, the call to
119 @code{call-with-dynamic-root} is not captured. Therefore,
120 @code{call-with-dynamic-root} always returns at most one time.
122 Before calling @var{thunk}, the dynamic-wind chain is un-wound back to
123 the root and a new chain started for @var{thunk}. Therefore, this call
124 may not do what you expect:
127 ;; Almost certainly a bug:
132 (call-with-dynamic-root
136 (lambda (errcode) errcode))))
139 The problem is, on what port will @samp{fnord} be displayed? You
140 might expect that because of the @code{with-output-to-port} that
141 it will be displayed on the port bound to @code{some-port}. But it
142 probably won't -- before evaluating the thunk, dynamic winds are
143 unwound, including those created by @code{with-output-to-port}.
144 So, the standard output port will have been re-set to its default value
145 before @code{display} is evaluated.
147 (This function was added to Guile mostly to help calls to functions in C
148 libraries that can not tolerate non-local exits or calls that return
149 multiple times. If such functions call back to the interpreter, it should
150 be under a new dynamic root.)
154 @c docstring begin (texi-doc-string "guile" "dynamic-root")
155 @deffn primitive dynamic-root
156 Return an object representing the current dynamic root.
158 These objects are only useful for comparison using @code{eq?}.
159 They are currently represented as numbers, but your code should
160 in no way depend on this.
163 @c begin (scm-doc-string "boot-9.scm" "quit")
164 @deffn procedure quit [exit_val]
165 Throw back to the error handler of the current dynamic root.
167 If integer @var{exit_val} is specified and if Guile is being used
168 stand-alone and if quit is called from the initial dynamic-root,
169 @var{exit_val} becomes the exit status of the Guile process and the
173 When Guile is run interactively, errors are caught from within the
174 read-eval-print loop. An error message will be printed and @code{abort}
175 called. A default set of signal handlers is installed, e.g., to allow
176 user interrupt of the interpreter.
178 It is possible to switch to a "batch mode", in which the interpreter
179 will terminate after an error and in which all signals cause their
180 default actions. Switching to batch mode causes any handlers installed
181 from Scheme code to be removed. An example of where this is useful is
182 after forking a new process intended to run non-interactively.
184 @c begin (scm-doc-string "boot-9.scm" "batch-mode?")
185 @deffn procedure batch-mode?
186 Returns a boolean indicating whether the interpreter is in batch mode.
189 @c begin (scm-doc-string "boot-9.scm" "set-batch-mode?!")
190 @deffn procedure set-batch-mode?! arg
191 If @var{arg} is true, switches the interpreter to batch mode.
192 The @code{#f} case has not been implemented.
198 @cindex Guile threads
200 @strong{[NOTE: this chapter was written for Cygnus Guile and has not yet
201 been updated for the Guile 1.x release.]}
203 Here is a the reference for Guile's threads. In this chapter I simply
204 quote verbatim Tom Lord's description of the low-level primitives
205 written in C (basically an interface to the POSIX threads library) and
206 Anthony Green's description of the higher-level thread procedures
208 @cindex posix threads
210 @cindex Green, Anthony
212 When using Guile threads, keep in mind that each guile thread is
213 executed in a new dynamic root.
216 * Low level thread primitives::
217 * Higher level thread procedures::
221 @node Low level thread primitives
222 @subsection Low level thread primitives
224 @c NJFIXME no current mechanism for making sure that these docstrings
227 @c begin (texi-doc-string "guile" "call-with-new-thread")
228 @deffn primitive call-with-new-thread thunk error-handler
229 Evaluate @code{(thunk)} in a new thread, and new dynamic context,
230 returning a new thread object representing the thread.
232 If an error occurs during evaluation, call error-handler, passing it an
233 error code describing the condition. [Error codes are currently
234 meaningless integers. In the future, real values will be specified.]
235 If this happens, the error-handler is called outside the scope of the new
236 root -- it is called in the same dynamic context in which
237 with-new-thread was evaluated, but not in the caller's thread.
239 All the evaluation rules for dynamic roots apply to threads.
242 @c begin (texi-doc-string "guile" "join-thread")
243 @deffn primitive join-thread thread
244 Suspend execution of the calling thread until the target @var{thread}
245 terminates, unless the target @var{thread} has already terminated.
248 @c begin (texi-doc-string "guile" "yield")
249 @deffn primitive yield
250 If one or more threads are waiting to execute, calling yield forces an
251 immediate context switch to one of them. Otherwise, yield has no effect.
254 @c begin (texi-doc-string "guile" "make-mutex")
255 @deffn primitive make-mutex
256 Create a new mutex object.
259 @c begin (texi-doc-string "guile" "lock-mutex")
260 @deffn primitive lock-mutex mutex
261 Lock @var{mutex}. If the mutex is already locked, the calling thread
262 blocks until the mutex becomes available. The function returns when
263 the calling thread owns the lock on @var{mutex}.
266 @c begin (texi-doc-string "guile" "unlock-mutex")
267 @deffn primitive unlock-mutex mutex
268 Unlocks @var{mutex} if the calling thread owns the lock on @var{mutex}.
269 Calling unlock-mutex on a mutex not owned by the current thread results
270 in undefined behaviour. Once a mutex has been unlocked, one thread
271 blocked on @var{mutex} is awakened and grabs the mutex lock.
274 @c begin (texi-doc-string "guile" "make-condition-variable")
275 @deffn primitive make-condition-variable
278 @c begin (texi-doc-string "guile" "wait-condition-variable")
279 @deffn primitive wait-condition-variable cond-var mutex
282 @c begin (texi-doc-string "guile" "signal-condition-variable")
283 @deffn primitive signal-condition-variable cond-var
287 @node Higher level thread procedures
288 @subsection Higher level thread procedures
290 @c new by ttn, needs review
292 Higher level thread procedures are available by loading the
293 @code{(ice-9 threads)} module. These provide standardized
294 thread creation and mutex interaction.
296 @c docstring begin (texi-doc-string "guile" "%thread-handler")
297 @deffn primitive %thread-handler tag args@dots{}
299 This procedure is specified as the standard error-handler for
300 @code{make-thread} and @code{begin-thread}. If the number of @var{args}
301 is three or more, use @code{display-error}, otherwise display a message
302 "uncaught throw to @var{tag}". All output is sent to the port specified
303 by @code{current-error-port}.
305 Before display, global var @code{the-last-stack} is set to @code{#f}
306 and signals are unmasked with @code{unmask-signals}.
308 [FIXME: Why distinguish based on number of args?! Cue voodoo music here.]
311 @c docstring begin (texi-doc-string "guile" "make-thread")
312 @deffn macro make-thread proc [args@dots{}]
313 Apply @var{proc} to @var{args} in a new thread formed by
314 @code{call-with-new-thread} using @code{%thread-handler} as the error
318 @c docstring begin (texi-doc-string "guile" "begin-thread")
319 @deffn macro begin-thread first [rest@dots{}]
320 Evaluate forms @var{first} and @var{rest} in a new thread formed by
321 @code{call-with-new-thread} using @code{%thread-handler} as the error
325 @c docstring begin (texi-doc-string "guile" "with-mutex")
326 @deffn macro with-mutex m [body@dots{}]
327 Lock mutex @var{m}, evaluate @var{body}, and then unlock @var{m}.
328 These sub-operations form the branches of a @code{dynamic-wind}.
331 @c docstring begin (texi-doc-string "guile" "monitor")
332 @deffn macro monitor first [rest@dots{}]
333 Evaluate forms @var{first} and @var{rest} under a newly created
334 anonymous mutex, using @code{with-mutex}.
336 [FIXME: Is there any way to access the mutex?]
343 @c docstring begin (texi-doc-string "guile" "make-fluid")
344 @deffn primitive make-fluid
345 Return a newly created fluid.
346 Fluids are objects of a certain type (a smob) that can hold one SCM
347 value per dynamic root. That is, modifications to this value are
348 only visible to code that executes within the same dynamic root as
349 the modifying code. When a new dynamic root is constructed, it
350 inherits the values from its parent. Because each thread executes
351 in its own dynamic root, you can use fluids for thread local storage.
354 @c docstring begin (texi-doc-string "guile" "fluid?")
355 @deffn primitive fluid? obj
356 Return @code{#t} iff @var{obj} is a fluid; otherwise, return
360 @c docstring begin (texi-doc-string "guile" "fluid-ref")
361 @deffn primitive fluid-ref fluid
362 Return the value associated with @var{fluid} in the current
363 dynamic root. If @var{fluid} has not been set, then return
367 @c docstring begin (texi-doc-string "guile" "fluid-set!")
368 @deffn primitive fluid-set! fluid value
369 Set the value associated with @var{fluid} in the current dynamic root.
372 @c docstring begin (texi-doc-string "guile" "with-fluids*")
373 @deffn primitive with-fluids* fluids values thunk
374 Set @var{fluids} to @var{values} temporary, and call @var{thunk}.
375 @var{fluids} must be a list of fluids and @var{values} must be the same
376 number of their values to be applied. Each substitution is done
377 one after another. @var{thunk} must be a procedure with no argument.
382 @c TeX-master: "guile.texi"