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

Last change on this file since 8820 was 8820, checked in by jaj, 12 years ago

This commit includes support for docbook 4.5, stylesheet changes, and updated documentation.

In order to support docbook 4.5 in nXML mode, I have added a new directory called docbook-rng-4.5 and changed schemas.xml to point to it. This should just work when editing the documentation in EMACS.

The two most obvious changes to the stylesheets are that the table of contents for each chapter now occurs at the beginning of the chapter, and the format for refentries is cleaner and more concise.

I think that we should consistently use refentry elements for all of the definitions of functions, macros, variables, etc. This retains the structured data for the definitions that can be reformatted to have different appearences by the stylesheets. We should also consistently use other docbook elements such as function and varname. I'm not really happy with their appearance right now, but that can be easily tweaked in the stylesheets as long as they are consistently used throughout the documentation.

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