source: trunk/source/doc/src/04-threads.xml @ 8567

Last change on this file since 8567 was 8567, checked in by rme, 13 years ago

Break up monolithic openmcl-documentation.xml file into chapters. Add file
top.xml, which includes all the chapters via xi:xinclude.

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