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

Last change on this file since 8606 was 8606, checked in by gb, 13 years ago

Rename chapter-level files to not include chapter numbers (so that it'd be
less confusing to change chapter order, remove/introduce chapters, etc.)

Ensure that all chapter-level files have ENTITY definitions in their
DOCTYPE forms.

Define a CCL entity (currently just <literal>CCL</literal>; change all
references to "OpenMCL" to "&CCL;"

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