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

Last change on this file since 8981 was 8981, checked in by mikel, 11 years ago

additions to ObjC and ffi docs; many mechanical edits; some standardization of XML elements and formatting

File size: 108.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>
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 principle 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 suspend itself; it it&#39;s successful in doing
876              so, then it can obviously only be resumed by some other
877              process.</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>a generalized boolean.  The default is T.</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.  If <varname>kill-option</varname>
1550              is true, <varname>process</varname> then exits.  Otherwise, it
1551              enters a state where it can be
1552              <xref linkend="f_process-preset"/>. This
1553              is implemented by signaling a condition of type PROCESS-RESET;
1554              user-defined condition handlers should generally refrain from
1555              attempting to handle conditions of this type.</para>
1556
1557            <para>A process can meaningfully reset itself.</para>
1558
1559            <para>There is in general no way to know precisely when
1560              <varname>process</varname>
1561              has completed the act of resetting or killing itself; a process
1562              which has either entered the limbo of the reset state or exited
1563              has few ways of communicating either fact.
1564              <xref linkend="f_process-enable"/>
1565              can reliably determine when a process has entered
1566              the "limbo of the reset state", but can't predict how long the
1567              clean exit from ongoing computation might take: that depends on
1568              the behavior of <function>unwind-protect</function> cleanup
1569              forms, and of the OS scheduler.</para>
1570
1571            <para>Resetting a process other than
1572              <xref linkend="v_current-process"/> involves the
1573              use of <xref linkend="f_process-interrupt"/>.</para>
1574          </refsect1>
1575
1576          <refsect1>
1577            <title>See Also</title>
1578           
1579            <simplelist type="inline">
1580              <member><xref linkend="f_process-kill"/></member>
1581              <member><xref linkend="f_process-abort"/></member>
1582            </simplelist>
1583          </refsect1>
1584    </refentry>
1585
1586    <refentry id="f_process-kill">
1587          <indexterm zone="f_process-kill">
1588            <primary>process-kill</primary>
1589          </indexterm>
1590
1591          <refnamediv>
1592            <refname>PROCESS-KILL</refname>
1593            <refpurpose>Causes a specified process to cleanly exit from any
1594              ongoing computation, and then exit.</refpurpose>
1595            <refclass>Function</refclass>
1596          </refnamediv>
1597
1598          <refsynopsisdiv>
1599            <synopsis><function>process-kill</function> process
1600              => result</synopsis>
1601          </refsynopsisdiv>
1602
1603          <refsect1>
1604            <title>Arguments and Values</title>
1605
1606            <variablelist>
1607              <varlistentry>
1608                <term>process</term>
1609                <listitem>
1610                      <para>a lisp process (thread).</para>
1611                </listitem>
1612              </varlistentry>
1613              <varlistentry>
1614                <term>result</term>
1615                <listitem>
1616                      <para>undefined.</para>
1617                </listitem>
1618              </varlistentry>
1619            </variablelist>
1620          </refsect1>
1621
1622          <refsect1>
1623            <title>Description</title>
1624
1625            <para>Entirely equivalent to calling
1626              (PROCESS-RESET PROCESS T).  Causes <varname>process</varname>
1627              to cleanly exit from any ongoing computation, and then exit.</para>
1628          </refsect1>
1629
1630          <refsect1>
1631            <title>See Also</title>
1632           
1633            <simplelist type="inline">
1634              <member><xref linkend="f_process-reset"/></member>
1635              <member><xref linkend="f_process-abort"/></member>
1636            </simplelist>
1637          </refsect1>
1638    </refentry>
1639
1640    <refentry id="f_process-abort">
1641          <indexterm zone="f_process-abort">
1642            <primary>process-abort</primary>
1643          </indexterm>
1644
1645          <refnamediv>
1646            <refname>PROCESS-ABORT</refname>
1647            <refpurpose>Causes a specified process to process an abort
1648              condition, as if it had invoked
1649              <function>abort</function>.</refpurpose>
1650            <refclass>Function</refclass>
1651          </refnamediv>
1652
1653          <refsynopsisdiv>
1654            <synopsis><function>process-abort</function> process
1655              &optional; condition
1656              => NIL</synopsis>
1657          </refsynopsisdiv>
1658
1659          <refsect1>
1660            <title>Arguments and Values</title>
1661
1662            <variablelist>
1663              <varlistentry>
1664                <term>process</term>
1665                <listitem>
1666                      <para>a lisp process (thread).</para>
1667                </listitem>
1668              </varlistentry>
1669              <varlistentry>
1670                <term>condition</term>
1671                <listitem>
1672                      <para>a lisp condition.  The default is NIL.</para>
1673                </listitem>
1674              </varlistentry>
1675            </variablelist>
1676          </refsect1>
1677
1678          <refsect1>
1679            <title>Description</title>
1680
1681            <para>Entirely equivalent to calling
1682              (<xref linkend="f_process-interrupt"/> <varname>process</varname>
1683              (<function>lambda</function> ()
1684              (<function>abort</function> <varname>condition</varname>))).
1685              Causes <varname>process</varname> to transfer control to the
1686              applicable handler or restart for <function>abort</function>.</para>
1687
1688            <para>If <varname>condition</varname> is non-NIL,
1689              <function>process-abort</function> does not consider any
1690              handlers which are explicitly bound to conditions other than
1691              <varname>condition</varname>.</para>
1692          </refsect1>
1693
1694          <refsect1>
1695            <title>See Also</title>
1696           
1697            <simplelist type="inline">
1698              <member><xref linkend="f_process-reset"/></member>
1699              <member><xref linkend="f_process-kill"/></member>
1700            </simplelist>
1701          </refsect1>
1702    </refentry>
1703
1704    <refentry id="v_ticks-per-second">
1705          <indexterm zone="v_ticks-per-second">
1706            <primary>*ticks-per-second*</primary>
1707          </indexterm>
1708
1709          <refnamediv>
1710            <refname>*TICKS-PER-SECOND*</refname>
1711            <refpurpose>Bound to the clock resolution of the OS
1712              scheduler.</refpurpose>
1713            <refclass>Variable</refclass>
1714          </refnamediv>
1715
1716          <refsect1>
1717            <title>Value Type</title>
1718
1719            <para>A positive integer.</para>
1720          </refsect1>
1721
1722          <refsect1>
1723            <title>Initial Value</title>
1724           
1725            <para>The clock resolution of the OS scheduler.  Currently,
1726              both LinuxPPC and DarwinPPC yield an initial value of 100.
1727            </para>
1728          </refsect1>
1729
1730          <refsect1>
1731            <title>Description</title>
1732
1733            <para>This value is ordinarily of marginal interest at best,
1734              but, for backward compatibility, some functions accept timeout
1735              values expressed in "ticks".  This value gives the number of
1736              ticks per second.</para>
1737          </refsect1>
1738
1739          <refsect1>
1740            <title>See Also</title>
1741           
1742            <simplelist type="inline">
1743              <member><xref linkend="f_process-wait-with-timeout"/></member>
1744            </simplelist>
1745          </refsect1>
1746    </refentry>
1747
1748    <refentry id="f_process-whostate">
1749          <indexterm zone="f_process-whostate">
1750            <primary>process-whostate</primary>
1751          </indexterm>
1752
1753          <refnamediv>
1754            <refname>PROCESS-WHOSTATE</refname>
1755            <refpurpose>Returns a string which describes the status of
1756              a specified process.</refpurpose>
1757            <refclass>Function</refclass>
1758          </refnamediv>
1759
1760          <refsynopsisdiv>
1761            <synopsis><function>process-whostate</function> process
1762              => whostate</synopsis>
1763            <variablelist>
1764              <varlistentry>
1765                <term>process</term>
1766                <listitem>
1767                      <para>a lisp process (thread).</para>
1768                </listitem>
1769              </varlistentry>
1770              <varlistentry>
1771                <term>whostate</term>
1772                <listitem>
1773                      <para>a string which describes the "state" of
1774                        <varname>process</varname>.</para>
1775                </listitem>
1776              </varlistentry>
1777            </variablelist>
1778          </refsynopsisdiv>
1779
1780          <refsect1>
1781            <title>Description</title>
1782
1783            <para>This information is primarily for the benefit of
1784              debugging tools.  <varname>whostate</varname> is a terse report
1785              on what <varname>process</varname> is doing, or not doing,
1786              and why.</para>
1787
1788            <para>If the process is currently waiting in a call to
1789              <xref linkend="f_process-wait"/> or
1790              <xref linkend="f_process-wait-with-timeout"/>, its
1791              <function>process-whostate</function> will be the value
1792              which was passed to that function as <varname>whostate</varname>.
1793            </para>
1794          </refsect1>
1795
1796          <refsect1>
1797            <title>See Also</title>
1798           
1799            <simplelist type="inline">
1800              <member><xref linkend="f_process-wait"/></member>
1801              <member><xref linkend="f_process-wait-with-timeout"/></member>
1802              <member><xref linkend="m_with-terminal-input"/></member>
1803            </simplelist>
1804          </refsect1>
1805
1806          <refsect1>
1807            <title>Notes</title>
1808
1809            <para>This should arguably be SETFable, but doesn't seem to
1810              ever have been.</para>
1811          </refsect1>
1812    </refentry>
1813
1814    <refentry id="f_process-allow-schedule">
1815          <indexterm zone="f_process-allow-schedule">
1816            <primary>process-allow-schedule</primary>
1817          </indexterm>
1818
1819          <refnamediv>
1820            <refname>PROCESS-ALLOW-SCHEDULE</refname>
1821            <refpurpose>Used for cooperative multitasking; probably never
1822              necessary.</refpurpose>
1823            <refclass>Function</refclass>
1824          </refnamediv>
1825
1826          <refsynopsisdiv>
1827            <synopsis><function>process-allow-schedule</function></synopsis>
1828          </refsynopsisdiv>
1829
1830          <refsect1>
1831            <title>Description</title>
1832
1833            <para>Advises the OS scheduler that the current thread has nothing
1834              useful to do and that it should try to find some other thread to
1835              schedule in its place. There's almost always a better
1836              alternative, such as waiting for some specific event to
1837              occur.  For example, you could use a lock or semaphore.</para>
1838          </refsect1>
1839
1840          <refsect1>
1841            <title>See Also</title>
1842           
1843            <simplelist type="inline">
1844              <member><xref linkend="f_make-lock"/></member>
1845              <member><xref linkend="f_make-read-write-lock"/></member>
1846              <member><xref linkend="f_make-semaphore"/></member>
1847              <member><xref linkend="f_process-input-wait"/></member>
1848              <member><xref linkend="f_process-output-wait"/></member>
1849              <member><xref linkend="m_with-terminal-input"/></member>
1850            </simplelist>
1851          </refsect1>
1852
1853          <refsect1>
1854            <title>Notes</title>
1855
1856            <para>This is a holdover from the days of cooperative
1857              multitasking.  All modern general-purpose operating systems use
1858              preemptive multitasking.</para>
1859          </refsect1>
1860    </refentry>
1861
1862    <refentry id="f_process-wait">
1863          <indexterm zone="f_process-wait">
1864            <primary>process-wait</primary>
1865          </indexterm>
1866
1867          <refnamediv>
1868            <refname>PROCESS-WAIT</refname>
1869            <refpurpose>Causes the current lisp process (thread) to wait for
1870              a given
1871              predicate to return true.</refpurpose>
1872            <refclass>Function</refclass>
1873          </refnamediv>
1874
1875          <refsynopsisdiv>
1876            <synopsis><function>process-wait</function>
1877              whostate function &rest; args => result</synopsis>
1878          </refsynopsisdiv>
1879
1880          <refsect1>
1881            <title>Arguments and Values</title>
1882
1883            <variablelist>
1884              <varlistentry>
1885                <term>whostate</term>
1886
1887                <listitem>
1888                      <para>a string, which will be the value of
1889                        <xref linkend="f_process-whostate"/>
1890                        while the process is waiting.</para>
1891                </listitem>
1892              </varlistentry>
1893              <varlistentry>
1894                <term>function</term>
1895                <listitem>
1896                      <para>a function, designated by itself or by a symbol
1897                        which names it.
1898                      </para>
1899                </listitem>
1900              </varlistentry>
1901              <varlistentry>
1902                <term>args</term>
1903                <listitem>
1904                      <para>a list of values, appropriate as arguments to
1905                        <varname>function</varname>.</para>
1906                </listitem>
1907              </varlistentry>
1908              <varlistentry>
1909                <term>result</term>
1910                <listitem>
1911                      <para>NIL.</para>
1912                </listitem>
1913              </varlistentry>
1914            </variablelist>
1915          </refsect1>
1916
1917          <refsect1>
1918            <title>Description</title>
1919
1920            <para>Causes the current lisp process (thread) to repeatedly
1921              apply <varname>function</varname> to
1922              <varname>args</varname> until the call returns a true result, then
1923              returns NIL. After
1924              each failed call, yields the CPU as if by
1925              <xref linkend="f_process-allow-schedule"/>.</para>
1926           
1927            <para>
1928              As with <xref linkend="f_process-allow-schedule"/>, it's almost
1929              always more efficient to wait for some
1930              specific event to occur; this isn't exactly busy-waiting, but
1931              the OS scheduler can do a better job of scheduling if it's given
1932              the relevant information.  For example, you could use a lock
1933              or semaphore.</para>
1934          </refsect1>
1935
1936          <refsect1>
1937            <title>See Also</title>
1938           
1939            <simplelist type="inline">
1940              <member><xref linkend="f_process-whostate"/></member>
1941              <member><xref linkend="f_process-wait-with-timeout"/></member>
1942              <member><xref linkend="f_make-lock"/></member>
1943              <member><xref linkend="f_make-read-write-lock"/></member>
1944              <member><xref linkend="f_make-semaphore"/></member>
1945              <member><xref linkend="f_process-input-wait"/></member>
1946              <member><xref linkend="f_process-output-wait"/></member>
1947              <member><xref linkend="m_with-terminal-input"/></member>
1948            </simplelist>
1949          </refsect1>
1950    </refentry>
1951
1952    <refentry id="f_process-wait-with-timeout">
1953          <indexterm zone="f_process-wait-with-timeout">
1954            <primary>process-wait-with-timeout</primary>
1955          </indexterm>
1956
1957          <refnamediv>
1958            <refname>PROCESS-WAIT-WITH-TIMEOUT</refname>
1959            <refpurpose>Causes the current thread to wait for a given
1960              predicate to return true, or for a timeout to expire.</refpurpose>
1961            <refclass>Function</refclass>
1962          </refnamediv>
1963
1964          <refsynopsisdiv>
1965            <synopsis><function>process-wait-with-timeout</function>
1966              whostate ticks function args => result</synopsis>
1967          </refsynopsisdiv>
1968
1969          <refsect1>
1970            <title>Arguments and Values</title>
1971
1972            <variablelist>
1973              <varlistentry>
1974                <term>whostate</term>
1975                <listitem>
1976                      <para>a string, which will be the value of
1977                        <xref linkend="f_process-whostate"/>
1978                        while the process is waiting.</para>
1979                </listitem>
1980              </varlistentry>
1981              <varlistentry>
1982                <term>ticks</term>
1983                <listitem>
1984                      <para>either a positive integer expressing a duration
1985                        in "ticks" (see <xref linkend="v_ticks-per-second"/>),
1986                        or NIL.</para>
1987                </listitem>
1988              </varlistentry>
1989              <varlistentry>
1990                <term>function</term>
1991                <listitem>
1992                      <para>a function, designated by itself or by a symbol
1993                        which names it.</para>
1994                </listitem>
1995              </varlistentry>
1996              <varlistentry>
1997                <term>args</term>
1998                <listitem>
1999                      <para>a list of values, appropriate as arguments to
2000                        <varname>function</varname>.</para>
2001                </listitem>
2002              </varlistentry>
2003              <varlistentry>
2004                <term>result</term>
2005                <listitem>
2006                      <para>T if <function>process-wait-with-timeout</function>
2007                        returned because its <varname>function</varname> returned
2008                        true, or NIL if it returned because the duration
2009                        <varname>ticks</varname> has been exceeded.</para>
2010                </listitem>
2011              </varlistentry>
2012            </variablelist>
2013          </refsect1>
2014
2015          <refsect1>
2016            <title>Description</title>
2017
2018            <para>If <varname>ticks</varname> is NIL, behaves exactly like
2019              <xref linkend="f_process-wait"/>, except for returning T.
2020              Otherwise, <varname>function</varname> will be tested repeatedly,
2021              in the same
2022              kind of test/yield loop as in <xref linkend="f_process-wait"/>>
2023              until either <varname>function</varname> returns true,
2024              or the duration <varname>ticks</varname> has been exceeded.
2025            </para>
2026
2027            <para> Having already read the descriptions of
2028              <xref linkend="f_process-allow-schedule"/> and
2029              <xref linkend="f_process-wait"/>, the
2030              astute reader has no doubt anticipated the observation that
2031              better alternatives should be used whenever possible.</para>
2032          </refsect1>
2033
2034          <refsect1>
2035            <title>See Also</title>
2036           
2037            <simplelist type="inline">
2038              <member><xref linkend="v_ticks-per-second"/></member>
2039              <member><xref linkend="f_process-whostate"/></member>
2040              <member><xref linkend="f_process-wait"/></member>
2041              <member><xref linkend="f_make-lock"/></member>
2042              <member><xref linkend="f_make-read-write-lock"/></member>
2043              <member><xref linkend="f_make-semaphore"/></member>
2044              <member><xref linkend="f_process-input-wait"/></member>
2045              <member><xref linkend="f_process-output-wait"/></member>
2046              <member><xref linkend="m_with-terminal-input"/></member>
2047            </simplelist>
2048          </refsect1>
2049    </refentry>
2050
2051    <refentry id="m_without-interrupts">
2052          <indexterm zone="m_without-interrupts">
2053            <primary>without-interrupts</primary>
2054          </indexterm>
2055
2056          <refnamediv>
2057            <refname>WITHOUT-INTERRUPTS</refname>
2058            <refpurpose>Evaluates its body in an environment in which
2059              process-interrupt requests are deferred.</refpurpose>
2060            <refclass>Macro</refclass>
2061          </refnamediv>
2062
2063          <refsynopsisdiv>
2064            <synopsis><function>without-interrupts</function>
2065              &body; body => result</synopsis>
2066          </refsynopsisdiv>
2067
2068          <refsect1>
2069            <title>Arguments and Values</title>
2070
2071            <variablelist>
2072              <varlistentry>
2073                <term>body</term>
2074                <listitem>
2075                      <para>an implicit progn.</para>
2076                </listitem>
2077              </varlistentry>
2078              <varlistentry>
2079                <term>result</term>
2080                <listitem>
2081                      <para>the primary value returned by
2082                        <varname>body</varname>.</para>
2083                </listitem>
2084              </varlistentry>
2085            </variablelist>
2086          </refsect1>
2087
2088          <refsect1>
2089            <title>Description</title>
2090
2091            <para>Executes <varname>body</varname>
2092              in an environment in which <xref linkend="f_process-interrupt"/>
2093              requests are
2094              deferred. As noted in the description of
2095              <xref linkend="f_process-interrupt"/>, this has nothing to do
2096              with the
2097              scheduling of other threads; it may be necessary to inhibit
2098              <xref linkend="f_process-interrupt"/> handling when
2099              (for instance) modifying some data
2100              structure (for which the current thread holds an appropriate lock)
2101              in some manner that&#39;s not reentrant.</para>
2102          </refsect1>
2103
2104          <refsect1>
2105            <title>See Also</title>
2106           
2107            <simplelist type="inline">
2108              <member><xref linkend="f_process-interrupt"/></member>
2109            </simplelist>
2110          </refsect1>
2111    </refentry>
2112
2113    <refentry id="f_make-lock">
2114          <indexterm zone="f_make-lock">
2115            <primary>make-lock</primary>
2116          </indexterm>
2117
2118          <refnamediv>
2119            <refname>MAKE-LOCK</refname>
2120            <refpurpose>Creates and returns a lock object, which can
2121              be used for synchronization between threads.</refpurpose>
2122            <refclass>Function</refclass>
2123          </refnamediv>
2124
2125          <refsynopsisdiv>
2126            <synopsis><function>make-lock</function> &optional;
2127              name => lock</synopsis>
2128          </refsynopsisdiv>
2129
2130          <refsect1>
2131            <title>Arguments and Values</title>
2132
2133            <variablelist>
2134              <varlistentry>
2135                <term>name</term>
2136                <listitem>
2137                      <para>any lisp object; saved as part of
2138                        <varname>lock</varname>.  Typically a string or symbol
2139                        which may appear in the <xref linkend="f_process-whostate"/>s
2140                        of threads which are waiting for <varname>lock</varname>.
2141                      </para>
2142                </listitem>
2143              </varlistentry>
2144              <varlistentry>
2145                <term>lock</term>
2146                <listitem>
2147                      <para>a newly-allocated object of type CCL:LOCK.</para>
2148                </listitem>
2149              </varlistentry>
2150            </variablelist>
2151          </refsect1>
2152
2153          <refsect1>
2154            <title>Description</title>
2155
2156            <para>Creates and returns a lock object, which can
2157              be used to synchronize access to some shared resource.
2158              <varname>lock</varname> is
2159              initially in a &#34;free&#34; state; a lock can also be
2160              &#34;owned&#34; by a
2161              thread.</para>
2162          </refsect1>
2163
2164          <refsect1>
2165            <title>See Also</title>
2166           
2167            <simplelist type="inline">
2168              <member><xref linkend="m_with-lock-grabbed"/></member>
2169              <member><xref linkend="f_grab-lock"/></member>
2170              <member><xref linkend="f_release-lock"/></member>
2171              <member><xref linkend="f_try-lock"/></member>
2172              <member><xref linkend="f_make-read-write-lock"/></member>
2173              <member><xref linkend="f_make-semaphore"/></member>
2174              <member><xref linkend="f_process-input-wait"/></member>
2175              <member><xref linkend="f_process-output-wait"/></member>
2176              <member><xref linkend="m_with-terminal-input"/></member>
2177            </simplelist>
2178          </refsect1>
2179    </refentry>
2180
2181    <refentry id="m_with-lock-grabbed">
2182          <indexterm zone="m_with-lock-grabbed">
2183            <primary>with-lock-grabbed</primary>
2184          </indexterm>
2185
2186          <refnamediv>
2187            <refname>WITH-LOCK-GRABBED</refname>
2188            <refpurpose>Waits until a given lock can be obtained, then
2189              evaluates its body with the lock held.</refpurpose>
2190            <refclass>Macro</refclass>
2191          </refnamediv>
2192
2193          <refsynopsisdiv>
2194            <synopsis><function>with-lock-grabbed</function>
2195              (lock) &body; body</synopsis>
2196          </refsynopsisdiv>
2197
2198          <refsect1>
2199            <title>Arguments and Values</title>
2200
2201            <variablelist>
2202              <varlistentry>
2203                <term>lock</term>
2204                <listitem>
2205                      <para>an object of type CCL:LOCK.</para>
2206                </listitem>
2207              </varlistentry>
2208              <varlistentry>
2209                <term>body</term>
2210                <listitem>
2211                      <para>an implicit progn.</para>
2212                </listitem>
2213              </varlistentry>
2214              <varlistentry>
2215                <term>result</term>
2216                <listitem>
2217                      <para>the primary value returned by
2218                        <varname>body</varname>.</para>
2219                </listitem>
2220              </varlistentry>
2221            </variablelist>
2222          </refsect1>
2223
2224          <refsect1>
2225            <title>Description</title>
2226
2227            <para>Waits until <varname>lock</varname> is either free or
2228              owned by the calling
2229              thread, then executes <varname>body</varname> with the
2230              lock owned by the calling thread. If <varname>lock</varname>
2231              was free when <function>with-lock-grabbed</function> was called,
2232              it is restored to a free state after <varname>body</varname>
2233              is executed.</para>
2234          </refsect1>
2235
2236          <refsect1>
2237            <title>See Also</title>
2238           
2239            <simplelist type="inline">
2240              <member><xref linkend="f_make-lock"/></member>
2241              <member><xref linkend="f_grab-lock"/></member>
2242              <member><xref linkend="f_release-lock"/></member>
2243              <member><xref linkend="f_try-lock"/></member>
2244              <member><xref linkend="f_make-read-write-lock"/></member>
2245              <member><xref linkend="f_make-semaphore"/></member>
2246              <member><xref linkend="f_process-input-wait"/></member>
2247              <member><xref linkend="f_process-output-wait"/></member>
2248              <member><xref linkend="m_with-terminal-input"/></member>
2249            </simplelist>
2250          </refsect1>
2251    </refentry>
2252
2253    <refentry id="f_grab-lock">
2254          <indexterm zone="f_grab-lock">
2255            <primary>grab-lock</primary>
2256          </indexterm>
2257
2258          <refnamediv>
2259            <refname>GRAB-LOCK</refname>
2260            <refpurpose>Waits until a given lock can be obtained, then
2261              obtains it.</refpurpose>
2262            <refclass>Function</refclass>
2263          </refnamediv>
2264
2265          <refsynopsisdiv>
2266            <synopsis><function>grab-lock</function> lock</synopsis>
2267          </refsynopsisdiv>
2268
2269          <refsect1>
2270            <title>Arguments and Values</title>
2271
2272            <variablelist>
2273              <varlistentry>
2274                <term>lock</term>
2275                <listitem>
2276                      <para>an object of type CCL:LOCK.</para>
2277                </listitem>
2278              </varlistentry>
2279            </variablelist>
2280          </refsect1>
2281
2282          <refsect1>
2283            <title>Description</title>
2284
2285            <para>Blocks until <varname>lock</varname> is owned by the
2286              calling thread.</para>
2287
2288            <para>The macro <xref linkend="m_with-lock-grabbed"/>
2289              <emphasis>could</emphasis> be defined in
2290              terms of <function>grab-lock</function> and
2291              <xref linkend="f_release-lock"/>, but it is actually
2292              implemented at a slightly lower level.</para>
2293          </refsect1>
2294
2295          <refsect1>
2296            <title>See Also</title>
2297           
2298            <simplelist type="inline">
2299              <member><xref linkend="f_make-lock"/></member>
2300              <member><xref linkend="m_with-lock-grabbed"/></member>
2301              <member><xref linkend="f_release-lock"/></member>
2302              <member><xref linkend="f_try-lock"/></member>
2303              <member><xref linkend="f_make-read-write-lock"/></member>
2304              <member><xref linkend="f_make-semaphore"/></member>
2305              <member><xref linkend="f_process-input-wait"/></member>
2306              <member><xref linkend="f_process-output-wait"/></member>
2307              <member><xref linkend="m_with-terminal-input"/></member>
2308            </simplelist>
2309          </refsect1>
2310    </refentry>
2311
2312    <refentry id="f_release-lock">
2313          <indexterm zone="f_release-lock">
2314            <primary>release-lock</primary>
2315          </indexterm>
2316
2317          <refnamediv>
2318            <refname>RELEASE-LOCK</refname>
2319            <refpurpose>Relinquishes ownership of a given lock.</refpurpose>
2320            <refclass>Function</refclass>
2321          </refnamediv>
2322
2323          <refsynopsisdiv>
2324            <synopsis><function>release-lock</function> lock</synopsis>
2325          </refsynopsisdiv>
2326
2327          <refsect1>
2328            <title>Arguments and Values</title>
2329
2330            <variablelist>
2331              <varlistentry>
2332                <term>lock</term>
2333                <listitem>
2334                      <para>an object of type CCL:LOCK.</para>
2335                </listitem>
2336              </varlistentry>
2337            </variablelist>
2338          </refsect1>
2339
2340          <refsect1>
2341            <title>Description</title>
2342
2343            <para>Signals an error of type CCL:LOCK-NOT-OWNER if
2344              <varname>lock</varname>
2345              is not already owned by the calling thread; otherwise, undoes the
2346              effect of one previous
2347              <xref linkend="f_grab-lock"/>.  If this means that
2348              <function>release-lock</function> has now been called on
2349              <varname>lock</varname> the same number of times as
2350              <xref linkend="f_grab-lock"/> has, <varname>lock</varname>
2351              becomes free.</para>
2352          </refsect1>
2353
2354          <refsect1>
2355            <title>See Also</title>
2356           
2357            <simplelist type="inline">
2358              <member><xref linkend="f_make-lock"/></member>
2359              <member><xref linkend="m_with-lock-grabbed"/></member>
2360              <member><xref linkend="f_grab-lock"/></member>
2361              <member><xref linkend="f_try-lock"/></member>
2362              <member><xref linkend="f_make-read-write-lock"/></member>
2363              <member><xref linkend="f_make-semaphore"/></member>
2364              <member><xref linkend="f_process-input-wait"/></member>
2365              <member><xref linkend="f_process-output-wait"/></member>
2366              <member><xref linkend="m_with-terminal-input"/></member>
2367            </simplelist>
2368          </refsect1>
2369    </refentry>
2370
2371    <refentry id="f_try-lock">
2372          <indexterm zone="f_try-lock">
2373            <primary>try-lock</primary>
2374          </indexterm>
2375
2376          <refnamediv>
2377            <refname>TRY-LOCK</refname>
2378            <refpurpose>Obtains the given lock, but only if it is not
2379              necessary to wait for it.</refpurpose>
2380            <refclass>Function</refclass>
2381          </refnamediv>
2382
2383          <refsynopsisdiv>
2384            <synopsis><function>try-lock</function> lock => result</synopsis>
2385          </refsynopsisdiv>
2386
2387          <refsect1>
2388            <title>Arguments and Values</title>
2389
2390            <variablelist>
2391              <varlistentry>
2392                <term>lock</term>
2393                <listitem>
2394                      <para>an object of type CCL:LOCK.</para>
2395                </listitem>
2396              </varlistentry>
2397              <varlistentry>
2398                <term>result</term>
2399                <listitem>
2400                      <para>T if <varname>lock</varname> has been obtained,
2401                        or NIL if it has not.</para>
2402                </listitem>
2403              </varlistentry>
2404            </variablelist>
2405          </refsect1>
2406
2407          <refsect1>
2408            <title>Description</title>
2409
2410            <para>Tests whether <varname>lock</varname>
2411              can be obtained without blocking - that is, either
2412              <varname>lock</varname> is already free, or it is already owned
2413              by <xref linkend="v_current-process"/>.  If it can,
2414              causes it to
2415              be owned by the calling lisp process (thread) and returns T.
2416              Otherwise, the lock
2417              is already owned by another thread and cannot be obtained without
2418              blocking; NIL is returned in this case.</para>
2419          </refsect1>
2420
2421          <refsect1>
2422            <title>See Also</title>
2423           
2424            <simplelist type="inline">
2425              <member><xref linkend="f_make-lock"/></member>
2426              <member><xref linkend="m_with-lock-grabbed"/></member>
2427              <member><xref linkend="f_grab-lock"/></member>
2428              <member><xref linkend="f_release-lock"/></member>
2429              <member><xref linkend="f_make-read-write-lock"/></member>
2430              <member><xref linkend="f_make-semaphore"/></member>
2431              <member><xref linkend="f_process-input-wait"/></member>
2432              <member><xref linkend="f_process-output-wait"/></member>
2433              <member><xref linkend="m_with-terminal-input"/></member>
2434            </simplelist>
2435          </refsect1>
2436    </refentry>
2437
2438    <refentry id="f_make-read-write-lock">
2439          <indexterm zone="f_make-read-write-lock">
2440            <primary>make-read-write-lock</primary>
2441          </indexterm>
2442
2443          <refnamediv>
2444            <refname>MAKE-READ-WRITE-LOCK</refname>
2445            <refpurpose>Creates and returns a read-write lock, which can
2446              be used for synchronization between threads.</refpurpose>
2447            <refclass>Function</refclass>
2448          </refnamediv>
2449
2450          <refsynopsisdiv>
2451            <synopsis><function>make-read-write-lock</function>
2452              => read-write-lock</synopsis>
2453          </refsynopsisdiv>
2454
2455          <refsect1>
2456            <title>Arguments and Values</title>
2457
2458            <variablelist>
2459              <varlistentry>
2460                <term>read-write-lock</term>
2461                <listitem>
2462                      <para>a newly-allocated object of type
2463                        CCL:READ-WRITE-LOCK.</para>
2464                </listitem>
2465              </varlistentry>
2466            </variablelist>
2467          </refsect1>
2468
2469          <refsect1>
2470            <title>Description</title>
2471
2472            <para>Creates and returns an object of type CCL::READ-WRITE-LOCK.
2473              A read-write lock may, at any given time, belong to any number
2474              of lisp processes (threads) which act as "readers"; or, it may
2475              belong to at most one process which acts as a "writer".  A
2476              read-write lock may never be held by a reader at the same time as
2477              a writer.  Initially, <varname>read-write-lock</varname> has
2478              no readers and no writers.</para>
2479          </refsect1>
2480
2481          <refsect1>
2482            <title>See Also</title>
2483           
2484            <simplelist type="inline">
2485              <member><xref linkend="m_with-read-lock"/></member>
2486              <member><xref linkend="m_with-write-lock"/></member>
2487              <member><xref linkend="f_make-lock"/></member>
2488              <member><xref linkend="f_make-semaphore"/></member>
2489              <member><xref linkend="f_process-input-wait"/></member>
2490              <member><xref linkend="f_process-output-wait"/></member>
2491              <member><xref linkend="m_with-terminal-input"/></member>
2492            </simplelist>
2493          </refsect1>
2494
2495          <refsect1>
2496            <title>Notes</title>
2497
2498            <para>There probably should be some way to
2499              atomically &#34;promote&#34; a reader, making it a writer without
2500              releasing the lock, which could otherwise cause delay.</para>
2501          </refsect1>
2502    </refentry>
2503
2504    <refentry id="m_with-read-lock">
2505          <indexterm zone="m_with-read-lock">
2506            <primary>with-read-lock</primary>
2507          </indexterm>
2508
2509          <refnamediv>
2510            <refname>WITH-READ-LOCK</refname>
2511            <refpurpose>Waits until a given lock is available for
2512              read-only access, then evaluates its body with the lock
2513              held.</refpurpose>
2514            <refclass>Macro</refclass>
2515          </refnamediv>
2516
2517          <refsynopsisdiv>
2518            <synopsis><function>with-read-lock</function>
2519              (read-write-lock) &body; body => result</synopsis>
2520          </refsynopsisdiv>
2521
2522          <refsect1>
2523            <title>Arguments and Values</title>
2524
2525            <variablelist>
2526              <varlistentry>
2527                <term>read-write-lock</term>
2528                <listitem>
2529                      <para>an object of type
2530                        CCL:READ-WRITE-LOCK.</para>
2531                </listitem>
2532              </varlistentry>
2533              <varlistentry>
2534                <term>body</term>
2535                <listitem>
2536                      <para>an implicit progn.</para>
2537                </listitem>
2538              </varlistentry>
2539              <varlistentry>
2540                <term>result</term>
2541                <listitem>
2542                      <para>the primary value returned by
2543                        <varname>body</varname>.</para>
2544                </listitem>
2545              </varlistentry>
2546            </variablelist>
2547          </refsect1>
2548
2549          <refsect1>
2550            <title>Description</title>
2551
2552            <para>Waits until <varname>read-write-lock</varname> has no
2553              writer,
2554              ensures that <xref linkend="v_current-process"/> is a
2555              reader of it, then executes <varname>body</varname>.
2556            </para>
2557
2558            <para>After executing <varname>body</varname>, if
2559              <xref linkend="v_current-process"/> was not a reader of
2560              <varname>read-write-lock</varname> before
2561              <function>with-read-lock</function> was called, the lock is
2562              released.  If it was already a reader, it remains one.</para>
2563          </refsect1>
2564
2565          <refsect1>
2566            <title>See Also</title>
2567           
2568            <simplelist type="inline">
2569              <member><xref linkend="f_make-read-write-lock"/></member>
2570              <member><xref linkend="m_with-write-lock"/></member>
2571              <member><xref linkend="f_make-lock"/></member>
2572              <member><xref linkend="f_make-semaphore"/></member>
2573              <member><xref linkend="f_process-input-wait"/></member>
2574              <member><xref linkend="f_process-output-wait"/></member>
2575              <member><xref linkend="m_with-terminal-input"/></member>
2576            </simplelist>
2577          </refsect1>
2578    </refentry>
2579
2580    <refentry id="m_with-write-lock">
2581          <indexterm zone="m_with-write-lock">
2582            <primary>with-write-lock</primary>
2583          </indexterm>
2584
2585          <refnamediv>
2586            <refname>WITH-WRITE-LOCK</refname>
2587            <refpurpose>Waits until the given lock is available for write
2588              access, then executes its body with the lock held.</refpurpose>
2589            <refclass>Macro</refclass>
2590          </refnamediv>
2591
2592          <refsynopsisdiv>
2593            <synopsis><function>with-write-lock</function>
2594              (read-write-lock) &body; body</synopsis>
2595          </refsynopsisdiv>
2596
2597          <refsect1>
2598            <title>Arguments and Values</title>
2599
2600            <variablelist>
2601              <varlistentry>
2602                <term>read-write-lock</term>
2603                <listitem>
2604                      <para>an object of type
2605                        CCL:READ-WRITE-LOCK.</para>
2606                </listitem>
2607              </varlistentry>
2608              <varlistentry>
2609                <term>body</term>
2610                <listitem>
2611                      <para>an implicit progn.</para>
2612                </listitem>
2613              </varlistentry>
2614              <varlistentry>
2615                <term>result</term>
2616                <listitem>
2617                      <para>the primary value returned by
2618                        <varname>body</varname>.</para>
2619                </listitem>
2620              </varlistentry>
2621            </variablelist>
2622          </refsect1>
2623
2624          <refsect1>
2625            <title>Description</title>
2626
2627            <para>Waits until <varname>read-write-lock</varname> has no
2628              readers and no writer other than <xref linkend="v_current-process"/>,
2629              then ensures that <xref linkend="v_current-process"/> is the
2630              writer of it.  With the lock held, executes <varname>body</varname>.
2631            </para>
2632
2633            <para>After executing <varname>body</varname>, if
2634              <xref linkend="v_current-process"/> was not the writer of
2635              <varname>read-write-lock</varname> before
2636              <function>with-write-lock</function> was called, the lock is
2637              released.  If it was already the writer, it remains the
2638              writer.</para>
2639          </refsect1>
2640
2641          <refsect1>
2642            <title>See Also</title>
2643           
2644            <simplelist type="inline">
2645              <member><xref linkend="f_make-read-write-lock"/></member>
2646              <member><xref linkend="m_with-read-lock"/></member>
2647              <member><xref linkend="f_make-lock"/></member>
2648              <member><xref linkend="f_make-semaphore"/></member>
2649              <member><xref linkend="f_process-input-wait"/></member>
2650              <member><xref linkend="f_process-output-wait"/></member>
2651              <member><xref linkend="m_with-terminal-input"/></member>
2652            </simplelist>
2653          </refsect1>
2654    </refentry>
2655
2656    <refentry id="f_make-semaphore">
2657          <indexterm zone="f_make-semaphore">
2658            <primary>make-semaphore</primary>
2659          </indexterm>
2660
2661          <refnamediv>
2662            <refname>MAKE-SEMAPHORE</refname>
2663            <refpurpose>Creates and returns a semaphore, which can be used
2664              for synchronization between threads.</refpurpose>
2665            <refclass>Function</refclass>
2666          </refnamediv>
2667
2668          <refsynopsisdiv>
2669            <synopsis><function>make-semaphore</function>
2670              => semaphore</synopsis>
2671          </refsynopsisdiv>
2672
2673          <refsect1>
2674            <title>Arguments and Values</title>
2675           
2676            <variablelist>
2677              <varlistentry>
2678                <term>semaphore</term>
2679                <listitem>
2680                      <para>a newly-allocated object of type CCL:SEMAPHORE.</para>
2681                </listitem>
2682              </varlistentry>
2683            </variablelist>
2684          </refsect1>
2685
2686          <refsect1>
2687            <title>Description</title>
2688
2689            <para>Creates and returns an object of type CCL:SEMAPHORE.
2690              A semaphore has an associated "count" which may be incremented
2691              and decremented atomically; incrementing it represents sending
2692              a signal, and decrementing it represents handling that signal.
2693              <varname>semaphore</varname> has an initial count of 0.</para>
2694          </refsect1>
2695
2696          <refsect1>
2697            <title>See Also</title>
2698           
2699            <simplelist type="inline">
2700              <member><xref linkend="f_signal-semaphore"/></member>
2701              <member><xref linkend="f_wait-on-semaphore"/></member>
2702              <member><xref linkend="f_timed-wait-on-semaphore"/></member>
2703              <member><xref linkend="f_make-lock"/></member>
2704              <member><xref linkend="f_make-read-write-lock"/></member>
2705              <member><xref linkend="f_process-input-wait"/></member>
2706              <member><xref linkend="f_process-output-wait"/></member>
2707              <member><xref linkend="m_with-terminal-input"/></member>
2708            </simplelist>
2709          </refsect1>
2710    </refentry>
2711
2712    <refentry id="f_signal-semaphore">
2713          <indexterm zone="f_signal-semaphore">
2714            <primary>signal-semaphore</primary>
2715          </indexterm>
2716
2717          <refnamediv>
2718            <refname>SIGNAL-SEMAPHORE</refname>
2719            <refpurpose>Atomically increments the count of a given
2720              semaphore.</refpurpose>
2721            <refclass>Function</refclass>
2722          </refnamediv>
2723
2724          <refsynopsisdiv>
2725            <synopsis><function>signal-semaphore</function>
2726              semaphore => result</synopsis>
2727          </refsynopsisdiv>
2728
2729          <refsect1>
2730            <title>Arguments and Values</title>
2731           
2732            <variablelist>
2733              <varlistentry>
2734                <term>semaphore</term>
2735                <listitem>
2736                      <para>an object of type CCL:SEMAPHORE.</para>
2737                </listitem>
2738              </varlistentry>
2739              <varlistentry>
2740                <term>result</term>
2741                <listitem>
2742                      <para>an integer representing an error identifier
2743                        which was returned by the underlying OS call.</para>
2744                </listitem>
2745              </varlistentry>
2746            </variablelist>
2747          </refsect1>
2748
2749          <refsect1>
2750            <title>Description</title>
2751
2752            <para>Atomically increments <varname>semaphore</varname>'s
2753              "count" by 1; this
2754              may enable a waiting thread to resume execution.</para>
2755          </refsect1>
2756
2757          <refsect1>
2758            <title>See Also</title>
2759           
2760            <simplelist type="inline">
2761              <member><xref linkend="f_make-semaphore"/></member>
2762              <member><xref linkend="f_wait-on-semaphore"/></member>
2763              <member><xref linkend="f_timed-wait-on-semaphore"/></member>
2764              <member><xref linkend="f_make-lock"/></member>
2765              <member><xref linkend="f_make-read-write-lock"/></member>
2766              <member><xref linkend="f_process-input-wait"/></member>
2767              <member><xref linkend="f_process-output-wait"/></member>
2768              <member><xref linkend="m_with-terminal-input"/></member>
2769            </simplelist>
2770          </refsect1>
2771
2772          <refsect1>
2773            <title>Notes</title>
2774
2775            <para><varname>result</varname> should probably be interpreted
2776              and acted on by <function>signal-semaphore</function>, because
2777              it is not likely to be meaningful to a lisp program, and the
2778              most common cause of failure is a type error.</para>
2779          </refsect1>
2780    </refentry>
2781
2782    <refentry id="f_wait-on-semaphore">
2783          <indexterm zone="f_wait-on-semaphore">
2784            <primary>wait-on-semaphore</primary>
2785          </indexterm>
2786
2787          <refnamediv>
2788            <refname>WAIT-ON-SEMAPHORE</refname>
2789            <refpurpose>Waits until the given semaphore has a positive
2790              count which can be atomically decremented.</refpurpose>
2791            <refclass>Function</refclass>
2792          </refnamediv>
2793
2794          <refsynopsisdiv>
2795            <synopsis><function>wait-on-semaphore</function>
2796              semaphore => result</synopsis>
2797          </refsynopsisdiv>
2798
2799          <refsect1>
2800            <title>Arguments and Values</title>
2801           
2802            <variablelist>
2803              <varlistentry>
2804                <term>semaphore</term>
2805                <listitem>
2806                      <para>an object of type CCL:SEMAPHORE.</para>
2807                </listitem>
2808              </varlistentry>
2809              <varlistentry>
2810                <term>result</term>
2811                <listitem>
2812                      <para>an integer representing an error identifier
2813                        which was returned by the underlying OS call.</para>
2814                </listitem>
2815              </varlistentry>
2816            </variablelist>
2817          </refsect1>
2818
2819          <refsect1>
2820            <title>Description</title>
2821
2822            <para>Waits until <varname>semaphore</varname>
2823              has a positive count that can be
2824              atomically decremented; this will succeed exactly once for each
2825              corresponding call to SIGNAL-SEMAPHORE.</para>
2826          </refsect1>
2827
2828          <refsect1>
2829            <title>See Also</title>
2830           
2831            <simplelist type="inline">
2832              <member><xref linkend="f_make-semaphore"/></member>
2833              <member><xref linkend="f_signal-semaphore"/></member>
2834              <member><xref linkend="f_timed-wait-on-semaphore"/></member>
2835              <member><xref linkend="f_make-lock"/></member>
2836              <member><xref linkend="f_make-read-write-lock"/></member>
2837              <member><xref linkend="f_process-input-wait"/></member>
2838              <member><xref linkend="f_process-output-wait"/></member>
2839              <member><xref linkend="m_with-terminal-input"/></member>
2840            </simplelist>
2841          </refsect1>
2842
2843          <refsect1>
2844            <title>Notes</title>
2845
2846            <para><varname>result</varname> should probably be interpreted
2847              and acted on by <function>wait-on-semaphore</function>, because
2848              it is not likely to be meaningful to a lisp program, and the
2849              most common cause of failure is a type error.</para>
2850          </refsect1>
2851    </refentry>
2852
2853    <refentry id="f_timed-wait-on-semaphore">
2854          <indexterm zone="f_timed-wait-on-semaphore">
2855            <primary>timed-wait-on-semaphore</primary>
2856          </indexterm>
2857
2858          <refnamediv>
2859            <refname>TIMED-WAIT-ON-SEMAPHORE</refname>
2860            <refpurpose>Waits until the given semaphore has a positive
2861              count which can be atomically decremented, or until a timeout
2862              expires.</refpurpose>
2863            <refclass>Function</refclass>
2864          </refnamediv>
2865
2866          <refsynopsisdiv>
2867            <synopsis><function>timed-wait-on-semaphore</function>
2868              semaphore timeout => result</synopsis>
2869          </refsynopsisdiv>
2870
2871          <refsect1>
2872            <title>Arguments and Values</title>
2873           
2874            <variablelist>
2875              <varlistentry>
2876                <term>semaphore</term>
2877                <listitem>
2878                      <para>An object of type CCL:SEMAPHORE.</para>
2879                </listitem>
2880              </varlistentry>
2881              <varlistentry>
2882                <term>timeout</term>
2883                <listitem>
2884                      <para>a time interval in seconds.  May be any
2885                        non-negative real number the <function>floor</function> of
2886                        which fits in 32 bits.  The default is 1.</para>
2887                </listitem>
2888              </varlistentry>
2889              <varlistentry>
2890                <term>result</term>
2891                <listitem>
2892                      <para>T if <function>timed-wait-on-semaphore</function>
2893                        returned because it was able to decrement the count of
2894                        <varname>semaphore</varname>; NIL if it returned because
2895                        the duration <varname>timeout</varname> has been
2896                        exceeded.</para>
2897                </listitem>
2898              </varlistentry>
2899            </variablelist>
2900          </refsect1>
2901
2902          <refsect1>
2903            <title>Description</title>
2904
2905            <para>Waits until <varname>semaphore</varname>
2906              has a positive count that can be
2907              atomically decremented, or until the duration
2908              <varname>timeout</varname> has
2909              elapsed.</para>
2910          </refsect1>
2911
2912          <refsect1>
2913            <title>See Also</title>
2914           
2915            <simplelist type="inline">
2916              <member><xref linkend="f_make-semaphore"/></member>
2917              <member><xref linkend="f_wait-on-semaphore"/></member>
2918              <member><xref linkend="f_make-lock"/></member>
2919              <member><xref linkend="f_make-read-write-lock"/></member>
2920              <member><xref linkend="f_process-input-wait"/></member>
2921              <member><xref linkend="f_process-output-wait"/></member>
2922              <member><xref linkend="m_with-terminal-input"/></member>
2923            </simplelist>
2924          </refsect1>
2925    </refentry>
2926
2927    <refentry id="f_process-input-wait">
2928          <indexterm zone="f_process-input-wait">
2929            <primary>process-input-wait</primary>
2930          </indexterm>
2931
2932          <refnamediv>
2933            <refname>PROCESS-INPUT-WAIT</refname>
2934            <refpurpose>Waits until input is available on a given
2935              file-descriptor.</refpurpose>
2936            <refclass>Function</refclass>
2937          </refnamediv>
2938
2939          <refsynopsisdiv>
2940            <synopsis><function>process-input-wait</function>
2941              fd &optional; timeout</synopsis>
2942          </refsynopsisdiv>
2943
2944          <refsect1>
2945            <title>Arguments and Values</title>
2946           
2947            <variablelist>
2948              <varlistentry>
2949                <term>fd</term>
2950                <listitem>
2951                      <para>a file descriptor, which is a non-negative integer
2952                        used by the OS to refer to an open file, socket, or similar
2953                        I/O connection.  See <xref linkend="f_stream-device"/>.</para>
2954                </listitem>
2955              </varlistentry>
2956              <varlistentry>
2957                <term>timeout</term>
2958                <listitem>
2959                      <para>either NIL or a time interval in milliseconds.  Must be a non-negative integer.  The default is NIL.</para>
2960                </listitem>
2961              </varlistentry>
2962            </variablelist>
2963          </refsect1>
2964
2965          <refsect1>
2966            <title>Description</title>
2967
2968            <para>Wait until input is available on <varname>fd</varname>.
2969              This uses the <function>select()</function> system call, and is
2970              generally a fairly
2971              efficient way of blocking while waiting for input. More
2972              accurately, <function>process-input-wait</function>
2973              waits until it&#39;s possible to read
2974              from fd without blocking, or until <varname>timeout</varname>, if
2975              it is not NIL, has been exceeded.</para>
2976
2977            <para>
2978              Note that it&#39;s possible to read without blocking if
2979              the file is at its end - although, of course, the read will
2980              return zero bytes.</para>
2981          </refsect1>
2982         
2983          <refsect1>
2984            <title>See Also</title>
2985           
2986            <simplelist type="inline">
2987              <member><xref linkend="f_make-lock"/></member>
2988              <member><xref linkend="f_make-read-write-lock"/></member>
2989              <member><xref linkend="f_make-semaphore"/></member>
2990              <member><xref linkend="f_process-output-wait"/></member>
2991              <member><xref linkend="m_with-terminal-input"/></member>
2992            </simplelist>
2993          </refsect1>
2994
2995          <refsect1>
2996            <title>Notes</title>
2997
2998            <para>
2999              <function>process-input-wait</function> has a timeout parameter,
3000              and
3001              <xref linkend="f_process-output-wait"/> does not.  This
3002              inconsistency should probably be corrected.
3003            </para>
3004          </refsect1>
3005    </refentry>
3006
3007    <refentry id="f_process-output-wait">
3008          <indexterm zone="f_process-output-wait">
3009            <primary>process-output-wait</primary>
3010          </indexterm>
3011
3012          <refnamediv>
3013            <refname>PROCESS-OUTPUT-WAIT</refname>
3014            <refpurpose>Waits until output is possible on a given file
3015              descriptor.</refpurpose>
3016            <refclass>Function</refclass>
3017          </refnamediv>
3018
3019          <refsynopsisdiv>
3020            <synopsis><function>process-output-wait</function>
3021              fd  &optional; timeout</synopsis>
3022          </refsynopsisdiv>
3023
3024          <refsect1>
3025            <title>Arguments and Values</title>
3026           
3027            <variablelist>
3028              <varlistentry>
3029                <term>fd</term>
3030                <listitem>
3031                      <para>a file descriptor, which is a non-negative integer
3032                        used by the OS to refer to an open file, socket, or similar
3033                        I/O connection.  See <xref linkend="f_stream-device"/>.</para>
3034                </listitem>
3035              </varlistentry>
3036              <varlistentry>
3037                <term>timeout</term>
3038                <listitem>
3039                      <para>either NIL or a time interval in milliseconds.  Must be a non-negative integer.  The default is NIL.</para>
3040                </listitem>
3041              </varlistentry>
3042            </variablelist>
3043          </refsect1>
3044
3045          <refsect1>
3046            <title>Description</title>
3047
3048            <para>Wait until output is possible on <varname>fd</varname> or until <varname>timeout</varname>, if
3049              it is not NIL, has been exceeded.
3050              This uses the <function>select()</function> system call, and is
3051              generally a fairly
3052              efficient way of blocking while waiting to output.</para>
3053
3054            <para>If <function>process-output-wait</function> is called on
3055              a network socket which has not yet established a connection, it
3056              will wait until the connection is established.  This is an
3057              important use, often overlooked.</para>
3058          </refsect1>
3059
3060          <refsect1>
3061            <title>See Also</title>
3062           
3063            <simplelist type="inline">
3064              <member><xref linkend="f_make-lock"/></member>
3065              <member><xref linkend="f_make-read-write-lock"/></member>
3066              <member><xref linkend="f_make-semaphore"/></member>
3067              <member><xref linkend="f_process-input-wait"/></member>
3068              <member><xref linkend="m_with-terminal-input"/></member>
3069            </simplelist>
3070          </refsect1>
3071
3072          <refsect1>
3073            <title>Notes</title>
3074
3075            <para>
3076              <xref linkend="f_process-input-wait"/> has a timeout parameter,
3077              and
3078              <function>process-output-wait</function> does not.  This
3079              inconsistency should probably be corrected.
3080            </para>
3081          </refsect1>
3082    </refentry>
3083
3084    <refentry id="m_with-terminal-input">
3085          <indexterm zone="m_with-terminal-input">
3086            <primary>with-terminal-input</primary>
3087          </indexterm>
3088
3089          <refnamediv>
3090            <refname>WITH-TERMINAL-INPUT</refname>
3091            <refpurpose>Executes its body in an environment with exclusive
3092              read access to the terminal.</refpurpose>
3093            <refclass>Macro</refclass>
3094          </refnamediv>
3095
3096          <refsynopsisdiv>
3097            <synopsis><function>with-terminal-input</function>
3098              &body; body => result</synopsis>
3099          </refsynopsisdiv>
3100
3101          <refsect1>
3102            <title>Arguments and Values</title>
3103           
3104            <variablelist>
3105              <varlistentry>
3106                <term>body</term>
3107                <listitem>
3108                      <para>an implicit progn.</para>
3109                </listitem>
3110              </varlistentry>
3111              <varlistentry>
3112                <term>result</term>
3113                <listitem>
3114                      <para>the primary value returned by
3115                        <varname>body</varname>.</para>
3116                </listitem>
3117              </varlistentry>
3118            </variablelist>
3119          </refsect1>
3120
3121          <refsect1>
3122            <title>Description</title>
3123
3124            <para>Requests exclusive read access to the standard terminal
3125              stream, <varname>*terminal-io*</varname>.  Executes
3126              <varname>body</varname> in an environment with that access.
3127            </para>
3128          </refsect1>
3129
3130          <refsect1>
3131            <title>See Also</title>
3132           
3133            <simplelist type="inline">
3134              <member><xref
3135                         linkend="v_request-terminal-input-via-break"/></member>
3136              <member><xref linkend="cmd_y"/></member>
3137              <member><xref linkend="f_make-lock"/></member>
3138              <member><xref linkend="f_make-read-write-lock"/></member>
3139              <member><xref linkend="f_make-semaphore"/></member>
3140              <member><xref linkend="f_process-input-wait"/></member>
3141              <member><xref linkend="f_process-output-wait"/></member>
3142            </simplelist>
3143          </refsect1>
3144    </refentry>
3145
3146    <refentry id="v_request-terminal-input-via-break">
3147          <indexterm zone="v_request-terminal-input-via-break">
3148            <primary>request-terminal-input-via-break</primary>
3149          </indexterm>
3150
3151          <refnamediv>
3152            <refname>*REQUEST-TERMINAL-INPUT-VIA-BREAK*</refname>
3153            <refpurpose>Controls how attempts to obtain ownership of
3154              terminal input are made.</refpurpose>
3155            <refclass>Variable</refclass>
3156          </refnamediv>
3157
3158          <refsect1>
3159            <title>Value Type</title>
3160
3161            <para>A boolean.</para>
3162          </refsect1>
3163
3164          <refsect1>
3165            <title>Initial Value</title>
3166           
3167            <para>NIL.</para>
3168          </refsect1>
3169
3170          <refsect1>
3171            <title>Description</title>
3172
3173            <para>Controls how attempts to obtain ownership of terminal input
3174              are made. When NIL, a message is printed on *TERMINAL-IO*;
3175              it's expected that the user will later yield
3176              control of the terminal via the :Y toplevel command. When T, a
3177              BREAK condition is signaled in the owning process; continuing from
3178              the break loop will yield the terminal to the requesting process
3179              (unless the :Y command was already used to do so in the break
3180              loop.)</para>
3181          </refsect1>
3182
3183          <refsect1>
3184            <title>See Also</title>
3185           
3186            <simplelist type="inline">
3187              <member><xref linkend="m_with-terminal-input"/></member>
3188              <member><xref linkend="cmd_y"/></member>
3189              <member><xref linkend="f_make-lock"/></member>
3190              <member><xref linkend="f_make-read-write-lock"/></member>
3191              <member><xref linkend="f_make-semaphore"/></member>
3192              <member><xref linkend="f_process-input-wait"/></member>
3193              <member><xref linkend="f_process-output-wait"/></member>
3194            </simplelist>
3195          </refsect1>
3196    </refentry>
3197
3198    <refentry id="cmd_y">
3199          <indexterm zone="cmd_y">
3200            <primary>:y</primary>
3201          </indexterm>
3202
3203          <refnamediv>
3204            <refname>:Y</refname>
3205            <refpurpose>Yields control of terminal input to a specified
3206              lisp process (thread).</refpurpose>
3207            <refclass>Toplevel Command</refclass>
3208          </refnamediv>
3209
3210          <refsynopsisdiv>
3211            <synopsis>(<function>:y</function> p)</synopsis>
3212          </refsynopsisdiv>
3213
3214          <refsect1>
3215            <title>Arguments and Values</title>
3216
3217            <variablelist>
3218              <varlistentry>
3219                <term>p</term>
3220                <listitem>
3221                      <para>a lisp process (thread), designated either by
3222                        an integer which matches its
3223                        <function>process-serial-number</function>,
3224                        or by a string which is <function>equal</function> to
3225                        its <function>process-name</function>.</para>
3226                </listitem>
3227              </varlistentry>
3228            </variablelist>
3229          </refsect1>
3230
3231          <refsect1>
3232            <title>Description</title>
3233
3234            <para>:Y is a toplevel command, not a function.  As such, it
3235              can only be used interactively, and only from the initial
3236              process.</para>
3237
3238            <para>The command yields control of terminal input to the
3239              process <varname>p</varname>, which must have used
3240              <xref linkend="m_with-terminal-input"/> to request access to the
3241              terminal input stream.</para>
3242          </refsect1>
3243
3244          <refsect1>
3245            <title>See Also</title>
3246           
3247            <simplelist type="inline">
3248              <member><xref linkend="m_with-terminal-input"/></member>
3249              <member><xref
3250                         linkend="v_request-terminal-input-via-break"/></member>
3251              <member><xref linkend="f_make-lock"/></member>
3252              <member><xref linkend="f_make-read-write-lock"/></member>
3253              <member><xref linkend="f_make-semaphore"/></member>
3254              <member><xref linkend="f_process-input-wait"/></member>
3255              <member><xref linkend="f_process-output-wait"/></member>
3256            </simplelist>
3257          </refsect1>
3258    </refentry>
3259
3260  </sect1>
3261</chapter>
Note: See TracBrowser for help on using the repository browser.