source: trunk/source/doc/src/threads.xml @ 11688

Last change on this file since 11688 was 11688, checked in by gb, 11 years ago

Don't claim that a process can suspend itself.

File size: 110.1 KB
Line 
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
3          <!ENTITY rest "<varname>&amp;rest</varname>">
4          <!ENTITY key "<varname>&amp;key</varname>">
5          <!ENTITY optional "<varname>&amp;optional</varname>">
6          <!ENTITY body "<varname>&amp;body</varname>">
7          <!ENTITY aux "<varname>&amp;aux</varname>">
8          <!ENTITY allow-other-keys "<varname>&amp;allow-other-keys</varname>">
9          <!ENTITY CCL "Clozure CL">
10          ]>
11
12<chapter id="Programming-with-Threads">
13  <title>Programming with Threads</title>
14
15  <sect1 id="Threads-overview">
16    <title>Threads Overview</title>
17
18    <para>&CCL; provides facilities which enable multiple threads
19      of execution (<emphasis>threads</emphasis>, sometimes called
20      <emphasis>lightweight processes</emphasis> or just
21      <emphasis>processes</emphasis>, though the latter term shouldn't
22      be confused with the OS's notion of a process) within a lisp
23      session. This document describes those facilities and issues
24      related to multithreaded programming in &CCL;.</para>
25
26    <para>Wherever possible, I'll try to use the term "thread" to
27      denote a lisp thread, even though many of the functions in the
28      API have the word "process" in their name. A
29      <emphasis>lisp-process</emphasis> is a lisp object (of type
30      CCL:PROCESS) which is used to control and communicate with an
31      underlying <emphasis>native thread</emphasis>. Sometimes, the
32      distinction between these two (quite different) objects can be
33      blurred; other times, it's important to maintain.</para>
34    <para>Lisp threads share the same address space, but maintain
35      their own execution context (stacks and registers) and their own
36      dynamic binding context.</para>
37   
38    <para>Traditionally, &CCL;'s threads have been
39      <emphasis>cooperatively scheduled</emphasis>: through a
40      combination of compiler and runtime support, the currently
41      executing lisp thread arranged to be interrupted at certain
42      discrete points in its execution (typically on entry to a
43      function and at the beginning of any looping construct). This
44      interrupt occurred several dozen times per second; in response,
45      a handler function might observe that the current thread had
46      used up its time slice and another function (<emphasis>the lisp
47        scheduler</emphasis>) would be called to find some other thread
48      that was in a runnable state, suspend execution of the current
49      thread, and resume execution of the newly executed thread.  The
50      process of switching contexts between the outgoing and incoming
51      threads happened in some mixture of Lisp and assembly language
52      code; as far as the OS was concerned, there was one native
53      thread running in the Lisp image and its stack pointer and other
54      registers just happened to change from time to time.</para>
55    <para>Under &CCL;'s cooperative scheduling model, it was
56      possible (via the use of the CCL:WITHOUT-INTERRUPTS construct)
57      to defer handling of the periodic interrupt that invoked the
58      lisp scheduler; it was not uncommon to use WITHOUT-INTERRUPTS to
59      gain safe, exclusive access to global data structures. In some
60      code (including much of &CCL; itself) this idiom was very
61      common: it was (justifiably) believed to be an efficient way of
62      inhibiting the execution of other threads for a short period of
63      time.</para>
64
65    <para>The timer interrupt that drove the cooperative scheduler
66      was only able to (pseudo-)preempt lisp code: if any thread
67      called a blocking OS I/O function, no other thread could be
68      scheduled until that thread resumed execution of lisp code. Lisp
69      library functions were generally attuned to this constraint, and
70      did a complicated mixture of polling and "timed blocking" in an
71      attempt to work around it. Needless to say, this code is
72      complicated and less efficient than it might be; it meant that
73      the lisp was a little busier than it should have been when it
74      was "doing nothing" (waiting for I/O to be possible.)</para>
75
76    <para>For a variety of reasons - better utilization of CPU
77      resources on single and multiprocessor systems and better
78      integration with the OS in general - threads in &CCL; 0.14 and
79      later are <emphasis>preemptively scheduled. </emphasis>In this
80      model, lisp threads are native threads and all scheduling
81      decisions involving them are made by the OS kernel. (Those
82      decisions might involve scheduling multiple lisp threads
83      simultaneously on multiple processors on SMP systems.) This
84      change has a number of subtle effects:</para>
85
86    <itemizedlist>
87      <listitem>
88            <para>it is possible for two (or more) lisp threads to be
89              executing simultaneously, possibly trying to access and/or
90              modify the same data structures. Such access really should
91              have been coordinated through the use of synchronization
92              objects regardless of the scheduling modeling effect;
93              preemptively scheduled threads increase the chance of things
94              going wrong at the wrong time and do not offer
95              lightweight alternatives to the use of those synchronization
96              objects.</para>
97          </listitem>
98      <listitem>
99            <para>even on a single-processor system, a context switch
100              can happen on any instruction boundary. Since (in general)
101              other threads might allocate memory, this means that a GC can
102              effectively take place at any instruction boundary. That's
103              mostly an issue for the compiler and runtime system to be
104              aware of, but it means that certain practices(such as trying
105              to pass the address of a lisp object to foreign code)that
106              were always discouraged are now discouraged
107              ... vehemently.</para>
108          </listitem>
109      <listitem>
110            <para>there is no simple and efficient way to "inhibit the
111              scheduler"or otherwise gain exclusive access to the entire
112              CPU.</para>
113          </listitem>
114      <listitem>
115            <para>There are a variety of simple and efficient ways
116              to synchronize access to particular data
117              structures.</para>
118          </listitem>
119    </itemizedlist>
120    <para>As a broad generalization: code that's been aggressively
121      tuned to the constraints of the cooperative scheduler may need
122      to be redesigned to work well with the preemptive scheduler (and
123      code written to run under &CCL;'s interface to the native
124      scheduler may be less portable to other CL implementations, many
125      of which offer a cooperative scheduler and an API similar to
126      &CCL; (&lt; 0.14) 's.) At the same time, there's a large
127      overlap in functionality in the two scheduling models, and it'll
128      hopefully be possible to write interesting and useful MP code
129      that's largely independent of the underlying scheduling
130      details.</para>
131    <para>The keyword :OPENMCL-NATIVE-THREADS is on *FEATURES* in
132      0.14 and later and can be used for conditionalization where
133      required.</para>
134  </sect1>
135
136  <sect1 id="Intentionally--Missing-Functionality">
137    <title>(Intentionally) Missing Functionality</title>
138    <para>Much of the functionality described above is similar to
139      that provided by &CCL;'s cooperative scheduler, some other
140      parts of which make no sense in a native threads
141      implementation.</para>
142    <itemizedlist>
143      <listitem>
144            <para>PROCESS-RUN-REASONS and PROCESS-ARREST-REASONS were
145              SETFable process attributes; each was just a list of
146              arbitrary tokens. A thread was eligible for scheduling
147              (roughly equivalent to being "enabled") if its arrest-reasons
148              list was empty and its run-reasons list was not. I don't
149              think that it's appropriate to encourage a programming style
150              in which otherwise runnable threads are enabled and disabled
151              on a regular basis (it's preferable for threads to wait for
152              some sort of synchronization event to occur if they can't
153              occupy their time productively.)</para>
154          </listitem>
155      <listitem>
156            <para>There were a number of primitives for maintaining
157              process queues;that's now the OS's job.</para>
158          </listitem>
159      <listitem>
160            <para>Cooperative threads were based on coroutining
161              primitives associated with objects of type
162              STACK-GROUP. STACK-GROUPs no longerexist.</para>
163          </listitem>
164    </itemizedlist>
165  </sect1>
166
167
168  <sect1 id="Implementation-Decisions-and-Open-Questions">
169    <title>Implementation Decisions and Open Questions</title>
170    <sect2 id="Thread-Stack-Sizes">
171      <title>Thread Stack Sizes</title>
172      <para>When you use MAKE-PROCESS to create a thread, you can
173        specify a stack size. &CCL; does not impose a limit on the stack
174        size you choose, but there is some evidence that choosing a
175        stack size larger than the operating system's limit can cause
176        excessive paging activity, at least on some operating
177        systems.</para>
178      <para>The maximum stack size is operating-system-dependent. You
179        can use shell commands to determine what it is on your
180        platform. In bash, use "ulimit -s -H" to find the limit; in
181        tcsh, use "limit -h s".</para>
182      <para>This issue does not affect programs that create threads
183        using the default stack size, which you can do either by
184        specifying no value for the :stack-size argument to
185        MAKE-PROCESS, or by specifying the value
186        CCL::*default-control-stack-size*.</para>
187      <para>If your program creates threads with a specified stack size,
188        and that size is larger than the OS-specified limit, you may want
189        to consider reducing the stack size in order to avoid possible
190        excessive paging activity.</para>
191    </sect2>
192    <sect2>
193      <title> As of August 2003:</title>
194      <itemizedlist>
195        <listitem>
196              <para>It's not clear that exposing
197                PROCESS-SUSPEND/PROCESS-RESUME is a good idea: it's not clear
198                that they offer ways to win, and it's clear that they offer
199                ways to lose.</para>
200            </listitem>
201        <listitem>
202              <para>It has traditionally been possible to reset and enable
203                a process that's "exhausted" . (As used here, the
204                term"exhausted" means that the process's initial function
205                has run and returned and the underlying native thread has
206                been deallocated.) One of the principal uses of PROCESS-RESET
207                is to "recycle" threads; enabling an exhausted process
208                involves creating a new native thread (and stacks and
209                synchronization objects and ...),and this is the sort of
210                overhead that such a recycling scheme is seeking to avoid. It
211                might be worth trying to tighten things up and declare that
212                it's an error to apply PROCESS-ENABLE to an exhausted thread
213                (and to make PROCESS-ENABLE detect this error.)</para>
214            </listitem>
215        <listitem>
216              <para>When native threads that aren't created by &CCL;
217                first call into lisp, a "foreign process" is created, and
218                that process is given its own set of initial bindings and set
219                up to look mostly like a process that had been created by
220                MAKE-PROCESS. The life cycle of a foreign process is
221                certainly different from that of a lisp-created one: it
222                doesn't make sense to reset/preset/enable a foreign process,
223                and attempts to perform these operations should be
224                detected and treated as errors.</para>
225            </listitem>
226      </itemizedlist>
227    </sect2>
228  </sect1>
229
230
231
232  <sect1 id="Porting-Code-from-the-Old-Thread-Model">
233    <title>Porting Code from the Old Thread Model</title>
234    <para>Older versions of &CCL; used what are often called
235      "user-mode threads", a less versatile threading model which does
236      not require specific support from the operating system.  This
237      section discusses how to port code which was written for that
238      mode.</para>
239    <para>It's hard to give step-by-step instructions; there are certainly
240      a few things that one should look at carefully:</para>
241    <itemizedlist>
242      <listitem>
243            <para>It's wise to be suspicious of most uses
244              of WITHOUT-INTERRUPTS; there may be exceptions, but
245              WITHOUT-INTERRUPTS is often used as shorthand for
246              WITH-APPROPRIATE-LOCKING. Determining what type of locking
247              is appropriate and writing the code to implement it is
248              likely to be straightforward and simple most of the
249              time.</para>
250          </listitem>
251      <listitem>
252            <para>I've only seen one case where a process's "run reasons"
253              were used to communicate information as well as to control
254              execution; I don't think that this is a common idiom, but may
255              be mistaken about that.
256            </para>
257          </listitem>
258      <listitem>
259            <para>It's certainly possible that programs written
260              for cooperatively scheduled lisps that have run reliably for
261              a long time have done so by accident: resource-contention
262              issues tend to be timing-sensitive, and decoupling thread
263              scheduling from lisp program execution affects timing. I know
264              that there is or was code in both &CCL; and commercial MCL
265              that was written under the explicit assumption that certain
266              sequences of open-coded operations were uninterruptable; it's
267              certainly possible that the same assumptions have been made
268              (explicitly or otherwise) by application developers.</para>
269          </listitem>
270    </itemizedlist>
271  </sect1>
272
273  <sect1 id="Background-Terminal-Input">
274    <title>Background Terminal Input</title>
275
276    <sect2 id="backgrount-ti-overview">
277      <title>Overview</title>
278          <para>
279            Unless and until &CCL; provides alternatives (via window
280            streams, telnet streams, or some other mechanism) all lisp
281            processes share a common *TERMINAL-IO* stream (and therefore
282            share *DEBUG-IO*, *QUERY-IO*, and other standard and
283            internal interactive streams.)</para>
284          <para>It's anticipated that most lisp processes other than
285            the "Initial" process run mostly in the background. If a
286            background process writes to the output side of
287            *TERMINAL-IO*, that may be a little messy and a little
288            confusing to the user, but it shouldn't really be
289            catastrophic. All I/O to &CCL;'s buffered streams goes
290            thru a locking mechanism that prevents the worst kinds of
291            resource-contention problems.</para>
292          <para>Although the problems associated with terminal output
293            from multiple processes may be mostly cosmetic, the question
294            of which process receives input from the terminal is likely
295            to be a great deal more important. The stream locking
296            mechanisms can make a confusing situation even worse:
297            competing processes may "steal" terminal input from each
298            other unless locks are held longer than they otherwise need
299            to be, and locks can be held longer than they need to be (as
300            when a process is merely waiting for input to become
301            available on an underlying file descriptor).</para>
302          <para>Even if background processes rarely need to
303            intentionally read input from the terminal, they may still
304            need to do so in response to errors or other unanticipated
305            situations. There are tradeoffs involved in any solution to
306            this problem. The protocol described below allows background
307            processes which follow it to reliably prompt for and receive
308            terminal input. Background processes which attempt to
309            receive terminal input without following this protocol will
310            likely hang indefinitely while attempting to do so. That's
311            certainly a harsh tradeoff, but since attempts to read
312            terminal input without following this protocol only worked
313            some of the time anyway, it doesn't seem to be an
314            unreasonable one.</para>
315          <para>In the solution described here (and introduced in
316            &CCL; 0.9), the internal stream used to provide terminal
317            input is always locked by some process (the "owning"
318            process.) The initial process (the process that typically
319            runs the read-eval-print loop) owns that stream when it's
320            first created. By using the macro WITH-TERMINAL-INPUT,
321            background processes can temporarily obtain ownership of the
322            terminal and relinquish ownership to the previous owner when
323            they're done with it.</para>
324          <para>In &CCL;, BREAK, ERROR, CERROR, Y-OR-N-P,
325            YES-OR-NO-P, and CCL:GET-STRING- FROM-USER are all defined
326            in terms of WITH-TERMINAL-INPUT, as are the :TTY
327            user-interfaces to STEP and INSPECT.</para>
328    </sect2>
329
330    <sect2 id="background-terminal-example">
331      <title>An example</title>
332
333      <programlisting>
334? Welcome to &CCL; Version (Beta: linux) 0.9!
335?
336
337? (process-run-function "sleeper" #'(lambda () (sleep 5) (break "broken")))
338#&lt;PROCESS sleeper(1) [Enabled] #x3063B33E&gt;
339
340?
341;;
342;; Process sleeper(1) needs access to terminal input.
343;;
344      </programlisting>
345
346      <para>This example was run under ILISP; ILISP often gets confused if one
347            tries to enter input and "point" doesn't follow a prompt.
348            Entering a "simple" expression at this point gets it back in
349            synch; that's otherwise not relevant to this example.</para>
350
351          <programlisting>
352()
353NIL
354? (:y 1)
355;;
356;; process sleeper(1) now controls terminal input
357;;
358> Break in process sleeper(1): broken
359> While executing: #&lt;Anonymous Function #x3063B276&gt;
360> Type :GO to continue, :POP to abort.
361> If continued: Return from BREAK.
362Type :? for other options.
3631 &gt; :b
364(30C38E30) : 0 "Anonymous Function #x3063B276" 52
365(30C38E40) : 1 "Anonymous Function #x304984A6" 376
366(30C38E90) : 2 "RUN-PROCESS-INITIAL-FORM" 340
367(30C38EE0) : 3 "%RUN-STACK-GROUP-FUNCTION" 768
3681 &gt; :pop
369;;
370;; control of terminal input restored to process Initial(0)
371;;
372?
373      </programlisting>
374    </sect2>
375
376    <sect2 id="A-more-elaborate-example-">
377      <title>A more elaborate example.</title>
378          <para>If a background process ("A") needs access to the terminal
379            input stream and that stream is owned by another background process
380            ("B"), process "A" announces that fact, then waits until
381            the initial process regains control.</para>
382
383          <programlisting>
384? Welcome to &CCL; Version (Beta: linux) 0.9!
385?
386
387? (process-run-function "sleep-60" #'(lambda () (sleep 60) (break "Huh?")))
388#&lt;PROCESS sleep-60(1) [Enabled] #x3063BF26&gt;
389
390? (process-run-function "sleep-5" #'(lambda () (sleep 5) (break "quicker")))
391#&lt;PROCESS sleep-5(2) [Enabled] #x3063D0A6&gt;
392
393?       ;;
394;; Process sleep-5(2) needs access to terminal input.
395;;
396()
397NIL
398
399? (:y 2)
400;;
401;; process sleep-5(2) now controls terminal input
402;;
403> Break in process sleep-5(2): quicker
404> While executing: #x3063CFDE>
405> Type :GO to continue, :POP to abort.
406> If continued: Return from BREAK.
407Type :? for other options.
4081 >     ;; Process sleep-60(1) will need terminal access when
409;; the initial process regains control of it.
410;;
411()
412NIL
4131 > :pop
414;;
415;; Process sleep-60(1) needs access to terminal input.
416;;
417;;
418;; control of terminal input restored to process Initial(0)
419;;
420
421? (:y 1)
422;;
423;; process sleep-60(1) now controls terminal input
424;;
425> Break in process sleep-60(1): Huh?
426> While executing: #x3063BE5E>
427> Type :GO to continue, :POP to abort.
428> If continued: Return from BREAK.
429Type :? for other options.
4301 > :pop
431;;
432;; control of terminal input restored to process Initial(0)
433;;
434
435?
436      </programlisting>
437
438    </sect2>
439
440    <sect2 id="Summary">
441          <title>Summary</title>
442          <para>This scheme is certainly not bulletproof: imaginative
443            use of PROCESS-INTERRUPT and similar functions might be able
444            to defeat it and deadlock the lisp, and any scenario where
445            several background processes are clamoring for access to the
446            shared terminal input stream at the same time is likely to be
447            confusing and chaotic. (An alternate scheme, where the input
448            focus was magically granted to whatever thread the user was
449            thinking about, was considered and rejected due to technical
450            limitations.)</para>
451          <para>The longer-term fix would probably involve using network or
452            window-system streams to give each process unique instances of
453            *TERMINAL-IO*.</para>
454      <para>Existing code that attempts to read from *TERMINAL-IO*
455        from a background process will need to be changed to use
456        WITH-TERMINAL-INPUT.  Since that code was probably not working
457        reliably in previous versions of &CCL;, this requirement
458        doesn't seem to be too onerous.</para>
459      <para>Note that WITH-TERMINAL-INPUT both requests ownership of
460        the terminal input stream and promises to restore that
461        ownership to the initial process when it's done with it. An ad
462        hoc use of READ or READ-CHAR doesn't make this promise; this
463        is the rationale for the restriction on the :Y command.</para>
464    </sect2>
465  </sect1>
466
467  <sect1 id="The-Threads-which-CCL-Uses-for-Its-Own-Purposes">
468    <title>The Threads which &CCL; Uses for Its Own Purposes</title>
469    <para>
470      In the "tty world", &CCL; starts out with 2 lisp-level threads:</para>
471
472    <programlisting>
473? :proc
4741 : -> listener     [Active]
4750 :    Initial      [Active]
476    </programlisting>
477
478    <para>If you look at a running &CCL; with a debugging tool,
479      such as GDB, or Apple's Thread Viewer.app, you'll see an
480      additional kernel-level thread on Darwin; this is used by the
481      Mach exception-handling mechanism.</para>
482    <para>The initial thread, conveniently named "initial", is the
483      one that was created by the operating system when it launched
484      &CCL;.  It maps the heap image into memory, does some
485      Lisp-level initialization, and, when the Cocoa IDE isn't being
486      used, creates the thread "listener", which runs the top-level
487      loop that reads input, evaluates it, and prints the
488      result.</para>
489    <para>After the listener thread is created, the initial thread
490      does "housekeeping": it sits in a loop, sleeping most of the
491      time and waking up occasionally to do "periodic tasks".  These
492      tasks include forcing output on specified interactive streams,
493      checking for and handling control-C interrupts, etc.  Currently,
494      those tasks also include polling for the exit status of external
495      processes and handling some kinds of I/O to and from those
496      processes.</para>
497    <para>In this environment, the initial thread does these
498      "housekeeping" activities as necessary, until
499      <literal>ccl:quit</literal> is called;
500      <literal>quit</literal>ting interrupts the initial thread, which
501      then ends all other threads in as orderly a fashion as possible
502      and calls the C function <literal>#_exit</literal>.</para>
503    <para>The short-term plan is to handle each external-process in
504      a dedicated thread; the worst-case behavior of the current
505      scheme can involve busy-waiting and excessive CPU utilization
506      while waiting for an external process to terminate in some
507      cases.</para>
508    <para>The Cocoa features use more threads.  Adding a Cocoa
509      listener creates two threads:</para>
510
511    <programlisting>
512      ? :proc
513      3 : -> Listener     [Active]
514      2 :    housekeeping  [Active]
515      1 :    listener     [Active]
516      0 :    Initial      [Active]
517    </programlisting>
518
519    <para>The Cocoa event loop has to run in the initial thread;
520      when the event loop starts up, it creates a new thread to do the
521      "housekeeping" tasks which the initial thread would do in the
522      terminal-only mode.  The initial thread then becomes the one to
523      receive all Cocoa events from the window server; it's the only
524      thread which can.</para>
525    <para>It also creates one "Listener" (capital-L) thread for each
526      listener window, with a lifetime that lasts as long as the
527      thread does.  So, if you open a second listener, you'll see five
528      threads all together:</para>
529
530    <programlisting>
531      ? :proc
532      4 : -> Listener-2   [Active]
533      3 :    Listener     [Active]
534      2 :    housekeeping  [Active]
535      1 :    listener     [Active]
536      0 :    Initial      [Active]
537    </programlisting>
538
539    <para>Unix signals, such as SIGINT (control-C), invoke a handler
540      installed by the Lisp kernel.  Although the OS doesn't make any
541      specific guarantee about which thread will receive the signal,
542      in practice, it seems to be the initial thread.  The handler
543      just sets a flag and returns; the housekeeping thread (which may
544      be the initial thread, if Cocoa's not being used) will check for
545      the flag and take whatever action is appropriate to the
546      signal.</para>
547    <para>In the case of SIGINT, the action is to enter a break
548      loop, by calling on the thread being interrupted.  When there's
549      more than one Lisp listener active, it's not always clear what
550      thread that should be, since it really depends on the user's
551      intentions, which there's no way to divine programmatically.  To
552      make its best guess, the handler first checks whether the value
553      of <literal>ccl:*interactive-abort-process*</literal> is a
554      thread, and, if so, uses it.  If that fails, it chooses the
555      thread which currently "owns" the default terminal input stream;
556      see .</para>
557    <para>In the bleeding-edge version of the Cocoa support which is
558      based on Hemlock, an Emacs-like editor, each editor window has a
559      dedicated thread associated with it.  When a keypress event
560      comes in which affects that specific window the initial thread
561      sends it to the window's dedicated thread.  The dedicated thread
562      is responsible for trying to interpret keypresses as Hemlock
563      commands, applying those commands to the active buffer; it
564      repeats this in a loop, until the window closes.  The initial
565      thread handles all other events, such as mouse clicks and
566      drags.</para>
567    <para>This thread-per-window scheme makes many things simpler,
568      including the process of entering a "recursive command loop" in
569      commands like "Incremental Search Forward", etc.  (It might be
570      possible to handle all Hemlock commands in the Cocoa event
571      thread, but these "recursive command loops" would have to
572      maintain a lot of context/state information; threads are a
573      straightforward way of maintaining that information.)</para>
574    <para>Currently (August 2004), when a dedicated thread needs to
575      alter the contents of the buffer or the selection, it does so by
576      invoking methods in the initial thread, for synchronization
577      purposes, but this is probably overkill and will likely be
578      replaced by a more efficient scheme in the future.</para>
579    <para>The per-window thread could probably take more
580      responsibility for drawing and handling the screen than it
581      currently does; -something- needs to be done to buffer screen
582      updates a bit better in some cases: you don't need to see
583      everything that happens during something like indentation; you
584      do need to see the results...</para>
585    <para>When Hemlock is being used, listener windows are editor
586      windows, so in addition to each "Listener" thread, you should
587      also see a thread which handles Hemlock command
588      processing.</para>
589    <para>The Cocoa runtime may make additional threads in certain
590      special situations; these threads usually don't run lisp code,
591      and rarely if ever run much of it.</para>
592  </sect1>
593
594  <sect1 id="Threads-Dictionary">
595    <title>Threads Dictionary</title>
596    <refentry id="f_all-processes">
597          <indexterm zone="f_all-processes">
598            <primary>all-processes</primary>
599          </indexterm>
600
601          <refnamediv>
602            <refname>ALL-PROCESSES</refname>
603            <refpurpose>Obtain a fresh list of all known Lisp
604              threads.</refpurpose>
605            <refclass>Function</refclass>
606          </refnamediv>
607
608          <refsynopsisdiv>
609            <synopsis>
610              <function>all-processes</function> => result
611            </synopsis>
612          </refsynopsisdiv>
613
614          <refsect1>
615            <title>Values</title>
616           
617            <variablelist>
618              <varlistentry>
619                <term>result</term>
620                <listitem>
621                      <para>a list of all lisp processes (threads)
622                        known to &CCL;.</para>
623                </listitem>
624              </varlistentry>
625            </variablelist>
626          </refsect1>
627          <refsect1>
628            <title>Description</title>
629
630            <para>Returns a list of all lisp processes (threads) known
631              to &CCL; as of
632              the precise instant it&#39;s called. It&#39;s safe to traverse
633              this list and to modify the cons cells that comprise that list
634              (it&#39;s freshly consed.) Since other threads can create and kill
635              threads at any time, there&#39;s generally no way to get an
636              &#34;accurate&#34; list of all threads, and (generally) no
637              sense in which such a list can be accurate.</para>
638          </refsect1>
639
640          <refsect1>
641            <title>See Also</title>
642           
643            <simplelist type="inline">
644              <member><xref linkend="v_current-process"/></member>
645            </simplelist>
646          </refsect1>
647    </refentry>
648
649    <refentry id="f_make-process">
650          <indexterm zone="f_make-process">
651            <primary>make-process</primary>
652          </indexterm>
653
654          <refnamediv>
655            <refname>MAKE-PROCESS</refname>
656            <refpurpose>Creates and returns a new process.</refpurpose>
657            <refclass>Function</refclass>
658          </refnamediv>
659
660          <refsynopsisdiv>
661            <synopsis>
662              <function>make-process</function>
663              name &amp;key
664              persistent priority class stack-size vstack-size
665              tstack-size initial-bindings use-standard-initial-bindings
666              => process
667            </synopsis>
668          </refsynopsisdiv>
669
670          <refsect1>
671            <title>Arguments and Values</title>
672           
673            <variablelist>
674              <varlistentry>
675                <term>name</term>
676               
677                <listitem>
678                      <para>a string, used to identify the process.</para>
679                </listitem>
680              </varlistentry>
681             
682              <varlistentry>
683                <term>persistent</term>
684               
685                <listitem>
686                      <para>if true, requests that information about the process
687                        be retained by SAVE-APPLICATION so that an equivalent
688                        process can be restarted when a saved image is run.  The
689                        default is nil.</para>
690                </listitem>
691              </varlistentry>
692             
693              <varlistentry>
694                <term>priority</term>
695               
696                <listitem>
697                      <para>ignored.  It
698                        shouldn't be ignored of course, but there are
699                        complications on some platforms.  The default is 0.</para>
700                </listitem>
701              </varlistentry>
702             
703              <varlistentry>
704                <term>class</term>
705               
706                <listitem>
707                      <para>the class of process object to create;
708                        should be a subclass of CCL:PROCESS.  The default is
709                        CCL:PROCESS.</para>
710                </listitem>
711              </varlistentry>
712             
713              <varlistentry>
714                <term>stack-size</term>
715               
716                <listitem>
717                      <para>the size, in bytes, of the newly-created process's
718                        control stack; used for foreign function calls and to save
719                        function return address context.  The default is
720                        CCL:*DEFAULT-CONTROL-STACK-SIZE*.</para>
721                </listitem>
722              </varlistentry>
723             
724              <varlistentry>
725                <term>vstack-size</term>
726               
727                <listitem>
728                      <para>the size, in bytes, of the newly-created process's
729                        value stack; used for lisp function arguments, local
730                        variables, and other stack-allocated lisp objects.
731                        The default is CCL:*DEFAULT-VALUE-STACK-SIZE*.</para>
732                </listitem>
733              </varlistentry>
734             
735              <varlistentry>
736                <term>tstack-size</term>
737               
738                <listitem>
739                      <para>the size, in bytes, of the newly-created process's
740                        temp stack; used for the allocation of dynamic-extent
741                        objects.  The default is CCL:*DEFAULT-TEMP-STACK-SIZE*.</para>
742                </listitem>
743              </varlistentry>
744             
745              <varlistentry>
746                <term>use-standard-initial-bindings</term>
747               
748                <listitem>
749                      <para>when true, the global "standard initial
750                        bindings" are put into effect in the new thread before. See
751                        DEF-STANDARD-INITIAL-BINDING.  "standard" initial bindings
752                        are put into effect before any bindings specified by
753                        :initial-bindings are.  The default is t.</para>
754                </listitem>
755              </varlistentry>
756             
757              <varlistentry>
758                <term>initial-bindings</term>
759               
760                <listitem>
761                      <para>an alist of (<varname>symbol</varname> .
762                        <varname>valueform</varname>) pairs, which can be
763                        used to initialize special variable bindings in the new
764                        thread. Each <varname>valueform</varname> is used to
765                        compute the value of a new binding of
766                        <varname>symbol</varname> in the execution environment of
767                        the newly-created thread.  The default is nil.</para>
768                </listitem>
769              </varlistentry>
770             
771              <varlistentry>
772                <term>process</term>
773               
774                <listitem>
775                      <para>the newly-created process.</para>
776                </listitem>
777              </varlistentry>
778            </variablelist>
779          </refsect1>
780
781          <refsect1>
782            <title>Description</title>
783
784            <para>Creates and returns a new lisp process (thread) with the
785              specified attributes. <varname>process</varname> will not begin
786              execution immediately; it will need to be
787              <emphasis>preset</emphasis> (given
788              an initial function to run, as by
789              <xref linkend="f_process-preset"/>) and
790              <emphasis>enabled</emphasis>
791              (allowed to execute, as by <xref linkend="f_process-enable"/>)
792              before it&#39;s able to actually do anything.</para>
793
794            <para>If <varname>valueform</varname> is a function, it is
795              called, with no arguments, in the execution environment of the
796              newly-created thread; the primary value it returns is used for
797              the binding of the corresponding <varname>symbol</varname>.</para>
798
799            <para>Otherwise, <varname>valueform</varname> is evaluated in the
800              execution
801              environment of the newly-created thread, and the resulting value
802              is used.</para>
803          </refsect1>
804
805          <refsect1>
806            <title>See Also</title>
807           
808            <simplelist type="inline">
809              <member><xref linkend="f_process-preset"/></member>
810              <member><xref linkend="f_process-enable"/></member>
811              <member><xref linkend="f_process-run-function"/></member>
812            </simplelist>
813          </refsect1>
814    </refentry>
815
816    <refentry id="f_process-suspend">
817          <indexterm zone="f_process-suspend">
818            <primary>process-suspend</primary>
819          </indexterm>
820
821          <refnamediv>
822            <refname>PROCESS-SUSPEND</refname>
823            <refpurpose>Suspends a specified process.</refpurpose>
824            <refclass>Function</refclass>
825          </refnamediv>
826         
827          <refsynopsisdiv>
828            <synopsis><function>process-suspend</function> process
829              => result</synopsis>
830          </refsynopsisdiv>
831
832          <refsect1>
833            <title>Arguments and Values</title>
834           
835            <variablelist>
836              <varlistentry>
837                <term>process</term>
838                <listitem>
839                      <para>a lisp process (thread).</para>
840                </listitem>
841              </varlistentry>
842              <varlistentry>
843                <term>result</term>
844                <listitem>
845                      <para>T if <varname>process</varname> had been runnable
846                        and is now suspended; NIL otherwise.  That is, T if
847                        <varname>process</varname>'s
848                        <xref linkend="f_process-suspend-count"/>
849                        transitioned from 0 to 1.</para>
850                </listitem>
851              </varlistentry>
852            </variablelist>
853          </refsect1>
854
855          <refsect1>
856            <title>Description</title>
857
858            <para>Suspends <varname>process</varname>, preventing it from
859              running, and stopping it if it was already running. This is a fairly
860              expensive operation, because it involves a few
861              calls to the OS.  It also risks creating deadlock if used
862              improperly, for instance, if the process being suspended owns a
863              lock or other resource which another process will wait for.</para>
864
865            <para>
866              Each
867              call to <function>process-suspend</function> must be reversed by
868              a matching call to <xref linkend="f_process-resume"/>
869              before <varname>process</varname> is able to run.  What
870              <function>process-suspend</function> actually does is increment
871              the <xref linkend="f_process-suspend-count"/> of
872              <varname>process</varname>.
873            </para>
874
875            <para>A process can't suspend itself, though this once
876            worked and this documentation claimed has claimed that it
877            did.</para>
878          </refsect1>
879
880          <refsect1>
881            <title>See Also</title>
882           
883            <simplelist type="inline">
884              <member><xref linkend="f_process-resume"/></member>
885              <member><xref linkend="f_process-suspend-count"/></member>
886            </simplelist>
887          </refsect1>
888
889          <refsect1>
890            <title>Notes</title>
891            <para><function>process-suspend</function> was previously called
892              <function>process-disable</function>.
893              <xref linkend="f_process-enable"/>
894              now names a function for which there is no
895              obvious inverse, so <function>process-disable</function>
896              is no longer
897              defined.</para>
898          </refsect1>
899    </refentry>
900
901    <refentry id="f_process-resume">
902          <indexterm zone="f_process-resume">
903            <primary>process-resume</primary>
904          </indexterm>
905
906          <refnamediv>
907            <refname>PROCESS-RESUME</refname>
908            <refpurpose>Resumes a specified process which had previously
909              been suspended by process-suspend.</refpurpose>
910            <refclass>Function</refclass>
911          </refnamediv>
912
913          <refsynopsisdiv>
914            <synopsis><function>process-resume</function> process
915              => result</synopsis>
916          </refsynopsisdiv>
917
918          <refsect1>
919            <title>Arguments and Values</title>
920           
921            <variablelist>
922              <varlistentry>
923                <term>process</term>
924                <listitem>
925                      <para>a lisp process (thread).</para>
926                </listitem>
927              </varlistentry>
928              <varlistentry>
929                <term>result</term>
930                <listitem>
931                      <para>T if <varname>process</varname> had been suspended
932                        and is now runnable; NIL otherwise.  That is, T if
933                        <varname>process</varname>'s
934                        <xref linkend="f_process-suspend-count"/>
935                        transitioned from  to 0.
936                      </para>
937                </listitem>
938              </varlistentry>
939            </variablelist>
940          </refsect1>
941
942          <refsect1>
943            <title>Description</title>
944
945            <para>Undoes the effect of a previous call to
946              <xref linkend="f_process-suspend"/>; if
947              all such calls are undone, makes the process runnable. Has no
948              effect if the process is not suspended.  What
949              <function>process-resume</function> actually does is decrement
950              the <xref linkend="f_process-suspend-count"/> of
951              <varname>process</varname>, to a minimum of 0.</para>
952          </refsect1>
953
954          <refsect1>
955            <title>See Also</title>
956           
957            <simplelist type="inline">
958              <member><xref linkend="f_process-suspend"/></member>
959              <member><xref linkend="f_process-suspend-count"/></member>
960            </simplelist>
961          </refsect1>
962
963          <refsect1>
964            <title>Notes</title>
965
966            <para>
967              This was previously called PROCESS-ENABLE;
968              <xref linkend="f_process-enable"/> now does something slightly
969              different.
970            </para>
971          </refsect1>
972    </refentry>
973
974    <refentry id="f_process-suspend-count">
975          <indexterm zone="f_process-suspend-count">
976            <primary>process-suspend-count</primary>
977          </indexterm>
978
979          <refnamediv>
980            <refname>PROCESS-SUSPEND-COUNT</refname>
981            <refpurpose>Returns the number of currently-pending suspensions
982              applicable to a given process.</refpurpose>
983            <refclass>Function</refclass>
984          </refnamediv>
985
986          <refsynopsisdiv>
987            <synopsis>
988              <function>process-suspend-count</function>
989              process => result
990            </synopsis>
991          </refsynopsisdiv>
992
993          <refsect1>
994            <title>Arguments and Values</title>
995
996            <variablelist>
997              <varlistentry>
998                <term>process</term>
999                <listitem>
1000                      <para>a lisp process (thread).</para>
1001                </listitem>
1002              </varlistentry>
1003              <varlistentry>
1004                <term>result</term>
1005                <listitem>
1006                      <para>The number of "outstanding"
1007                        <xref linkend="f_process-suspend"/> calls on
1008                        <varname>process</varname>, or NIL if
1009                        <varname>process</varname> has expired.
1010                      </para>
1011                </listitem>
1012              </varlistentry>
1013            </variablelist>
1014          </refsect1>
1015
1016          <refsect1>
1017            <title>Description</title>
1018
1019            <para>An "outstanding" <xref linkend="f_process-suspend"/> call
1020              is one which has not yet been reversed by a call to
1021              <xref linkend="f_process-resume"/>.  A process expires when
1022              its initial function returns, although it may later be
1023              reset.</para>
1024
1025            <para>A process is <emphasis>runnable</emphasis> when it has a
1026              <function>process-suspend-count</function> of 0, has been
1027              preset as by <xref linkend="f_process-preset"/>, and has been
1028              enabled as by <xref linkend="f_process-enable"/>.  Newly-created
1029              processes have a <function>process-suspend-count</function> of
1030              0.</para>
1031          </refsect1>
1032
1033          <refsect1>
1034            <title>See Also</title>
1035           
1036            <simplelist type="inline">
1037              <member><xref linkend="f_process-suspend"/></member>
1038              <member><xref linkend="f_process-resume"/></member>
1039            </simplelist>
1040          </refsect1>
1041    </refentry>
1042
1043    <refentry id="f_process-preset">
1044          <indexterm zone="f_process-preset">
1045            <primary>process-preset</primary>
1046          </indexterm>
1047
1048          <refnamediv>
1049            <refname>PROCESS-PRESET</refname>
1050            <refpurpose>Sets the initial function and arguments of a specified
1051              process.</refpurpose>
1052            <refclass>Function</refclass>
1053          </refnamediv>
1054
1055          <refsynopsisdiv>
1056            <synopsis><function>process-preset</function>
1057              process function &rest; args
1058              => result</synopsis>
1059          </refsynopsisdiv>
1060
1061          <refsect1>
1062            <title>Arguments and Values</title>
1063
1064            <variablelist>
1065              <varlistentry>
1066                <term>process</term>
1067                <listitem>
1068                      <para>a lisp process (thread).</para>
1069                </listitem>
1070              </varlistentry>
1071              <varlistentry>
1072                <term>function</term>
1073                <listitem>
1074                      <para>a function, designated by itself or by a symbol
1075                        which names it.
1076                      </para>
1077                </listitem>
1078              </varlistentry>
1079              <varlistentry>
1080                <term>args</term>
1081                <listitem>
1082                      <para>a list of values, appropriate as arguments to
1083                        <varname>function</varname>.</para>
1084                </listitem>
1085              </varlistentry>
1086              <varlistentry>
1087                <term>result</term>
1088                <listitem>
1089                      <para>undefined.</para>
1090                </listitem>
1091              </varlistentry>
1092            </variablelist>
1093          </refsect1>
1094
1095          <refsect1>
1096            <title>Description</title>
1097
1098            <para>Typically used to initialize a newly-created or newly-reset
1099              process, setting things up so that when <varname>process</varname>
1100              becomes enabled, it will begin execution by
1101              applying <varname>function</varname> to <varname>args</varname>.
1102              <function>process-preset</function> does not enable
1103              <varname>process</varname>,
1104              although a process must be <function>process-preset</function>
1105              before it can be enabled.  Processes are normally enabled by
1106              <xref linkend="f_process-enable"/>.
1107            </para>
1108          </refsect1>
1109
1110          <refsect1>
1111            <title>See Also</title>
1112           
1113            <simplelist type="inline">
1114              <member><xref linkend="f_make-process"/></member>
1115              <member><xref linkend="f_process-enable"/></member>
1116              <member><xref linkend="f_process-run-function"/></member>
1117            </simplelist>
1118          </refsect1>
1119    </refentry>
1120
1121    <refentry id="f_process-enable">
1122          <indexterm zone="f_process-enable">
1123            <primary>process-enable</primary>
1124          </indexterm>
1125
1126          <refnamediv>
1127            <refname>PROCESS-ENABLE</refname>
1128            <refpurpose>Begins executing the initial function of a specified
1129              process.</refpurpose>
1130            <refclass>Function</refclass>
1131          </refnamediv>
1132
1133          <refsynopsisdiv>
1134            <synopsis><function>process-enable</function>
1135              process &optional; timeout
1136            </synopsis>
1137          </refsynopsisdiv>
1138
1139          <refsect1>
1140            <title>Arguments and Values</title>
1141
1142            <variablelist>
1143              <varlistentry>
1144                <term>process</term>
1145                <listitem>
1146                      <para>a lisp process (thread).</para>
1147                </listitem>
1148              </varlistentry>
1149              <varlistentry>
1150                <term>timeout</term>
1151                <listitem>
1152                      <para>a time interval in seconds.  May be any
1153                        non-negative real number the <function>floor</function> of
1154                        which fits in 32 bits.  The default is 1.</para>
1155                </listitem>
1156              </varlistentry>
1157              <varlistentry>
1158                <term>result</term>
1159                <listitem>
1160                      <para>undefined.</para>
1161                </listitem>
1162              </varlistentry>
1163            </variablelist>
1164          </refsect1>
1165
1166          <refsect1>
1167            <title>Description</title>
1168
1169            <para>Tries to begin the execution of <varname>process</varname>.
1170              An error is signaled if <varname>process</varname> has never
1171              been <xref linkend="f_process-preset"/>.  Otherwise,
1172              <varname>process</varname> invokes its initial function.
1173            </para>
1174           
1175            <para><function>process-enable</function> attempts to
1176              synchronize with <varname>process</varname>, which is presumed
1177              to be reset or in the act of resetting itself.  If this attempt
1178              is not successful within the time interval specified by
1179              <varname>timeout</varname>, a continuable error is signaled,
1180              which offers the opportunity to continue waiting.
1181            </para>
1182
1183            <para>A process cannot meaningfully attempt to enable itself.</para>
1184          </refsect1>
1185
1186          <refsect1>
1187            <title>See Also</title>
1188           
1189            <simplelist type="inline">
1190              <member><xref linkend="f_make-process"/></member>
1191              <member><xref linkend="f_process-preset"/></member>
1192              <member><xref linkend="f_process-run-function"/></member>
1193            </simplelist>
1194          </refsect1>
1195
1196          <refsect1>
1197            <title>Notes</title>
1198
1199            <para>It would be nice to have more discussion of what it means
1200              to synchronize with the process.</para>
1201          </refsect1>
1202    </refentry>
1203
1204    <refentry id="f_process-run-function">
1205          <indexterm zone="f_process-run-function">
1206            <primary>process-run-function</primary>
1207          </indexterm>
1208
1209          <refnamediv>
1210            <refname>PROCESS-RUN-FUNCTION</refname>
1211            <refpurpose>Creates a process, presets it, and enables it.
1212            </refpurpose>
1213            <refclass>Function</refclass>
1214          </refnamediv>
1215
1216          <refsynopsisdiv>
1217            <synopsis><function>process-run-function</function>
1218              process-specifier function &rest; args => process</synopsis>
1219
1220            <variablelist>
1221              <varlistentry>
1222                <term>process-specifier</term>
1223                <listitem>
1224                      <para>
1225                        <varname>name</varname> |
1226                        (&key; <varname>name</varname>
1227                        <varname>persistent</varname>
1228                        <varname>priority</varname>
1229                        <varname>class</varname>
1230                        <varname>stack-size</varname>
1231                        <varname>vstack-size</varname>
1232                        <varname>tstack-size</varname>)
1233                      </para>
1234                </listitem>
1235              </varlistentry>
1236            </variablelist>
1237          </refsynopsisdiv>
1238
1239          <refsect1>
1240            <title>Arguments and Values</title>
1241
1242            <variablelist>
1243              <varlistentry>
1244                <term>name</term>
1245                <listitem>
1246                      <para>a string, used to identify the process.
1247                        Passed to <function>make-process</function>.</para>
1248                </listitem>
1249              </varlistentry>
1250              <varlistentry>
1251                <term>function</term>
1252                <listitem>
1253                      <para>a function, designated by itself or by a symbol
1254                        which names it.  Passed to
1255                        <function>preset-process</function>.
1256                      </para>
1257                </listitem>
1258              </varlistentry>
1259              <varlistentry>
1260                <term>persistent</term>
1261               
1262                <listitem>
1263                      <para>a boolean, passed to <function>make-process</function>.
1264                      </para>
1265                </listitem>
1266              </varlistentry>
1267             
1268              <varlistentry>
1269                <term>priority</term>
1270               
1271                <listitem>
1272                      <para>ignored.</para>
1273                </listitem>
1274              </varlistentry>
1275             
1276              <varlistentry>
1277                <term>class</term>
1278               
1279                <listitem>
1280                      <para>a subclass of CCL:PROCESS.  Passed to
1281                        <function>make-process</function>.</para>
1282                </listitem>
1283              </varlistentry>
1284             
1285              <varlistentry>
1286                <term>stack-size</term>
1287               
1288                <listitem>
1289                      <para>a size, in bytes.  Passed to
1290                        <function>make-process</function>.</para>
1291                </listitem>
1292              </varlistentry>
1293             
1294              <varlistentry>
1295                <term>vstack-size</term>
1296               
1297                <listitem>
1298                      <para>a size, in bytes.  Passed to
1299                        <function>make-process</function>.</para>
1300                </listitem>
1301              </varlistentry>
1302             
1303              <varlistentry>
1304                <term>tstack-size</term>
1305               
1306                <listitem>
1307                      <para>a size, in bytes.  Passed to
1308                        <function>make-process</function>.</para>
1309                </listitem>
1310              </varlistentry>
1311              <varlistentry>
1312                <term>process</term>
1313                <listitem>
1314                      <para>the newly-created process.</para>
1315                </listitem>
1316              </varlistentry>
1317            </variablelist>
1318          </refsect1>
1319
1320          <refsect1>
1321            <title>Description</title>
1322
1323            <para>Creates a lisp process (thread) via
1324              <xref linkend="f_make-process"/>,
1325              presets it via <xref linkend="f_process-preset"/>, and
1326              enables it via <xref linkend="f_process-enable"/>.  This means
1327              that <varname>process</varname> will immediately begin to
1328              execute.
1329              <function>process-run-function</function> is
1330              the simplest way to create and run a process.
1331            </para>
1332          </refsect1>
1333
1334          <refsect1>
1335            <title>See Also</title>
1336           
1337            <simplelist type="inline">
1338              <member><xref linkend="f_make-process"/></member>
1339              <member><xref linkend="f_process-preset"/></member>
1340              <member><xref linkend="f_process-enable"/></member>
1341            </simplelist>
1342          </refsect1>
1343    </refentry>
1344
1345    <refentry id="f_process-interrupt">
1346          <indexterm zone="f_process-interrupt">
1347            <primary>process-interrupt</primary>
1348          </indexterm>
1349
1350          <refnamediv>
1351            <refname>PROCESS-INTERRUPT</refname>
1352            <refpurpose>Arranges for the target process to invoke a
1353              specified function at some point in the near future, and then
1354              return to what it was doing.</refpurpose>
1355            <refclass>Function</refclass>
1356          </refnamediv>
1357
1358          <refsynopsisdiv>
1359            <synopsis><function>process-interrupt</function>
1360              process function &rest; args => result</synopsis>
1361          </refsynopsisdiv>
1362
1363          <refsect1>
1364            <title>Arguments and Values</title>
1365
1366            <variablelist>
1367              <varlistentry>
1368                <term>process</term>
1369                <listitem>
1370                      <para>a lisp process (thread).</para>
1371                </listitem>
1372              </varlistentry>
1373              <varlistentry>
1374                <term>function</term>
1375                <listitem>
1376                      <para>a function.
1377                      </para>
1378                </listitem>
1379              </varlistentry>
1380              <varlistentry>
1381                <term>args</term>
1382                <listitem>
1383                      <para>a list of values, appropriate as arguments to
1384                        <varname>function</varname>.</para>
1385                </listitem>
1386              </varlistentry>
1387              <varlistentry>
1388                <term>result</term>
1389                <listitem>
1390                      <para>the result of applying <varname>function</varname>
1391                        to <varname>args</varname> if <varname>process</varname>
1392                        is the <function>current-process</function>, otherwise
1393                        NIL.</para>
1394                </listitem>
1395              </varlistentry>
1396            </variablelist>
1397          </refsect1>
1398
1399          <refsect1>
1400            <title>Description</title>
1401
1402            <para>Arranges for <varname>process</varname>
1403              to apply <varname>function</varname> to <varname>args</varname> at
1404              some point in the near future (interrupting whatever
1405              <varname>process</varname>
1406              was doing.) If <varname>function</varname> returns normally,
1407              <varname>process</varname> resumes
1408              execution at the point at which it was interrupted.</para>
1409
1410            <para><varname>process</varname> must be in an enabled state in
1411              order to respond
1412              to a <function>process-interrupt</function> request.  It's
1413              perfectly legal for a process to call
1414              <function>process-interrupt</function> on itself.</para>
1415
1416            <para><function>process-interrupt</function>
1417              uses asynchronous POSIX signals to interrupt threads. If the
1418              thread being interrupted is executing lisp code, it can
1419              respond to the interrupt almost immediately (as soon as it
1420              has finished pseudo-atomic operations like consing and
1421              stack-frame initialization.)</para>
1422
1423            <para>If the interrupted thread is
1424              blocking in a system call, that system call is aborted by
1425              the signal and the interrupt is handled on return.
1426            </para>
1427
1428            <para>It is
1429              still difficult to reliably interrupt arbitrary foreign code
1430              (that may be stateful or otherwise non-reentrant); the
1431              interrupt request is handled when such foreign code returns
1432              to or enters lisp.</para>
1433          </refsect1>
1434
1435          <refsect1>
1436            <title>See Also</title>
1437           
1438            <simplelist type="inline">
1439              <member><xref linkend="m_without-interrupts"/></member>
1440            </simplelist>
1441          </refsect1>
1442
1443          <refsect1>
1444            <title>Notes</title>
1445
1446            <para>It would probably be better for <varname>result</varname>
1447              to always be NIL, since the present behavior is inconsistent.
1448            </para>
1449
1450            <para>
1451              <function>Process-interrupt</function> works by sending signals
1452              between threads, via the C function
1453              <function>#_pthread_signal</function>.  It could be argued
1454              that it should be done in one of several possible other ways
1455              under
1456              Darwin, to make it practical to asynchronously interrupt
1457              things which make heavy use of the Mach nanokernel.
1458            </para>
1459          </refsect1>
1460    </refentry>
1461
1462    <refentry id="v_current-process">
1463          <indexterm zone="v_current-process">
1464            <primary>*current-process*</primary>
1465          </indexterm>
1466
1467          <refnamediv>
1468            <refname>*CURRENT-PROCESS*</refname>
1469            <refpurpose>Bound in each process, to that process
1470              itself.</refpurpose>
1471            <refclass>Variable</refclass>
1472          </refnamediv>
1473
1474          <refsect1>
1475            <title>Value Type</title>
1476
1477            <para>A lisp process (thread).</para>
1478          </refsect1>
1479
1480          <refsect1>
1481            <title>Initial Value</title>
1482           
1483            <para>Bound separately in each process, to that process itself.
1484            </para>
1485          </refsect1>
1486
1487          <refsect1>
1488            <title>Description</title>
1489
1490            <para>Used when lisp code needs to find out what process it is
1491              executing in.  Shouldn't be set by user code.</para>
1492          </refsect1>
1493
1494          <refsect1>
1495            <title>See Also</title>
1496           
1497            <simplelist type="inline">
1498              <member><xref linkend="f_all-processes"/></member>
1499            </simplelist>
1500          </refsect1>
1501    </refentry>
1502
1503    <refentry id="f_process-reset">
1504          <indexterm zone="f_process-reset">
1505            <primary>process-reset</primary>
1506          </indexterm>
1507
1508          <refnamediv>
1509            <refname>PROCESS-RESET</refname>
1510            <refpurpose>Causes a specified process to cleanly exit from
1511              any ongoing computation.</refpurpose>
1512            <refclass>Function</refclass>
1513          </refnamediv>
1514
1515          <refsynopsisdiv>
1516            <synopsis><function>process-reset</function>
1517              process &optional; kill-option => result</synopsis>
1518          </refsynopsisdiv>
1519
1520          <refsect1>
1521            <title>Arguments and Values</title>
1522
1523            <variablelist>
1524              <varlistentry>
1525                <term>process</term>
1526                <listitem>
1527                      <para>a lisp process (thread).</para>
1528                </listitem>
1529              </varlistentry>
1530              <varlistentry>
1531                <term>kill-option</term>
1532                <listitem>
1533                      <para>an internal argument, must be nil.</para>
1534                </listitem>
1535              </varlistentry>
1536              <varlistentry>
1537                <term>result</term>
1538                <listitem>
1539                      <para>undefined.</para>
1540                </listitem>
1541              </varlistentry>
1542            </variablelist>
1543          </refsect1>
1544
1545          <refsect1>
1546            <title>Description</title>
1547
1548            <para>Causes <varname>process</varname> to cleanly exit
1549              from any ongoing computation and enter a state where it can be
1550              <xref linkend="f_process-preset"/>. This
1551              is implemented by signaling a condition of type PROCESS-RESET;
1552              user-defined condition handlers should generally refrain from
1553              attempting to handle conditions of this type.</para>
1554
1555            <para>The <varname>kill-option</varname> argument is for internal
1556            use only and should not be specified by user code</para>
1557
1558            <para>A process can meaningfully reset itself.</para>
1559
1560            <para>There is in general no way to know precisely when
1561              <varname>process</varname>
1562              has completed the act of resetting or killing itself; a process
1563              which has either entered the limbo of the reset state or exited
1564              has few ways of communicating either fact.
1565              <xref linkend="f_process-enable"/>
1566              can reliably determine when a process has entered
1567              the "limbo of the reset state", but can't predict how long the
1568              clean exit from ongoing computation might take: that depends on
1569              the behavior of <function>unwind-protect</function> cleanup
1570              forms, and of the OS scheduler.</para>
1571
1572            <para>Resetting a process other than
1573              <xref linkend="v_current-process"/> involves the
1574              use of <xref linkend="f_process-interrupt"/>.</para>
1575          </refsect1>
1576
1577          <refsect1>
1578            <title>See Also</title>
1579           
1580            <simplelist type="inline">
1581              <member><xref linkend="f_process-kill"/></member>
1582              <member><xref linkend="f_process-abort"/></member>
1583            </simplelist>
1584          </refsect1>
1585    </refentry>
1586
1587    <refentry id="f_process-kill">
1588          <indexterm zone="f_process-kill">
1589            <primary>process-kill</primary>
1590          </indexterm>
1591
1592          <refnamediv>
1593            <refname>PROCESS-KILL</refname>
1594            <refpurpose>Causes a specified process to cleanly exit from any
1595              ongoing computation, and then exit.</refpurpose>
1596            <refclass>Function</refclass>
1597          </refnamediv>
1598
1599          <refsynopsisdiv>
1600            <synopsis><function>process-kill</function> process
1601              => result</synopsis>
1602          </refsynopsisdiv>
1603
1604          <refsect1>
1605            <title>Arguments and Values</title>
1606
1607            <variablelist>
1608              <varlistentry>
1609                <term>process</term>
1610                <listitem>
1611                      <para>a lisp process (thread).</para>
1612                </listitem>
1613              </varlistentry>
1614              <varlistentry>
1615                <term>result</term>
1616                <listitem>
1617                      <para>undefined.</para>
1618                </listitem>
1619              </varlistentry>
1620            </variablelist>
1621          </refsect1>
1622
1623          <refsect1>
1624            <title>Description</title>
1625
1626            <para>Entirely equivalent to calling
1627              (PROCESS-RESET PROCESS T).  Causes <varname>process</varname>
1628              to cleanly exit from any ongoing computation, and then exit.</para>
1629          </refsect1>
1630
1631          <refsect1>
1632            <title>See Also</title>
1633           
1634            <simplelist type="inline">
1635              <member><xref linkend="f_process-reset"/></member>
1636              <member><xref linkend="f_process-abort"/></member>
1637            </simplelist>
1638          </refsect1>
1639    </refentry>
1640
1641    <refentry id="f_process-abort">
1642          <indexterm zone="f_process-abort">
1643            <primary>process-abort</primary>
1644          </indexterm>
1645
1646          <refnamediv>
1647            <refname>PROCESS-ABORT</refname>
1648            <refpurpose>Causes a specified process to process an abort
1649              condition, as if it had invoked
1650              <function>abort</function>.</refpurpose>
1651            <refclass>Function</refclass>
1652          </refnamediv>
1653
1654          <refsynopsisdiv>
1655            <synopsis><function>process-abort</function> process
1656              &optional; condition
1657              => NIL</synopsis>
1658          </refsynopsisdiv>
1659
1660          <refsect1>
1661            <title>Arguments and Values</title>
1662
1663            <variablelist>
1664              <varlistentry>
1665                <term>process</term>
1666                <listitem>
1667                      <para>a lisp process (thread).</para>
1668                </listitem>
1669              </varlistentry>
1670              <varlistentry>
1671                <term>condition</term>
1672                <listitem>
1673                      <para>a lisp condition.  The default is NIL.</para>
1674                </listitem>
1675              </varlistentry>
1676            </variablelist>
1677          </refsect1>
1678
1679          <refsect1>
1680            <title>Description</title>
1681
1682            <para>Entirely equivalent to calling
1683              (<xref linkend="f_process-interrupt"/> <varname>process</varname>
1684              (<function>lambda</function> ()
1685              (<function>abort</function> <varname>condition</varname>))).
1686              Causes <varname>process</varname> to transfer control to the
1687              applicable handler or restart for <function>abort</function>.</para>
1688
1689            <para>If <varname>condition</varname> is non-NIL,
1690              <function>process-abort</function> does not consider any
1691              handlers which are explicitly bound to conditions other than
1692              <varname>condition</varname>.</para>
1693          </refsect1>
1694
1695          <refsect1>
1696            <title>See Also</title>
1697           
1698            <simplelist type="inline">
1699              <member><xref linkend="f_process-reset"/></member>
1700              <member><xref linkend="f_process-kill"/></member>
1701            </simplelist>
1702          </refsect1>
1703    </refentry>
1704
1705    <refentry id="v_ticks-per-second">
1706          <indexterm zone="v_ticks-per-second">
1707            <primary>*ticks-per-second*</primary>
1708          </indexterm>
1709
1710          <refnamediv>
1711            <refname>*TICKS-PER-SECOND*</refname>
1712            <refpurpose>Bound to the clock resolution of the OS
1713              scheduler.</refpurpose>
1714            <refclass>Variable</refclass>
1715          </refnamediv>
1716
1717          <refsect1>
1718            <title>Value Type</title>
1719
1720            <para>A positive integer.</para>
1721          </refsect1>
1722
1723          <refsect1>
1724            <title>Initial Value</title>
1725           
1726            <para>The clock resolution of the OS scheduler.  Currently,
1727              both LinuxPPC and DarwinPPC yield an initial value of 100.
1728            </para>
1729          </refsect1>
1730
1731          <refsect1>
1732            <title>Description</title>
1733
1734            <para>This value is ordinarily of marginal interest at best,
1735              but, for backward compatibility, some functions accept timeout
1736              values expressed in "ticks".  This value gives the number of
1737              ticks per second.</para>
1738          </refsect1>
1739
1740          <refsect1>
1741            <title>See Also</title>
1742           
1743            <simplelist type="inline">
1744              <member><xref linkend="f_process-wait-with-timeout"/></member>
1745            </simplelist>
1746          </refsect1>
1747    </refentry>
1748
1749    <refentry id="f_process-whostate">
1750          <indexterm zone="f_process-whostate">
1751            <primary>process-whostate</primary>
1752          </indexterm>
1753
1754          <refnamediv>
1755            <refname>PROCESS-WHOSTATE</refname>
1756            <refpurpose>Returns a string which describes the status of
1757              a specified process.</refpurpose>
1758            <refclass>Function</refclass>
1759          </refnamediv>
1760
1761          <refsynopsisdiv>
1762            <synopsis><function>process-whostate</function> process
1763              => whostate</synopsis>
1764            <variablelist>
1765              <varlistentry>
1766                <term>process</term>
1767                <listitem>
1768                      <para>a lisp process (thread).</para>
1769                </listitem>
1770              </varlistentry>
1771              <varlistentry>
1772                <term>whostate</term>
1773                <listitem>
1774                      <para>a string which describes the "state" of
1775                        <varname>process</varname>.</para>
1776                </listitem>
1777              </varlistentry>
1778            </variablelist>
1779          </refsynopsisdiv>
1780
1781          <refsect1>
1782            <title>Description</title>
1783
1784            <para>This information is primarily for the benefit of
1785              debugging tools.  <varname>whostate</varname> is a terse report
1786              on what <varname>process</varname> is doing, or not doing,
1787              and why.</para>
1788
1789            <para>If the process is currently waiting in a call to
1790              <xref linkend="f_process-wait"/> or
1791              <xref linkend="f_process-wait-with-timeout"/>, its
1792              <function>process-whostate</function> will be the value
1793              which was passed to that function as <varname>whostate</varname>.
1794            </para>
1795          </refsect1>
1796
1797          <refsect1>
1798            <title>See Also</title>
1799           
1800            <simplelist type="inline">
1801              <member><xref linkend="f_process-wait"/></member>
1802              <member><xref linkend="f_process-wait-with-timeout"/></member>
1803              <member><xref linkend="m_with-terminal-input"/></member>
1804            </simplelist>
1805          </refsect1>
1806
1807          <refsect1>
1808            <title>Notes</title>
1809
1810            <para>This should arguably be SETFable, but doesn't seem to
1811              ever have been.</para>
1812          </refsect1>
1813    </refentry>
1814
1815    <refentry id="f_process-allow-schedule">
1816          <indexterm zone="f_process-allow-schedule">
1817            <primary>process-allow-schedule</primary>
1818          </indexterm>
1819
1820          <refnamediv>
1821            <refname>PROCESS-ALLOW-SCHEDULE</refname>
1822            <refpurpose>Used for cooperative multitasking; probably never
1823              necessary.</refpurpose>
1824            <refclass>Function</refclass>
1825          </refnamediv>
1826
1827          <refsynopsisdiv>
1828            <synopsis><function>process-allow-schedule</function></synopsis>
1829          </refsynopsisdiv>
1830
1831          <refsect1>
1832            <title>Description</title>
1833
1834            <para>Advises the OS scheduler that the current thread has nothing
1835              useful to do and that it should try to find some other thread to
1836              schedule in its place. There's almost always a better
1837              alternative, such as waiting for some specific event to
1838              occur.  For example, you could use a lock or semaphore.</para>
1839          </refsect1>
1840
1841          <refsect1>
1842            <title>See Also</title>
1843           
1844            <simplelist type="inline">
1845              <member><xref linkend="f_make-lock"/></member>
1846              <member><xref linkend="f_make-read-write-lock"/></member>
1847              <member><xref linkend="f_make-semaphore"/></member>
1848              <member><xref linkend="f_process-input-wait"/></member>
1849              <member><xref linkend="f_process-output-wait"/></member>
1850              <member><xref linkend="m_with-terminal-input"/></member>
1851            </simplelist>
1852          </refsect1>
1853
1854          <refsect1>
1855            <title>Notes</title>
1856
1857            <para>This is a holdover from the days of cooperative
1858              multitasking.  All modern general-purpose operating systems use
1859              preemptive multitasking.</para>
1860          </refsect1>
1861    </refentry>
1862
1863    <refentry id="f_process-wait">
1864          <indexterm zone="f_process-wait">
1865            <primary>process-wait</primary>
1866          </indexterm>
1867
1868          <refnamediv>
1869            <refname>PROCESS-WAIT</refname>
1870            <refpurpose>Causes the current lisp process (thread) to wait for
1871              a given
1872              predicate to return true.</refpurpose>
1873            <refclass>Function</refclass>
1874          </refnamediv>
1875
1876          <refsynopsisdiv>
1877            <synopsis><function>process-wait</function>
1878              whostate function &rest; args => result</synopsis>
1879          </refsynopsisdiv>
1880
1881          <refsect1>
1882            <title>Arguments and Values</title>
1883
1884            <variablelist>
1885              <varlistentry>
1886                <term>whostate</term>
1887
1888                <listitem>
1889                      <para>a string, which will be the value of
1890                        <xref linkend="f_process-whostate"/>
1891                        while the process is waiting.</para>
1892                </listitem>
1893              </varlistentry>
1894              <varlistentry>
1895                <term>function</term>
1896                <listitem>
1897                      <para>a function, designated by itself or by a symbol
1898                        which names it.
1899                      </para>
1900                </listitem>
1901              </varlistentry>
1902              <varlistentry>
1903                <term>args</term>
1904                <listitem>
1905                      <para>a list of values, appropriate as arguments to
1906                        <varname>function</varname>.</para>
1907                </listitem>
1908              </varlistentry>
1909              <varlistentry>
1910                <term>result</term>
1911                <listitem>
1912                      <para>NIL.</para>
1913                </listitem>
1914              </varlistentry>
1915            </variablelist>
1916          </refsect1>
1917
1918          <refsect1>
1919            <title>Description</title>
1920
1921            <para>Causes the current lisp process (thread) to repeatedly
1922              apply <varname>function</varname> to
1923              <varname>args</varname> until the call returns a true result, then
1924              returns NIL. After
1925              each failed call, yields the CPU as if by
1926              <xref linkend="f_process-allow-schedule"/>.</para>
1927           
1928            <para>
1929              As with <xref linkend="f_process-allow-schedule"/>, it's almost
1930              always more efficient to wait for some
1931              specific event to occur; this isn't exactly busy-waiting, but
1932              the OS scheduler can do a better job of scheduling if it's given
1933              the relevant information.  For example, you could use a lock
1934              or semaphore.</para>
1935          </refsect1>
1936
1937          <refsect1>
1938            <title>See Also</title>
1939           
1940            <simplelist type="inline">
1941              <member><xref linkend="f_process-whostate"/></member>
1942              <member><xref linkend="f_process-wait-with-timeout"/></member>
1943              <member><xref linkend="f_make-lock"/></member>
1944              <member><xref linkend="f_make-read-write-lock"/></member>
1945              <member><xref linkend="f_make-semaphore"/></member>
1946              <member><xref linkend="f_process-input-wait"/></member>
1947              <member><xref linkend="f_process-output-wait"/></member>
1948              <member><xref linkend="m_with-terminal-input"/></member>
1949            </simplelist>
1950          </refsect1>
1951    </refentry>
1952
1953    <refentry id="f_process-wait-with-timeout">
1954          <indexterm zone="f_process-wait-with-timeout">
1955            <primary>process-wait-with-timeout</primary>
1956          </indexterm>
1957
1958          <refnamediv>
1959            <refname>PROCESS-WAIT-WITH-TIMEOUT</refname>
1960            <refpurpose>Causes the current thread to wait for a given
1961              predicate to return true, or for a timeout to expire.</refpurpose>
1962            <refclass>Function</refclass>
1963          </refnamediv>
1964
1965          <refsynopsisdiv>
1966            <synopsis><function>process-wait-with-timeout</function>
1967              whostate ticks function args => result</synopsis>
1968          </refsynopsisdiv>
1969
1970          <refsect1>
1971            <title>Arguments and Values</title>
1972
1973            <variablelist>
1974              <varlistentry>
1975                <term>whostate</term>
1976                <listitem>
1977                      <para>a string, which will be the value of
1978                        <xref linkend="f_process-whostate"/>
1979                        while the process is waiting.</para>
1980                </listitem>
1981              </varlistentry>
1982              <varlistentry>
1983                <term>ticks</term>
1984                <listitem>
1985                      <para>either a positive integer expressing a duration
1986                        in "ticks" (see <xref linkend="v_ticks-per-second"/>),
1987                        or NIL.</para>
1988                </listitem>
1989              </varlistentry>
1990              <varlistentry>
1991                <term>function</term>
1992                <listitem>
1993                      <para>a function, designated by itself or by a symbol
1994                        which names it.</para>
1995                </listitem>
1996              </varlistentry>
1997              <varlistentry>
1998                <term>args</term>
1999                <listitem>
2000                      <para>a list of values, appropriate as arguments to
2001                        <varname>function</varname>.</para>
2002                </listitem>
2003              </varlistentry>
2004              <varlistentry>
2005                <term>result</term>
2006                <listitem>
2007                      <para>T if <function>process-wait-with-timeout</function>
2008                        returned because its <varname>function</varname> returned
2009                        true, or NIL if it returned because the duration
2010                        <varname>ticks</varname> has been exceeded.</para>
2011                </listitem>
2012              </varlistentry>
2013            </variablelist>
2014          </refsect1>
2015
2016          <refsect1>
2017            <title>Description</title>
2018
2019            <para>If <varname>ticks</varname> is NIL, behaves exactly like
2020              <xref linkend="f_process-wait"/>, except for returning T.
2021              Otherwise, <varname>function</varname> will be tested repeatedly,
2022              in the same
2023              kind of test/yield loop as in <xref linkend="f_process-wait"/>
2024              until either <varname>function</varname> returns true,
2025              or the duration <varname>ticks</varname> has been exceeded.
2026            </para>
2027
2028            <para> Having already read the descriptions of
2029              <xref linkend="f_process-allow-schedule"/> and
2030              <xref linkend="f_process-wait"/>, the
2031              astute reader has no doubt anticipated the observation that
2032              better alternatives should be used whenever possible.</para>
2033          </refsect1>
2034
2035          <refsect1>
2036            <title>See Also</title>
2037           
2038            <simplelist type="inline">
2039              <member><xref linkend="v_ticks-per-second"/></member>
2040              <member><xref linkend="f_process-whostate"/></member>
2041              <member><xref linkend="f_process-wait"/></member>
2042              <member><xref linkend="f_make-lock"/></member>
2043              <member><xref linkend="f_make-read-write-lock"/></member>
2044              <member><xref linkend="f_make-semaphore"/></member>
2045              <member><xref linkend="f_process-input-wait"/></member>
2046              <member><xref linkend="f_process-output-wait"/></member>
2047              <member><xref linkend="m_with-terminal-input"/></member>
2048            </simplelist>
2049          </refsect1>
2050    </refentry>
2051
2052    <refentry id="m_without-interrupts">
2053          <indexterm zone="m_without-interrupts">
2054            <primary>without-interrupts</primary>
2055          </indexterm>
2056
2057          <refnamediv>
2058            <refname>WITHOUT-INTERRUPTS</refname>
2059            <refpurpose>Evaluates its body in an environment in which
2060              process-interrupt requests are deferred.</refpurpose>
2061            <refclass>Macro</refclass>
2062          </refnamediv>
2063
2064          <refsynopsisdiv>
2065            <synopsis><function>without-interrupts</function>
2066              &body; body => result</synopsis>
2067          </refsynopsisdiv>
2068
2069          <refsect1>
2070            <title>Arguments and Values</title>
2071
2072            <variablelist>
2073              <varlistentry>
2074                <term>body</term>
2075                <listitem>
2076                      <para>an implicit progn.</para>
2077                </listitem>
2078              </varlistentry>
2079              <varlistentry>
2080                <term>result</term>
2081                <listitem>
2082                      <para>the primary value returned by
2083                        <varname>body</varname>.</para>
2084                </listitem>
2085              </varlistentry>
2086            </variablelist>
2087          </refsect1>
2088
2089          <refsect1>
2090            <title>Description</title>
2091
2092            <para>Executes <varname>body</varname>
2093              in an environment in which <xref linkend="f_process-interrupt"/>
2094              requests are
2095              deferred. As noted in the description of
2096              <xref linkend="f_process-interrupt"/>, this has nothing to do
2097              with the
2098              scheduling of other threads; it may be necessary to inhibit
2099              <xref linkend="f_process-interrupt"/> handling when
2100              (for instance) modifying some data
2101              structure (for which the current thread holds an appropriate lock)
2102              in some manner that&#39;s not reentrant.</para>
2103          </refsect1>
2104
2105          <refsect1>
2106            <title>See Also</title>
2107           
2108            <simplelist type="inline">
2109              <member><xref linkend="f_process-interrupt"/></member>
2110            </simplelist>
2111          </refsect1>
2112    </refentry>
2113
2114    <refentry id="f_make-lock">
2115          <indexterm zone="f_make-lock">
2116            <primary>make-lock</primary>
2117          </indexterm>
2118
2119          <refnamediv>
2120            <refname>MAKE-LOCK</refname>
2121            <refpurpose>Creates and returns a lock object, which can
2122              be used for synchronization between threads.</refpurpose>
2123            <refclass>Function</refclass>
2124          </refnamediv>
2125
2126          <refsynopsisdiv>
2127            <synopsis><function>make-lock</function> &optional;
2128              name => lock</synopsis>
2129          </refsynopsisdiv>
2130
2131          <refsect1>
2132            <title>Arguments and Values</title>
2133
2134            <variablelist>
2135              <varlistentry>
2136                <term>name</term>
2137                <listitem>
2138                      <para>any lisp object; saved as part of
2139                        <varname>lock</varname>.  Typically a string or symbol
2140                        which may appear in the <xref linkend="f_process-whostate"/>s
2141                        of threads which are waiting for <varname>lock</varname>.
2142                      </para>
2143                </listitem>
2144              </varlistentry>
2145              <varlistentry>
2146                <term>lock</term>
2147                <listitem>
2148                      <para>a newly-allocated object of type CCL:LOCK.</para>
2149                </listitem>
2150              </varlistentry>
2151            </variablelist>
2152          </refsect1>
2153
2154          <refsect1>
2155            <title>Description</title>
2156
2157            <para>Creates and returns a lock object, which can
2158              be used to synchronize access to some shared resource.
2159              <varname>lock</varname> is
2160              initially in a &#34;free&#34; state; a lock can also be
2161              &#34;owned&#34; by a
2162              thread.</para>
2163          </refsect1>
2164
2165          <refsect1>
2166            <title>See Also</title>
2167           
2168            <simplelist type="inline">
2169              <member><xref linkend="m_with-lock-grabbed"/></member>
2170              <member><xref linkend="f_grab-lock"/></member>
2171              <member><xref linkend="f_release-lock"/></member>
2172              <member><xref linkend="f_try-lock"/></member>
2173              <member><xref linkend="f_make-read-write-lock"/></member>
2174              <member><xref linkend="f_make-semaphore"/></member>
2175              <member><xref linkend="f_process-input-wait"/></member>
2176              <member><xref linkend="f_process-output-wait"/></member>
2177              <member><xref linkend="m_with-terminal-input"/></member>
2178            </simplelist>
2179          </refsect1>
2180    </refentry>
2181
2182    <refentry id="m_with-lock-grabbed">
2183          <indexterm zone="m_with-lock-grabbed">
2184            <primary>with-lock-grabbed</primary>
2185          </indexterm>
2186
2187          <refnamediv>
2188            <refname>WITH-LOCK-GRABBED</refname>
2189            <refpurpose>Waits until a given lock can be obtained, then
2190              evaluates its body with the lock held.</refpurpose>
2191            <refclass>Macro</refclass>
2192          </refnamediv>
2193
2194          <refsynopsisdiv>
2195            <synopsis><function>with-lock-grabbed</function>
2196              (lock) &body; body</synopsis>
2197          </refsynopsisdiv>
2198
2199          <refsect1>
2200            <title>Arguments and Values</title>
2201
2202            <variablelist>
2203              <varlistentry>
2204                <term>lock</term>
2205                <listitem>
2206                      <para>an object of type CCL:LOCK.</para>
2207                </listitem>
2208              </varlistentry>
2209              <varlistentry>
2210                <term>body</term>
2211                <listitem>
2212                      <para>an implicit progn.</para>
2213                </listitem>
2214              </varlistentry>
2215              <varlistentry>
2216                <term>result</term>
2217                <listitem>
2218                      <para>the primary value returned by
2219                        <varname>body</varname>.</para>
2220                </listitem>
2221              </varlistentry>
2222            </variablelist>
2223          </refsect1>
2224
2225          <refsect1>
2226            <title>Description</title>
2227
2228            <para>Waits until <varname>lock</varname> is either free or
2229              owned by the calling
2230              thread, then executes <varname>body</varname> with the
2231              lock owned by the calling thread. If <varname>lock</varname>
2232              was free when <function>with-lock-grabbed</function> was called,
2233              it is restored to a free state after <varname>body</varname>
2234              is executed.</para>
2235          </refsect1>
2236
2237          <refsect1>
2238            <title>See Also</title>
2239           
2240            <simplelist type="inline">
2241              <member><xref linkend="f_make-lock"/></member>
2242              <member><xref linkend="f_grab-lock"/></member>
2243              <member><xref linkend="f_release-lock"/></member>
2244              <member><xref linkend="f_try-lock"/></member>
2245              <member><xref linkend="f_make-read-write-lock"/></member>
2246              <member><xref linkend="f_make-semaphore"/></member>
2247              <member><xref linkend="f_process-input-wait"/></member>
2248              <member><xref linkend="f_process-output-wait"/></member>
2249              <member><xref linkend="m_with-terminal-input"/></member>
2250            </simplelist>
2251          </refsect1>
2252    </refentry>
2253
2254    <refentry id="f_grab-lock">
2255          <indexterm zone="f_grab-lock">
2256            <primary>grab-lock</primary>
2257          </indexterm>
2258
2259          <refnamediv>
2260            <refname>GRAB-LOCK</refname>
2261            <refpurpose>Waits until a given lock can be obtained, then
2262              obtains it.</refpurpose>
2263            <refclass>Function</refclass>
2264          </refnamediv>
2265
2266          <refsynopsisdiv>
2267            <synopsis><function>grab-lock</function> lock</synopsis>
2268          </refsynopsisdiv>
2269
2270          <refsect1>
2271            <title>Arguments and Values</title>
2272
2273            <variablelist>
2274              <varlistentry>
2275                <term>lock</term>
2276                <listitem>
2277                      <para>an object of type CCL:LOCK.</para>
2278                </listitem>
2279              </varlistentry>
2280            </variablelist>
2281          </refsect1>
2282
2283          <refsect1>
2284            <title>Description</title>
2285
2286            <para>Blocks until <varname>lock</varname> is owned by the
2287              calling thread.</para>
2288
2289            <para>The macro <xref linkend="m_with-lock-grabbed"/>
2290              <emphasis>could</emphasis> be defined in
2291              terms of <function>grab-lock</function> and
2292              <xref linkend="f_release-lock"/>, but it is actually
2293              implemented at a slightly lower level.</para>
2294          </refsect1>
2295
2296          <refsect1>
2297            <title>See Also</title>
2298           
2299            <simplelist type="inline">
2300              <member><xref linkend="f_make-lock"/></member>
2301              <member><xref linkend="m_with-lock-grabbed"/></member>
2302              <member><xref linkend="f_release-lock"/></member>
2303              <member><xref linkend="f_try-lock"/></member>
2304              <member><xref linkend="f_make-read-write-lock"/></member>
2305              <member><xref linkend="f_make-semaphore"/></member>
2306              <member><xref linkend="f_process-input-wait"/></member>
2307              <member><xref linkend="f_process-output-wait"/></member>
2308              <member><xref linkend="m_with-terminal-input"/></member>
2309            </simplelist>
2310          </refsect1>
2311    </refentry>
2312
2313    <refentry id="f_release-lock">
2314          <indexterm zone="f_release-lock">
2315            <primary>release-lock</primary>
2316          </indexterm>
2317
2318          <refnamediv>
2319            <refname>RELEASE-LOCK</refname>
2320            <refpurpose>Relinquishes ownership of a given lock.</refpurpose>
2321            <refclass>Function</refclass>
2322          </refnamediv>
2323
2324          <refsynopsisdiv>
2325            <synopsis><function>release-lock</function> lock</synopsis>
2326          </refsynopsisdiv>
2327
2328          <refsect1>
2329            <title>Arguments and Values</title>
2330
2331            <variablelist>
2332              <varlistentry>
2333                <term>lock</term>
2334                <listitem>
2335                      <para>an object of type CCL:LOCK.</para>
2336                </listitem>
2337              </varlistentry>
2338            </variablelist>
2339          </refsect1>
2340
2341          <refsect1>
2342            <title>Description</title>
2343
2344            <para>Signals an error of type CCL:LOCK-NOT-OWNER if
2345              <varname>lock</varname>
2346              is not already owned by the calling thread; otherwise, undoes the
2347              effect of one previous
2348              <xref linkend="f_grab-lock"/>.  If this means that
2349              <function>release-lock</function> has now been called on
2350              <varname>lock</varname> the same number of times as
2351              <xref linkend="f_grab-lock"/> has, <varname>lock</varname>
2352              becomes free.</para>
2353          </refsect1>
2354
2355          <refsect1>
2356            <title>See Also</title>
2357           
2358            <simplelist type="inline">
2359              <member><xref linkend="f_make-lock"/></member>
2360              <member><xref linkend="m_with-lock-grabbed"/></member>
2361              <member><xref linkend="f_grab-lock"/></member>
2362              <member><xref linkend="f_try-lock"/></member>
2363              <member><xref linkend="f_make-read-write-lock"/></member>
2364              <member><xref linkend="f_make-semaphore"/></member>
2365              <member><xref linkend="f_process-input-wait"/></member>
2366              <member><xref linkend="f_process-output-wait"/></member>
2367              <member><xref linkend="m_with-terminal-input"/></member>
2368            </simplelist>
2369          </refsect1>
2370    </refentry>
2371
2372    <refentry id="f_try-lock">
2373          <indexterm zone="f_try-lock">
2374            <primary>try-lock</primary>
2375          </indexterm>
2376
2377          <refnamediv>
2378            <refname>TRY-LOCK</refname>
2379            <refpurpose>Obtains the given lock, but only if it is not
2380              necessary to wait for it.</refpurpose>
2381            <refclass>Function</refclass>
2382          </refnamediv>
2383
2384          <refsynopsisdiv>
2385            <synopsis><function>try-lock</function> lock => result</synopsis>
2386          </refsynopsisdiv>
2387
2388          <refsect1>
2389            <title>Arguments and Values</title>
2390
2391            <variablelist>
2392              <varlistentry>
2393                <term>lock</term>
2394                <listitem>
2395                      <para>an object of type CCL:LOCK.</para>
2396                </listitem>
2397              </varlistentry>
2398              <varlistentry>
2399                <term>result</term>
2400                <listitem>
2401                      <para>T if <varname>lock</varname> has been obtained,
2402                        or NIL if it has not.</para>
2403                </listitem>
2404              </varlistentry>
2405            </variablelist>
2406          </refsect1>
2407
2408          <refsect1>
2409            <title>Description</title>
2410
2411            <para>Tests whether <varname>lock</varname>
2412              can be obtained without blocking - that is, either
2413              <varname>lock</varname> is already free, or it is already owned
2414              by <xref linkend="v_current-process"/>.  If it can,
2415              causes it to
2416              be owned by the calling lisp process (thread) and returns T.
2417              Otherwise, the lock
2418              is already owned by another thread and cannot be obtained without
2419              blocking; NIL is returned in this case.</para>
2420          </refsect1>
2421
2422          <refsect1>
2423            <title>See Also</title>
2424           
2425            <simplelist type="inline">
2426              <member><xref linkend="f_make-lock"/></member>
2427              <member><xref linkend="m_with-lock-grabbed"/></member>
2428              <member><xref linkend="f_grab-lock"/></member>
2429              <member><xref linkend="f_release-lock"/></member>
2430              <member><xref linkend="f_make-read-write-lock"/></member>
2431              <member><xref linkend="f_make-semaphore"/></member>
2432              <member><xref linkend="f_process-input-wait"/></member>
2433              <member><xref linkend="f_process-output-wait"/></member>
2434              <member><xref linkend="m_with-terminal-input"/></member>
2435            </simplelist>
2436          </refsect1>
2437    </refentry>
2438
2439    <refentry id="f_make-read-write-lock">
2440          <indexterm zone="f_make-read-write-lock">
2441            <primary>make-read-write-lock</primary>
2442          </indexterm>
2443
2444          <refnamediv>
2445            <refname>MAKE-READ-WRITE-LOCK</refname>
2446            <refpurpose>Creates and returns a read-write lock, which can
2447              be used for synchronization between threads.</refpurpose>
2448            <refclass>Function</refclass>
2449          </refnamediv>
2450
2451          <refsynopsisdiv>
2452            <synopsis><function>make-read-write-lock</function>
2453              => read-write-lock</synopsis>
2454          </refsynopsisdiv>
2455
2456          <refsect1>
2457            <title>Arguments and Values</title>
2458
2459            <variablelist>
2460              <varlistentry>
2461                <term>read-write-lock</term>
2462                <listitem>
2463                      <para>a newly-allocated object of type
2464                        CCL:READ-WRITE-LOCK.</para>
2465                </listitem>
2466              </varlistentry>
2467            </variablelist>
2468          </refsect1>
2469
2470          <refsect1>
2471            <title>Description</title>
2472
2473            <para>Creates and returns an object of type CCL::READ-WRITE-LOCK.
2474              A read-write lock may, at any given time, belong to any number
2475              of lisp processes (threads) which act as "readers"; or, it may
2476              belong to at most one process which acts as a "writer".  A
2477              read-write lock may never be held by a reader at the same time as
2478              a writer.  Initially, <varname>read-write-lock</varname> has
2479              no readers and no writers.</para>
2480          </refsect1>
2481
2482          <refsect1>
2483            <title>See Also</title>
2484           
2485            <simplelist type="inline">
2486              <member><xref linkend="m_with-read-lock"/></member>
2487              <member><xref linkend="m_with-write-lock"/></member>
2488              <member><xref linkend="f_make-lock"/></member>
2489              <member><xref linkend="f_make-semaphore"/></member>
2490              <member><xref linkend="f_process-input-wait"/></member>
2491              <member><xref linkend="f_process-output-wait"/></member>
2492              <member><xref linkend="m_with-terminal-input"/></member>
2493            </simplelist>
2494          </refsect1>
2495
2496          <refsect1>
2497            <title>Notes</title>
2498
2499            <para>There probably should be some way to
2500              atomically &#34;promote&#34; a reader, making it a writer without
2501              releasing the lock, which could otherwise cause delay.</para>
2502          </refsect1>
2503    </refentry>
2504
2505    <refentry id="m_with-read-lock">
2506          <indexterm zone="m_with-read-lock">
2507            <primary>with-read-lock</primary>
2508          </indexterm>
2509
2510          <refnamediv>
2511            <refname>WITH-READ-LOCK</refname>
2512            <refpurpose>Waits until a given lock is available for
2513              read-only access, then evaluates its body with the lock
2514              held.</refpurpose>
2515            <refclass>Macro</refclass>
2516          </refnamediv>
2517
2518          <refsynopsisdiv>
2519            <synopsis><function>with-read-lock</function>
2520              (read-write-lock) &body; body => result</synopsis>
2521          </refsynopsisdiv>
2522
2523          <refsect1>
2524            <title>Arguments and Values</title>
2525
2526            <variablelist>
2527              <varlistentry>
2528                <term>read-write-lock</term>
2529                <listitem>
2530                      <para>an object of type
2531                        CCL:READ-WRITE-LOCK.</para>
2532                </listitem>
2533              </varlistentry>
2534              <varlistentry>
2535                <term>body</term>
2536                <listitem>
2537                      <para>an implicit progn.</para>
2538                </listitem>
2539              </varlistentry>
2540              <varlistentry>
2541                <term>result</term>
2542                <listitem>
2543                      <para>the primary value returned by
2544                        <varname>body</varname>.</para>
2545                </listitem>
2546              </varlistentry>
2547            </variablelist>
2548          </refsect1>
2549
2550          <refsect1>
2551            <title>Description</title>
2552
2553            <para>Waits until <varname>read-write-lock</varname> has no
2554              writer,
2555              ensures that <xref linkend="v_current-process"/> is a
2556              reader of it, then executes <varname>body</varname>.
2557            </para>
2558
2559            <para>After executing <varname>body</varname>, if
2560              <xref linkend="v_current-process"/> was not a reader of
2561              <varname>read-write-lock</varname> before
2562              <function>with-read-lock</function> was called, the lock is
2563              released.  If it was already a reader, it remains one.</para>
2564          </refsect1>
2565
2566          <refsect1>
2567            <title>See Also</title>
2568           
2569            <simplelist type="inline">
2570              <member><xref linkend="f_make-read-write-lock"/></member>
2571              <member><xref linkend="m_with-write-lock"/></member>
2572              <member><xref linkend="f_make-lock"/></member>
2573              <member><xref linkend="f_make-semaphore"/></member>
2574              <member><xref linkend="f_process-input-wait"/></member>
2575              <member><xref linkend="f_process-output-wait"/></member>
2576              <member><xref linkend="m_with-terminal-input"/></member>
2577            </simplelist>
2578          </refsect1>
2579    </refentry>
2580
2581    <refentry id="m_with-write-lock">
2582          <indexterm zone="m_with-write-lock">
2583            <primary>with-write-lock</primary>
2584          </indexterm>
2585
2586          <refnamediv>
2587            <refname>WITH-WRITE-LOCK</refname>
2588            <refpurpose>Waits until the given lock is available for write
2589              access, then executes its body with the lock held.</refpurpose>
2590            <refclass>Macro</refclass>
2591          </refnamediv>
2592
2593          <refsynopsisdiv>
2594            <synopsis><function>with-write-lock</function>
2595              (read-write-lock) &body; body</synopsis>
2596          </refsynopsisdiv>
2597
2598          <refsect1>
2599            <title>Arguments and Values</title>
2600
2601            <variablelist>
2602              <varlistentry>
2603                <term>read-write-lock</term>
2604                <listitem>
2605                      <para>an object of type
2606                        CCL:READ-WRITE-LOCK.</para>
2607                </listitem>
2608              </varlistentry>
2609              <varlistentry>
2610                <term>body</term>
2611                <listitem>
2612                      <para>an implicit progn.</para>
2613                </listitem>
2614              </varlistentry>
2615              <varlistentry>
2616                <term>result</term>
2617                <listitem>
2618                      <para>the primary value returned by
2619                        <varname>body</varname>.</para>
2620                </listitem>
2621              </varlistentry>
2622            </variablelist>
2623          </refsect1>
2624
2625          <refsect1>
2626            <title>Description</title>
2627
2628            <para>Waits until <varname>read-write-lock</varname> has no
2629              readers and no writer other than <xref linkend="v_current-process"/>,
2630              then ensures that <xref linkend="v_current-process"/> is the
2631              writer of it.  With the lock held, executes <varname>body</varname>.
2632            </para>
2633
2634            <para>After executing <varname>body</varname>, if
2635              <xref linkend="v_current-process"/> was not the writer of
2636              <varname>read-write-lock</varname> before
2637              <function>with-write-lock</function> was called, the lock is
2638              released.  If it was already the writer, it remains the
2639              writer.</para>
2640          </refsect1>
2641
2642          <refsect1>
2643            <title>See Also</title>
2644           
2645            <simplelist type="inline">
2646              <member><xref linkend="f_make-read-write-lock"/></member>
2647              <member><xref linkend="m_with-read-lock"/></member>
2648              <member><xref linkend="f_make-lock"/></member>
2649              <member><xref linkend="f_make-semaphore"/></member>
2650              <member><xref linkend="f_process-input-wait"/></member>
2651              <member><xref linkend="f_process-output-wait"/></member>
2652              <member><xref linkend="m_with-terminal-input"/></member>
2653            </simplelist>
2654          </refsect1>
2655    </refentry>
2656
2657    <refentry id="f_make-semaphore">
2658          <indexterm zone="f_make-semaphore">
2659            <primary>make-semaphore</primary>
2660          </indexterm>
2661
2662          <refnamediv>
2663            <refname>MAKE-SEMAPHORE</refname>
2664            <refpurpose>Creates and returns a semaphore, which can be used
2665              for synchronization between threads.</refpurpose>
2666            <refclass>Function</refclass>
2667          </refnamediv>
2668
2669          <refsynopsisdiv>
2670            <synopsis><function>make-semaphore</function>
2671              => semaphore</synopsis>
2672          </refsynopsisdiv>
2673
2674          <refsect1>
2675            <title>Arguments and Values</title>
2676           
2677            <variablelist>
2678              <varlistentry>
2679                <term>semaphore</term>
2680                <listitem>
2681                      <para>a newly-allocated object of type CCL:SEMAPHORE.</para>
2682                </listitem>
2683              </varlistentry>
2684            </variablelist>
2685          </refsect1>
2686
2687          <refsect1>
2688            <title>Description</title>
2689
2690            <para>Creates and returns an object of type CCL:SEMAPHORE.
2691              A semaphore has an associated "count" which may be incremented
2692              and decremented atomically; incrementing it represents sending
2693              a signal, and decrementing it represents handling that signal.
2694              <varname>semaphore</varname> has an initial count of 0.</para>
2695          </refsect1>
2696
2697          <refsect1>
2698            <title>See Also</title>
2699           
2700            <simplelist type="inline">
2701              <member><xref linkend="f_signal-semaphore"/></member>
2702              <member><xref linkend="f_wait-on-semaphore"/></member>
2703              <member><xref linkend="f_timed-wait-on-semaphore"/></member>
2704              <member><xref linkend="f_make-lock"/></member>
2705              <member><xref linkend="f_make-read-write-lock"/></member>
2706              <member><xref linkend="f_process-input-wait"/></member>
2707              <member><xref linkend="f_process-output-wait"/></member>
2708              <member><xref linkend="m_with-terminal-input"/></member>
2709            </simplelist>
2710          </refsect1>
2711    </refentry>
2712
2713    <refentry id="f_signal-semaphore">
2714          <indexterm zone="f_signal-semaphore">
2715            <primary>signal-semaphore</primary>
2716          </indexterm>
2717
2718          <refnamediv>
2719            <refname>SIGNAL-SEMAPHORE</refname>
2720            <refpurpose>Atomically increments the count of a given
2721              semaphore.</refpurpose>
2722            <refclass>Function</refclass>
2723          </refnamediv>
2724
2725          <refsynopsisdiv>
2726            <synopsis><function>signal-semaphore</function>
2727              semaphore => result</synopsis>
2728          </refsynopsisdiv>
2729
2730          <refsect1>
2731            <title>Arguments and Values</title>
2732           
2733            <variablelist>
2734              <varlistentry>
2735                <term>semaphore</term>
2736                <listitem>
2737                      <para>an object of type CCL:SEMAPHORE.</para>
2738                </listitem>
2739              </varlistentry>
2740              <varlistentry>
2741                <term>result</term>
2742                <listitem>
2743                      <para>an integer representing an error identifier
2744                        which was returned by the underlying OS call.</para>
2745                </listitem>
2746              </varlistentry>
2747            </variablelist>
2748          </refsect1>
2749
2750          <refsect1>
2751            <title>Description</title>
2752
2753            <para>Atomically increments <varname>semaphore</varname>'s
2754              "count" by 1; this
2755              may enable a waiting thread to resume execution.</para>
2756          </refsect1>
2757
2758          <refsect1>
2759            <title>See Also</title>
2760           
2761            <simplelist type="inline">
2762              <member><xref linkend="f_make-semaphore"/></member>
2763              <member><xref linkend="f_wait-on-semaphore"/></member>
2764              <member><xref linkend="f_timed-wait-on-semaphore"/></member>
2765              <member><xref linkend="f_make-lock"/></member>
2766              <member><xref linkend="f_make-read-write-lock"/></member>
2767              <member><xref linkend="f_process-input-wait"/></member>
2768              <member><xref linkend="f_process-output-wait"/></member>
2769              <member><xref linkend="m_with-terminal-input"/></member>
2770            </simplelist>
2771          </refsect1>
2772
2773          <refsect1>
2774            <title>Notes</title>
2775
2776            <para><varname>result</varname> should probably be interpreted
2777              and acted on by <function>signal-semaphore</function>, because
2778              it is not likely to be meaningful to a lisp program, and the
2779              most common cause of failure is a type error.</para>
2780          </refsect1>
2781    </refentry>
2782
2783    <refentry id="f_wait-on-semaphore">
2784          <indexterm zone="f_wait-on-semaphore">
2785            <primary>wait-on-semaphore</primary>
2786          </indexterm>
2787
2788          <refnamediv>
2789            <refname>WAIT-ON-SEMAPHORE</refname>
2790            <refpurpose>Waits until the given semaphore has a positive
2791              count which can be atomically decremented.</refpurpose>
2792            <refclass>Function</refclass>
2793          </refnamediv>
2794
2795          <refsynopsisdiv>
2796            <synopsis><function>wait-on-semaphore</function>
2797              semaphore => result</synopsis>
2798          </refsynopsisdiv>
2799
2800          <refsect1>
2801            <title>Arguments and Values</title>
2802           
2803            <variablelist>
2804              <varlistentry>
2805                <term>semaphore</term>
2806                <listitem>
2807                      <para>an object of type CCL:SEMAPHORE.</para>
2808                </listitem>
2809              </varlistentry>
2810              <varlistentry>
2811                <term>result</term>
2812                <listitem>
2813                      <para>an integer representing an error identifier
2814                        which was returned by the underlying OS call.</para>
2815                </listitem>
2816              </varlistentry>
2817            </variablelist>
2818          </refsect1>
2819
2820          <refsect1>
2821            <title>Description</title>
2822
2823            <para>Waits until <varname>semaphore</varname>
2824              has a positive count that can be
2825              atomically decremented; this will succeed exactly once for each
2826              corresponding call to SIGNAL-SEMAPHORE.</para>
2827          </refsect1>
2828
2829          <refsect1>
2830            <title>See Also</title>
2831           
2832            <simplelist type="inline">
2833              <member><xref linkend="f_make-semaphore"/></member>
2834              <member><xref linkend="f_signal-semaphore"/></member>
2835              <member><xref linkend="f_timed-wait-on-semaphore"/></member>
2836              <member><xref linkend="f_make-lock"/></member>
2837              <member><xref linkend="f_make-read-write-lock"/></member>
2838              <member><xref linkend="f_process-input-wait"/></member>
2839              <member><xref linkend="f_process-output-wait"/></member>
2840              <member><xref linkend="m_with-terminal-input"/></member>
2841            </simplelist>
2842          </refsect1>
2843
2844          <refsect1>
2845            <title>Notes</title>
2846
2847            <para><varname>result</varname> should probably be interpreted
2848              and acted on by <function>wait-on-semaphore</function>, because
2849              it is not likely to be meaningful to a lisp program, and the
2850              most common cause of failure is a type error.</para>
2851          </refsect1>
2852    </refentry>
2853
2854    <refentry id="f_timed-wait-on-semaphore">
2855          <indexterm zone="f_timed-wait-on-semaphore">
2856            <primary>timed-wait-on-semaphore</primary>
2857          </indexterm>
2858
2859          <refnamediv>
2860            <refname>TIMED-WAIT-ON-SEMAPHORE</refname>
2861            <refpurpose>Waits until the given semaphore has a positive
2862              count which can be atomically decremented, or until a timeout
2863              expires.</refpurpose>
2864            <refclass>Function</refclass>
2865          </refnamediv>
2866
2867          <refsynopsisdiv>
2868            <synopsis><function>timed-wait-on-semaphore</function>
2869              semaphore timeout => result</synopsis>
2870          </refsynopsisdiv>
2871
2872          <refsect1>
2873            <title>Arguments and Values</title>
2874           
2875            <variablelist>
2876              <varlistentry>
2877                <term>semaphore</term>
2878                <listitem>
2879                      <para>An object of type CCL:SEMAPHORE.</para>
2880                </listitem>
2881              </varlistentry>
2882              <varlistentry>
2883                <term>timeout</term>
2884                <listitem>
2885                      <para>a time interval in seconds.  May be any
2886                        non-negative real number the <function>floor</function> of
2887                        which fits in 32 bits.  The default is 1.</para>
2888                </listitem>
2889              </varlistentry>
2890              <varlistentry>
2891                <term>result</term>
2892                <listitem>
2893                      <para>T if <function>timed-wait-on-semaphore</function>
2894                        returned because it was able to decrement the count of
2895                        <varname>semaphore</varname>; NIL if it returned because
2896                        the duration <varname>timeout</varname> has been
2897                        exceeded.</para>
2898                </listitem>
2899              </varlistentry>
2900            </variablelist>
2901          </refsect1>
2902
2903          <refsect1>
2904            <title>Description</title>
2905
2906            <para>Waits until <varname>semaphore</varname>
2907              has a positive count that can be
2908              atomically decremented, or until the duration
2909              <varname>timeout</varname> has
2910              elapsed.</para>
2911          </refsect1>
2912
2913          <refsect1>
2914            <title>See Also</title>
2915           
2916            <simplelist type="inline">
2917              <member><xref linkend="f_make-semaphore"/></member>
2918              <member><xref linkend="f_wait-on-semaphore"/></member>
2919              <member><xref linkend="f_make-lock"/></member>
2920              <member><xref linkend="f_make-read-write-lock"/></member>
2921              <member><xref linkend="f_process-input-wait"/></member>
2922              <member><xref linkend="f_process-output-wait"/></member>
2923              <member><xref linkend="m_with-terminal-input"/></member>
2924            </simplelist>
2925          </refsect1>
2926    </refentry>
2927
2928    <refentry id="f_process-input-wait">
2929          <indexterm zone="f_process-input-wait">
2930            <primary>process-input-wait</primary>
2931          </indexterm>
2932
2933          <refnamediv>
2934            <refname>PROCESS-INPUT-WAIT</refname>
2935            <refpurpose>Waits until input is available on a given
2936              file-descriptor.</refpurpose>
2937            <refclass>Function</refclass>
2938          </refnamediv>
2939
2940          <refsynopsisdiv>
2941            <synopsis><function>process-input-wait</function>
2942              fd &optional; timeout</synopsis>
2943          </refsynopsisdiv>
2944
2945          <refsect1>
2946            <title>Arguments and Values</title>
2947           
2948            <variablelist>
2949              <varlistentry>
2950                <term>fd</term>
2951                <listitem>
2952                      <para>a file descriptor, which is a non-negative integer
2953                        used by the OS to refer to an open file, socket, or similar
2954                        I/O connection.  See <xref linkend="f_stream-device"/>.</para>
2955                </listitem>
2956              </varlistentry>
2957              <varlistentry>
2958                <term>timeout</term>
2959                <listitem>
2960                      <para>either NIL or a time interval in milliseconds.  Must be a non-negative integer.  The default is NIL.</para>
2961                </listitem>
2962              </varlistentry>
2963            </variablelist>
2964          </refsect1>
2965
2966          <refsect1>
2967            <title>Description</title>
2968
2969            <para>Wait until input is available on <varname>fd</varname>.
2970              This uses the <function>select()</function> system call, and is
2971              generally a fairly
2972              efficient way of blocking while waiting for input. More
2973              accurately, <function>process-input-wait</function>
2974              waits until it&#39;s possible to read
2975              from fd without blocking, or until <varname>timeout</varname>, if
2976              it is not NIL, has been exceeded.</para>
2977
2978            <para>
2979              Note that it&#39;s possible to read without blocking if
2980              the file is at its end - although, of course, the read will
2981              return zero bytes.</para>
2982          </refsect1>
2983         
2984          <refsect1>
2985            <title>See Also</title>
2986           
2987            <simplelist type="inline">
2988              <member><xref linkend="f_make-lock"/></member>
2989              <member><xref linkend="f_make-read-write-lock"/></member>
2990              <member><xref linkend="f_make-semaphore"/></member>
2991              <member><xref linkend="f_process-output-wait"/></member>
2992              <member><xref linkend="m_with-terminal-input"/></member>
2993            </simplelist>
2994          </refsect1>
2995
2996          <refsect1>
2997            <title>Notes</title>
2998
2999            <para>
3000              <function>process-input-wait</function> has a timeout parameter,
3001              and
3002              <xref linkend="f_process-output-wait"/> does not.  This
3003              inconsistency should probably be corrected.
3004            </para>
3005          </refsect1>
3006    </refentry>
3007
3008    <refentry id="f_process-output-wait">
3009          <indexterm zone="f_process-output-wait">
3010            <primary>process-output-wait</primary>
3011          </indexterm>
3012
3013          <refnamediv>
3014            <refname>PROCESS-OUTPUT-WAIT</refname>
3015            <refpurpose>Waits until output is possible on a given file
3016              descriptor.</refpurpose>
3017            <refclass>Function</refclass>
3018          </refnamediv>
3019
3020          <refsynopsisdiv>
3021            <synopsis><function>process-output-wait</function>
3022              fd  &optional; timeout</synopsis>
3023          </refsynopsisdiv>
3024
3025          <refsect1>
3026            <title>Arguments and Values</title>
3027           
3028            <variablelist>
3029              <varlistentry>
3030                <term>fd</term>
3031                <listitem>
3032                      <para>a file descriptor, which is a non-negative integer
3033                        used by the OS to refer to an open file, socket, or similar
3034                        I/O connection.  See <xref linkend="f_stream-device"/>.</para>
3035                </listitem>
3036              </varlistentry>
3037              <varlistentry>
3038                <term>timeout</term>
3039                <listitem>
3040                      <para>either NIL or a time interval in milliseconds.  Must be a non-negative integer.  The default is NIL.</para>
3041                </listitem>
3042              </varlistentry>
3043            </variablelist>
3044          </refsect1>
3045
3046          <refsect1>
3047            <title>Description</title>
3048
3049            <para>Wait until output is possible on <varname>fd</varname> or until <varname>timeout</varname>, if
3050              it is not NIL, has been exceeded.
3051              This uses the <function>select()</function> system call, and is
3052              generally a fairly
3053              efficient way of blocking while waiting to output.</para>
3054
3055            <para>If <function>process-output-wait</function> is called on
3056              a network socket which has not yet established a connection, it
3057              will wait until the connection is established.  This is an
3058              important use, often overlooked.</para>
3059          </refsect1>
3060
3061          <refsect1>
3062            <title>See Also</title>
3063           
3064            <simplelist type="inline">
3065              <member><xref linkend="f_make-lock"/></member>
3066              <member><xref linkend="f_make-read-write-lock"/></member>
3067              <member><xref linkend="f_make-semaphore"/></member>
3068              <member><xref linkend="f_process-input-wait"/></member>
3069              <member><xref linkend="m_with-terminal-input"/></member>
3070            </simplelist>
3071          </refsect1>
3072
3073          <refsect1>
3074            <title>Notes</title>
3075
3076            <para>
3077              <xref linkend="f_process-input-wait"/> has a timeout parameter,
3078              and
3079              <function>process-output-wait</function> does not.  This
3080              inconsistency should probably be corrected.
3081            </para>
3082          </refsect1>
3083    </refentry>
3084
3085    <refentry id="m_with-terminal-input">
3086          <indexterm zone="m_with-terminal-input">
3087            <primary>with-terminal-input</primary>
3088          </indexterm>
3089
3090          <refnamediv>
3091            <refname>WITH-TERMINAL-INPUT</refname>
3092            <refpurpose>Executes its body in an environment with exclusive
3093              read access to the terminal.</refpurpose>
3094            <refclass>Macro</refclass>
3095          </refnamediv>
3096
3097          <refsynopsisdiv>
3098            <synopsis><function>with-terminal-input</function>
3099              &body; body => result</synopsis>
3100          </refsynopsisdiv>
3101
3102          <refsect1>
3103            <title>Arguments and Values</title>
3104           
3105            <variablelist>
3106              <varlistentry>
3107                <term>body</term>
3108                <listitem>
3109                      <para>an implicit progn.</para>
3110                </listitem>
3111              </varlistentry>
3112              <varlistentry>
3113                <term>result</term>
3114                <listitem>
3115                      <para>the primary value returned by
3116                        <varname>body</varname>.</para>
3117                </listitem>
3118              </varlistentry>
3119            </variablelist>
3120          </refsect1>
3121
3122          <refsect1>
3123            <title>Description</title>
3124
3125            <para>Requests exclusive read access to the standard terminal
3126              stream, <varname>*terminal-io*</varname>.  Executes
3127              <varname>body</varname> in an environment with that access.
3128            </para>
3129          </refsect1>
3130
3131          <refsect1>
3132            <title>See Also</title>
3133           
3134            <simplelist type="inline">
3135              <member><xref
3136                         linkend="v_request-terminal-input-via-break"/></member>
3137              <member><xref linkend="cmd_y"/></member>
3138              <member><xref linkend="f_make-lock"/></member>
3139              <member><xref linkend="f_make-read-write-lock"/></member>
3140              <member><xref linkend="f_make-semaphore"/></member>
3141              <member><xref linkend="f_process-input-wait"/></member>
3142              <member><xref linkend="f_process-output-wait"/></member>
3143            </simplelist>
3144          </refsect1>
3145    </refentry>
3146
3147    <refentry id="v_request-terminal-input-via-break">
3148          <indexterm zone="v_request-terminal-input-via-break">
3149            <primary>request-terminal-input-via-break</primary>
3150          </indexterm>
3151
3152          <refnamediv>
3153            <refname>*REQUEST-TERMINAL-INPUT-VIA-BREAK*</refname>
3154            <refpurpose>Controls how attempts to obtain ownership of
3155              terminal input are made.</refpurpose>
3156            <refclass>Variable</refclass>
3157          </refnamediv>
3158
3159          <refsect1>
3160            <title>Value Type</title>
3161
3162            <para>A boolean.</para>
3163          </refsect1>
3164
3165          <refsect1>
3166            <title>Initial Value</title>
3167           
3168            <para>NIL.</para>
3169          </refsect1>
3170
3171          <refsect1>
3172            <title>Description</title>
3173
3174            <para>Controls how attempts to obtain ownership of terminal input
3175              are made. When NIL, a message is printed on *TERMINAL-IO*;
3176              it's expected that the user will later yield
3177              control of the terminal via the :Y toplevel command. When T, a
3178              BREAK condition is signaled in the owning process; continuing from
3179              the break loop will yield the terminal to the requesting process
3180              (unless the :Y command was already used to do so in the break
3181              loop.)</para>
3182          </refsect1>
3183
3184          <refsect1>
3185            <title>See Also</title>
3186           
3187            <simplelist type="inline">
3188              <member><xref linkend="m_with-terminal-input"/></member>
3189              <member><xref linkend="cmd_y"/></member>
3190              <member><xref linkend="f_make-lock"/></member>
3191              <member><xref linkend="f_make-read-write-lock"/></member>
3192              <member><xref linkend="f_make-semaphore"/></member>
3193              <member><xref linkend="f_process-input-wait"/></member>
3194              <member><xref linkend="f_process-output-wait"/></member>
3195            </simplelist>
3196          </refsect1>
3197    </refentry>
3198
3199    <refentry id="cmd_y">
3200          <indexterm zone="cmd_y">
3201            <primary>:y</primary>
3202          </indexterm>
3203
3204          <refnamediv>
3205            <refname>:Y</refname>
3206            <refpurpose>Yields control of terminal input to a specified
3207              lisp process (thread).</refpurpose>
3208            <refclass>Toplevel Command</refclass>
3209          </refnamediv>
3210
3211          <refsynopsisdiv>
3212            <synopsis>(<function>:y</function> p)</synopsis>
3213          </refsynopsisdiv>
3214
3215          <refsect1>
3216            <title>Arguments and Values</title>
3217
3218            <variablelist>
3219              <varlistentry>
3220                <term>p</term>
3221                <listitem>
3222                      <para>a lisp process (thread), designated either by
3223                        an integer which matches its
3224                        <function>process-serial-number</function>,
3225                        or by a string which is <function>equal</function> to
3226                        its <function>process-name</function>.</para>
3227                </listitem>
3228              </varlistentry>
3229            </variablelist>
3230          </refsect1>
3231
3232          <refsect1>
3233            <title>Description</title>
3234
3235            <para>:Y is a toplevel command, not a function.  As such, it
3236              can only be used interactively, and only from the initial
3237              process.</para>
3238
3239            <para>The command yields control of terminal input to the
3240              process <varname>p</varname>, which must have used
3241              <xref linkend="m_with-terminal-input"/> to request access to the
3242              terminal input stream.</para>
3243          </refsect1>
3244
3245          <refsect1>
3246            <title>See Also</title>
3247           
3248            <simplelist type="inline">
3249              <member><xref linkend="m_with-terminal-input"/></member>
3250              <member><xref
3251                         linkend="v_request-terminal-input-via-break"/></member>
3252              <member><xref linkend="f_make-lock"/></member>
3253              <member><xref linkend="f_make-read-write-lock"/></member>
3254              <member><xref linkend="f_make-semaphore"/></member>
3255              <member><xref linkend="f_process-input-wait"/></member>
3256              <member><xref linkend="f_process-output-wait"/></member>
3257            </simplelist>
3258          </refsect1>
3259    </refentry>
3260
3261    <refentry id="f_join-process">
3262      <indexterm zone="f_join-process">
3263        <primary>join-process</primary>
3264      </indexterm>
3265
3266      <refnamediv>
3267        <refname>JOIN-PROCESS</refname>
3268        <refpurpose>Waits for a specified process to complete and
3269        returns the values that that process's initial function
3270        returned.</refpurpose>
3271        <refclass>Function</refclass>
3272      </refnamediv>
3273
3274      <refsynopsisdiv>
3275        <synopsis><function>join-process</function> process
3276        &optional; default => values</synopsis>
3277      </refsynopsisdiv>
3278     
3279      <refsect1>
3280        <title>Arguments and Values</title>
3281
3282        <variablelist>
3283          <varlistentry>
3284            <term>process</term>
3285            <listitem>
3286              <para>a process, typically created by <xref
3287              linkend="f_process-run-function"/> or by <xref
3288              linkend="f_make-process"/></para>
3289            </listitem>
3290          </varlistentry>
3291          <varlistentry>
3292            <term>default</term>
3293            <listitem>
3294              <para>A default value to be returned if the specified
3295              process doesn't exit normally.</para>
3296            </listitem>
3297          </varlistentry>
3298          <varlistentry>
3299            <term>values</term>
3300            <listitem>
3301              <para>The values returned by the specified process's
3302              initial function if that function returns, or the value
3303              of the default argument, otherwise.</para>
3304            </listitem>
3305          </varlistentry>
3306        </variablelist>
3307      </refsect1>
3308
3309      <refsect1>
3310        <title>Description</title>
3311        <para>Waits for the specified process to terminate.  If the
3312        process terminates "normally" (if its initial function
3313        returns), returns the values that that initial function
3314        returnes.  If the process does not terminate normally (e.g.,
3315        if it's terminated via <xref linkend="f_process-kill"/> and a
3316        default argument is provided, returns the value of that
3317        default argument.  If the process doesn't terminate normally
3318        and no default argument is provided, signals an error.</para>
3319       
3320        <para>A process can't successfully join itself, and only one
3321        process can successfully receive notification of another process's
3322        termination.</para>
3323      </refsect1>
3324    </refentry>
3325
3326  </sect1>
3327</chapter>
Note: See TracBrowser for help on using the repository browser.