This is bigloo.info, produced by makeinfo version 4.5 from bigloo.texi.

  This file documents Bigloo, an implementation of an extended version
of the Scheme programming language.

  Copyright (C) 1992-99, 2000-02 Manuel Serrano

     This program is free software; you can redistribute it
     and/or modify it under the terms of the GNU General Public
     License as published by the Free Software Foundation; either
     version 2 of the License, or (at your option) any later version.
     
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public
     License along with this program; if not, write to the Free
     Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
     MA 02111-1307, USA.

INFO-DIR-SECTION The Algorithmic Language Scheme
START-INFO-DIR-ENTRY
* bigloo: (bigloo).            The Bigloo Scheme compiler
END-INFO-DIR-ENTRY


File: bigloo.info,  Node: Programming with Fair threads,  Next: Fair Threads Api,  Prev: Introduction,  Up: Threads

Programming with Fair threads
=============================

  All ports of Bigloo JVM back-end (see *Note Compiler Description::)
support Fair threads. Only few ports of Bigloo native back-end support
Fair threads.  Please refer to the installation documentation (file
INSTALL) to check which native ports support Fair threads.

  Fair threads are available by the mean of a Bigloo library. That is,
when compiling and linking with threads, it is required to use a
`library' module clause (see *Note Module Declaration::) such as:

     (module http-server
       (library fthread)
       ...)

  When the Fair thread library is deployed the `cond-expand' form (see
*Note SRFIs::) evaluate `fthread' and `SRFI-18' clauses.

  For the sake of the example we present in this section a small web
server implemented with Fair threads. This server only supports Http
`GET' request but it supports concurrent requests. That is, the server
is able to server several clients simultaneously.

  First, the server needs to create a `socket' server (see the *Note
Socket:: documentation):

     (define (start-http-server)
        (let ((s (make-server-socket)))
           (print "Http server started: " (socket-port-number s))
           s))

  Then a Fair thread implementing the web server is created and ran:

     (let* ((svr (start-http-server))
            (thd (make-thread (make-http-server svr) 'http-server))
            (ts (thread-start! thd)))
        (scheduler-start!)
        (fprint (current-error-port) "Shuting down http server...")
        (socket-shutdown svr))

  The functions `make-thread' and `thread-start!'  (see Section *Note
Thread::) start the execution of a new thread.  The function
`scheduler-start!' (see Section *Note Scheduler::) manages the
execution of all threads.

  The body of the server is a thunk, created by the `make-http-server'
function. Its definition is:

     (define (make-http-server s::socket)
        (lambda ()
           (let loop ()
     	 (let ((s2 (thread-await! (make-accept-signal s))))
     	    (thread-start! (make-thread (lambda () (http-eval s2))))
     	    (thread-yield!)
     	    (loop)))))

  The function `thread-await!' waits for a connection to the socket
server S2. This blocks the current thread but it does not block the
scheduler and the execution of other threads in it. That is, when the
thread running the http server waits for a connection to the socket
server, the other threads started in the scheduler keep executing. When
a connection is established, a new thread is created that evaluates
(`http-eval') the request. When this thread is started the http server
cooperates (`thread-yield!').

     (define (http-eval s::socket)
        (define (readline)
           (thread-await! (make-input-signal (socket-input s)
                                             '(#\Newline #\Return))))
        (let* ((lines (let loop ((line (readline)))
     		    (thread-yield!)
     		    (if (and (string? line) (=fx (string-length line) 1))
     			'()
     			(cons (substring line 0 (-fx (string-length line) 1))
     			      (loop (readline))))))
     	  (line (car lines)))
           (http-get "index.html" s)
           (socket-close s)))

  The client request is first read. This is done using the non blocking
form of input `(thread-await! (make-input-signal (socket-input s)
'(#\Newline #\Return)))'.  This blocks the current thread until a
character `#\Newline' or `#\Return' is read. Then, the value of that
call is either the "end of file" object or the a string of characters.

  Each time a line is read, the thread cooperates (`thread-yield!').
The explanation is the same as for the socket connection. Without this
explicit cooperation, the call to `thread-await!' would always return
the same string of characters.

  At this point, let us suppose that we want our web server able to
serve HTML, Shell and Scheme pages. For this `http-get' looks at the
suffix of the file to be downloaded:

     (define (http-get fname s::socket)
        (case (string->symbol (suffix fname)
           ((scm)
            (http-get-scm fname s))
           ((sh)
            (http-get-sh fname s))
           (else
            (http-get-html fname s)))))

  For the first two requests, a new process is spawned. For the last
one, a file is opened:

     (define (http-get-scm file s::socket)
        (let ((proc (run-process "bigloo" "-i" "-s" file output: pipe:)))
           (http-get-input (process-output-port proc) s)))
     
     (define (http-get-sh file s::socket)
        (let ((proc (run-process "sh" "-f" file output: pipe:)))
           (http-get-input (process-output-port proc) s)))
     
     (define (http-get-html fname s::socket)
        (if (file-exists? fname)
            (let ((p (open-input-file fname)))
     	  (http-get-input p s)
     	  (close-input-port p))
            (http-reply s "plain" "Can't find file \"" fname "\"")))

  The function `http-get-input' reads all the characters from an input
port.

     (define (http-get-input p::input-port s::socket)
        (let loop ((res '()))
           (let ((v (thread-await! (make-input-signal p 1024))))
     	 (thread-yield!)
     	 (if (eof-object? v)
     	     (apply http-reply s "html" (reverse! res))
                  (loop (cons v res))))))

  It must be noted here that since the characters are read with
`thread-await!' which does not block the scheduler, while a client
request is being processed, the scheduler is able to handle
_simultaneously_ other requests. The form `(thread-await!
(make-input-signal p 1024))' blocks the current thread until at most
`1024' characters have been read from input port P.

  The function `http-reply' simply writes a list of strings to the
output port associated with the socket connection:

     (define (http-reply socket::socket kind . str)
        (let ((p (socket-output socket)))
           (thread-await! (make-output-signal p "HTTP/1.0 200 Ok\r
     Server: test_httpd/%x\r
     Connection: close\r
     Content-type: text/"))
           (thread-await! (make-output-signal p kind))
           (thread-await! (make-output-signal p "\r\n\r\n"))
           (for-each (lambda (s) (thread-await! (make-output-signal p s))) str)
           (thread-await! (make-output-signal p "\r\n"))))


File: bigloo.info,  Node: Fair Threads Api,  Next: SRFI-18,  Prev: Programming with Fair threads,  Up: Threads

Fair Threads Api
================

* Menu:

* Thread::
* Scheduler::
* Signal::

  Bigloo uses a set of _primitive_ functions to create, run and handle
thread. For the sake of standardization the name and semantic of
SRFI-18 (Multithreading support) has been used. This section presents
only the mandatory functions to program with Fair threads in Bigloo. The
Section *Note SRFI-18:: presents the functions that are not necessary
to Bigloo but supported for compliance with SRFI-18.


File: bigloo.info,  Node: Thread,  Next: Scheduler,  Up: Fair Threads Api

Thread
------

 - SRFI-18 function: current-thread
     Returns the current thread.

 - SRFI-18 function: thread? OBJ
     Returns `#t' if OBJ is a thread, otherwise returns `#f'.

 - SRFI-18 function: make-thread THUNK [NAME]
     Returns a new thread which is not started yet. The body of the
     thread is the body of the procedure THUNK. The optional argument
     NAME can be use to identify the thread. It can be any Bigloo value.

          (make-thread (lambda () (print 1) (thread-yield!) (print 2)) 'my-thread)

 - SRFI-18 function: thread-start! THREAD [SCHEDULER]
     Runs a thread created with `make-thread'. If SCHEDULER is
     provided, the THREAD is started this particular scheduler.
     Otherwise, it is started in the current scheduler (see Section
     *Note Scheduler::).  Threads are started at the beginning of
     _reactions_ (see Section *Note Scheduler::).

 - SRFI-18 function: thread-name THREAD
     Returns the name of the THREAD that has been passed to
     `make-thread'.

 - SRFI-18 function: thread-specific THREAD
 - SRFI-18 function: thread-specific-set! THREAD OBJ
     Returns and sets value in the specific field of the THREAD. If no
     value has been set, `thread-specific' returns an unspecified value.

          (let ((t (make-thread (lambda ()
                                   (print (thread-specific (current-thread)))))))
             (thread-specific-set! t 'foo)
             (thread-start! t)) -| foo

 - Bigloo function: thread-cleanup THREAD
 - Bigloo function: thread-cleanup-set! THREAD FUN
     Associates a cleanup function to a thread. The cleanup function is
     called with the result value of the thread. The cleanup function
     is executed in a context where `current-thread' is the thread
     owning the cleanup function.

          (let ((t (make-thread (lambda () 'done) 'foo)))
             (thread-cleanup-set! t (lambda (v) (print (thread-name (current-thread))
          					     ", exit value: " v)))
             (thread-start! t)) -| foo, exit value: done

 - SRFI-18 function: thread-yield!
     The current thread _cooperates_. That is, it is suspend for the
     _reaction_ and the scheduler selects a new thread to be resumed.
     The scheduler resumes the next avaliable thread. If there is only
     one thread started in the scheduler, the same thread is resumed.
     A _reaction_ correspond to the invocation of a `scheduler-react!'
     call (see Section *Note Scheduler::).


 - SRFI-18 function: thread-sleep! TIMEOUT
     The current thread _cooperates_ during _exactly_ TIMEOUT
     _reactions_ (see *Note Scheduler::). It is suspended and the
     scheduler selects a new thread to be resumed. If there is only one
     thread started in the scheduler, the same thread will be resumed.

          (let ((t1 (make-thread
                     (lambda () (thread-sleep! 2) (display 'foo))))
                (t2 (make-thread
                     (lambda () (let loop ((n 1))
                                   (display n)
                                   (thread-yield!)
                                   (if (< n 5)
                                       (loop (+ n 1))))))))
             (thread-start! t1)
             (thread-start! t2)
             (scheduler-start!)) -| 12foo34

 - SRFI-18 function: thread-terminate! THREAD
     Terminates THREAD at the end of the current reaction.

 - SRFI-18 function: thread-join! THREAD [TIMEOUT [TIMEOUT-VAL]]
     The current thread waits until the THREAD terminates or until the
     TIMEOUT is reached (when supplied). If the TIMEOUT is reached,
     `thread-join!' returns TIMEOUT-VAL. If THREAD terminates,
     `thread-join!' returns the end-result of the THREAD or the
     end-exception if that thread terminates abnormally.

     If several threads wait for the termination of the same thread,
     they are all notified of the termination during the current
     reaction.

          (let* ((t1 (thread-start!
          	    (make-thread (lambda ()
          			    (thread-sleep! 3)
          			    'foo))))
                 (t2 (thread-start!
          	    (make-thread (lambda ()
          			    (print "t1: " (thread-join! t1 1))))))
                 (t3 (thread-start!
          	    (make-thread (lambda ()
          			    (print "t2: " (thread-join! t1 2 'bar))))))
                 (t3 (thread-start!
          	    (make-thread (lambda ()
          			    (print "t3: " (thread-join! t1))))))
                 (t4 (thread-start!
          	    (make-thread (lambda ()
          			    (print "t4: " (thread-join! t1)))))))
             (scheduler-start!))
             -| t1: #|%uncaught-exception [reason: (exception . join-timeout)]|
                t2: bar
                t3: foo
                t4: foo

 - Bigloo function: thread-suspend! THREAD
 - Bigloo function: thread-resume! THREAD
     Suspends/resumes the THREAD at the end of reaction. While suspended
     a thread is not eligible to get the processor by the scheduler.

 - Bigloo function: thread-await! SIGNAL [TIMEOUT]
     Blocks the thread until SIGNAL has been broadcast or until TIMEOUT
     is elapsed. The function `thread-await!' returns the list of
     values associated with the previous emissions of the signal that
     took place during the reaction.

          (let ((t1 (thread-start!
                     (make-thread
                      (lambda ()
                       (display (thread-await! 'foo))
                       (display (thread-await! 'bar))))))
                (t2 (thread-start!
                     (make-thread
                      (lambda ()
                       (broadcast! 'foo 'val1-foo)
                       (broadcast! 'foo 'val2-foo)))))
                (t3 (thread-start!
                     (make-thread
                      (lambda ()
                       (thread-sleep! 2)
                       (broadcast! 'bar 'val-bar))))))
             (let loop ((n 1))
                (display n)
                (scheduler-react! (current-scheduler))
                (loop (+ n 1))))
            -| 1(val2-foo2 val1-fo)234(val-bar)456...

     In general `thread-await!' cannot be used to intercept all the
     signals broadcasted during a reaction. This is illustrated by the
     following example were obviously `thread-await!' cannot intercept
     the emission of the signal:

          (thread-start! (make-thread (lambda ()
                                         (tread-await! 'foo)
                                         (broadcast! 'foo 1))))
          (thread-start! (make-thread (lambda ()
                                         (broadcast! 'foo 2))))

 - Bigloo function: thread-get-values! SIGNAL
     Terminates the instant for the thread (as `thread-yield!') and
     returns, hence at the next instant, all the values associated with
     broadcast SIGNAL (see Section *Note Signal::) during the previous
     scheduler reaction (see Section *Note Scheduler::).

     Example:
          (thread-start! (make-thread
                            (lambda ()
                               (for-each print (thread-get-values! 'foo)))))
          (thread-start! (make-thread
                            (lambda ()
                               (broadcast! 'foo 1)
                               (broadcast! 'foo 'foo)
                               (broadcast! 'foo "blabla"))))
             -| 1
                foo
                blabla

     Example:
          (let ((t1 (thread-start!
                     (make-thread
                      (lambda ()
                         (for-each print (thread-get-values! 'foo)))
                      't1)))
                (t2 (thread-start!
                     (make-thread
                      (lambda ()
                         (broadcast! 'foo (current-thread))
                         (thread-yield!)
                         ;; this second broadcast won't be intercepted
                         ;; because it occurs during the next reaction
                         (broadcast! 'foo (current-thread)))
                      't2)))
                (t3 (thread-start!
                     (make-thread
                      (lambda ()
                         (broadcast! 'foo (current-thread))
                         (broadcast! 'foo (current-thread)))
                      't3))))
             (scheduler-start!))
             -| #<thread:t2>
                #<thread:t3>
                #<thread:t3>

 - Bigloo function: thread-await-values! SIGNAL [TIMEOUT]
     This blocks the current thread until SIGNAL has been broadcast.
     It then returns, at the next instant, all the values associated
     with all the broadcasts that took place during the instant.  It
     can be defined as:

          (define (thread-await-values! signal . tmt)
             (apply thread-await! signal tmt)
             (thread-get-values signal))

 - Bigloo function: thread-await*! SIGNALS [TIMEOUT]
     Wait for one of a list of signals. The function `thread-await*!'
     can be compared to the Unix `select' function. The argument
     SIGNALS is a list of signal identifier. The function
     `thread-await*!' blocks the current thread until one of the signal
     in the list SIGNALS is broadcast or until the optional numerical
     argument TIMEOUT is elapsed. If the thread unblocks because the
     timeout is elapsed, `thread-await*!' returns `#f'. Otherwise it
     returns two values that have to be collected with
     `multiple-value-bind' (see *Note Control Features::). The first
     one is the value of the broadcast signal. The second one is the
     broadcast signal.

     Example:
          (let ((res #f))
             (thread-start!
              (make-thread (lambda ()
                              (let ((sig* (list 'foo 'bar)))
                                 (multiple-value-bind (val1 sig1)
                                    (thread-await*! sig*)
                                    (multiple-value-bind (val2 sig2)
                                       (thread-await*! sig*)
                                       (thread-yield!)
                                       (multiple-value-bind (val3 sig3)
                                          (thread-await*! sig*)
                                          (set! res (list sig1 sig2 sig3)))))))))
             (thread-start!
              (make-thread (lambda ()
                              (thread-sleep! 2)
                              (broadcast! 'foo 1))))
             (thread-start!
              (make-thread (lambda ()
                              (thread-sleep! 3)
                              (broadcast! 'bar 2))))
             (scheduler-start!)
             res)
            => '(foo foo bar)

     A second example using timeouts:
          (let ((res #f))
             (thread-start!
              (make-thread (lambda ()
                              (let ((sig* (list 'foo 'bar)))
                                 (multiple-value-bind (val1 sig1)
                                    (thread-await*! sig* 1)
                                    (thread-yield!)
                                    (multiple-value-bind (val2 sig2)
                                       (thread-await*! sig* 1)
                                       (thread-yield!)
                                       (multiple-value-bind (val3 sig3)
                                          (thread-await*! sig* 2)
                                          (set! res (list sig1 sig2 sig3)))))))))
             (thread-start!
              (make-thread (lambda ()
                              (thread-sleep! 2)
                              (broadcast! 'foo 1))))
             (thread-start!
              (make-thread (lambda ()
                              (thread-sleep! 3)
                              (broadcast! 'bar 2))))
             (scheduler-start!)
             res)
            => '(#f foo bar)

 - Bigloo function: thread-get-values*! SIGNALS
     Terminates the instant for the thread (as `thread-yield!') and
     returns, hence at the next instant, all the values associated with
     all broadcast SIGNALS (see Section *Note Signal::) during the
     previous scheduler reaction (see Section *Note Scheduler::). The
     function `thread-get-values*!' returns an _alist_ made of the
     scanned signal and there values. That is the length of the returns
     list is the length of the list SIGNALS. If a signal of the list
     SIGNALS has not been broadcast, its associated entry the list
     returned by `thread-get-values*!' has an empty `cdr'.

     Example:
          (let ((s1 'foo)
                (s2 'bar)
                (s3 'gee)
                (res #f))
             (thread-start!
              (make-thread (lambda ()
                              (thread-sleep! 2)
                              (broadcast! 'foo (current-time))
                              (broadcast! 'bar 0))))
             (thread-start!
              (make-thread (lambda ()
                              (thread-await*! (list s1 s2 s3))
                              (set! res (thread-get-values*! (list s1 s2 s3))))))
             (thread-start!
              (make-thread (lambda ()
                              (thread-sleep! 2)
                              (broadcast! 'bar (current-time)))))
             (scheduler-start!)
             res)
            => ((foo 3) (bar 3 0) (gee))

     Used with asynchronous signal, the functions `thread-await*!' and
     `thread-get-values*!' can be used to read concurrently, in a non
     blocking way, several files.

 - Bigloo function: thread-await-values*! SIGNALS [TIMEOUT]
     This blocks the current thread until at least one of SIGNALS has
     been broadcast. It then returns, at the next instant, all the
     values associated with all the broadcasts that took place during
     the instant. It can be defined as:

          (define (thread-await-values*! signal . tmt)
             (apply thread-await*! signal tmt)
             (thread-get-values* signal))


File: bigloo.info,  Node: Scheduler,  Next: Signal,  Prev: Thread,  Up: Fair Threads Api

Scheduler
---------

 - Bigloo function: make-scheduler [ENVS]
     Creates a new scheduler. The optional arguments ENVS are _fair
     thread environments_ which will be defined in forthcoming Bigloo
     releases.

 - Bigloo function: scheduler? OBJ
     Returns `#t' if OBJ is a scheduler. Otherwise returns `#f'.

 - Bigloo function: current-scheduler
     Returns the current scheduler. The current scheduler is the
     scheduler used in the last call to `scheduler-react!' or
     `scheduler-start!'.  It always exists a current scheduler. That
     is, it is optional for an application to create a scheduler.

 - Bigloo function: scheduler-react! [SCHEDULER]
     Executes all the treads started (see `thread-start!', Section
     *Note Thread::) in the scheduler until all the threads are
     blocked. A thread is blocked if the has explicitly yield the
     processor (`thread-yield!' and `thread-sleep!') or because it is
     waiting a signal (`thread-await!'). A thread can be selected
     several times during the same reaction.  The function
     `scheduler-react!' returns a symbol denoting the _state_ of the
     scheduler. The possible states are:

        * `ready' The Scheduler is ready to execute some threads.

        * `done' All the threads started in the scheduler have
          terminated.

        * `await' All the threads  started in the scheduler are waiting
          for       a signal.

     An invocation of `scheduler-react!' is called a _reaction_.

 - Bigloo function: scheduler-start! [ARG [SCHEDULER]]
     Executes `scheduler-react!' as long as the scheduler is not done.
     If the optional argument SCHEDULER is not provided,
     `scheduler-start!' uses the current scheduler (see
     `current-scheduler'). The optional ARG can either be:
        * An integer standing for the number of times `scheduler-react!'
               must be called.

        * A procedure F of one argument. The procedure F       is
          invoked after each reaction. It is passed a value I which is
              the iteration number of the scheduler. The reactions of
          the scheduler       are stopped when F returns `#f'.

          (let* ((s (make-scheduler))
                 (t (make-thread (lambda ()
                                    (let loop ((n 0))
                                       (display n)
                                       (thread-yield!)
                                       (loop (+ 1 n)))))))
             (scheduler-start! 10 s))
            -| 0123456789
          
          (let* ((s (make-scheduler))
                 (t (make-thread (lambda ()
                                    (let loop ((n 0))
                                       (display n)
                                       (thread-yield!)
                                       (loop (+ 1 n)))))))
             (scheduler-start! (lambda (i) (read-char)) s))
            -| 0123456789

 - Bigloo function: scheduler-terminate! [SCHEDULER]
     Terminates all the threads in SCHEDULER.

 - Bigloo function: scheduler-instant [SCHEDULER]
     Returns the current reaction number of SCHEDULER. The reaction
     number is the number of times `scheduler-react!' has been invoked
     passing SCHEDULER as argument.


File: bigloo.info,  Node: Signal,  Prev: Scheduler,  Up: Fair Threads Api

Signal
------

 - Bigloo function: broadcast! SIGNAL [VAL]
     Broadcasts SIGNAL to all threads started in SCHEDULER
     _immediately_, that is during the reaction. This function can only
     be called from within a running thread. If the optional argument
     VAL is omitted, the SIGNAL is broadcast with an unspecified value.

          (thread-start! (make-thread
          		(lambda ()
          		   (thread-await! 'foo)
          		   (print (scheduler-instant (current-scheduler))))))
          (thread-start! (make-thread
          		(lambda ()
          		   (broadcast! 'foo))))
          (scheduler-start!)
            -| 1

 - Bigloo function: scheduler-broadcast! SCHEDULER SIGNAL [VAL]
     At the next react broadcasts SIGNAL to all threads started in
     SCHEDULER. This is used to impact running threads from outside any
     threads. If the optional argument VAL is omitted, the SIGNAL is
     broadcast with an unspecified value.

 - Bigloo function: make-input-signal INPUT-PORT OBJ [SCHEDULER]
     The argument OBJ can either be: a integer, a string, a pair. The
     condition for raising the signal depends on the type of OBJ.  See
     also `fair-read/rp'.

        * _integer:_ This function returns a new signal that can be
          used anywhere a signal is expected (e.g., `thread-await!').
          In addition, it spawns a asynchronous process that
          broadcasts, in SCHEDULER, the created signal when LEN
          characters are read to the INPUT-PORT. The value associated
          with the signal is either the "end of file" object when no
          more characters are available on the port or a string composed
          of the characters read on INPUT-PORT. Note that the string
          length could be lesser than LEN is less characters are
          available.

          See Section *Note Introduction:: for examples using
          `make-input-signal'.

        * _string:_ The signal is raised when the pattern OBJ is read
          on INPUT-PORT.

        * _list of strings:_ The signal is raised when one of the
          patterns in the list OBJ is read on INPUT-PORT.

        * _list of characters:_ The signal is raised when the character
          in the list OBJ is read on INPUT-PORT.

 - Bigloo function: make-send-chars-signal INPUT-PORT OUTPUT-PORT
          STRING [LEN] [SCHEDULER]
     Copies LEN characters from INPUT-PORT to OUTPUT-PORT. If the
     optional argument LEN is left empty, all the characters of
     INPUT-PORT are copied.

 - Bigloo function: make-output-signal OUTPUT-PORT STRING [SCHEDULER]
     This function behaves as `make-input-signal' expect that the
     signal is raised when the STRING is written on on OUTPUT-PORT.

 - Bigloo function: make-connect-signal SOCKET [SCHEDULER]
     This function behaves as `make-input-signal' expect that the
     signal is raised when a connection is established on SOCKET.

     The connection is established via the function
     `socket-accept-connection' See Section *Note Socket:: for the
     definition of this last function.

 - Bigloo function: make-accept-signal SOCKET [SCHEDULER]
     This function behaves as `make-input-signal' expect that the
     signal is raised when a connection is established on SOCKET. The
     socket client holding the connection is returned. If an error has
     occurred during the connection, the value `#f' is returned.

     The connection is established via the function `socket-accept'.
     See Section *Note Introduction:: for an example using
     `make-accept-signal'.  See Section *Note Socket:: for the
     definition of `make-accept-signal'.

 - Bigloo function: make-process-signal PROCESS [SCHEDULER]
     This function behaves has `make-input-signal' expect that the
     signal is raised when the PROCESS completes.

     Example:
          (thread-start! (make-thread
                          (lambda ()
                             (let* ((p (run-process "bigloo" "-i" "foo.scm"))
                                    (r (thread-await! (make-process-signal p))))
                                (print "process termination: " r)))))
          (thread-start! (make-thread
                          (lambda ()
                             ...)))

 - Bigloo function: make-sleep-signal MS [SCHEDULER]
     Sleep for at least MS microseconds.

 - Bigloo procedure: fair-read/rp GRAM PORT
     Read from the input port PORT according to the regular grammar
     GRAM. This function automatically collaborates with other threads.
     It can thus be used to implement non-blocking readings (see also
     `make-input-signal').


File: bigloo.info,  Node: SRFI-18,  Prev: Fair Threads Api,  Up: Threads

SRFI-18
=======

  Bigloo implements SRFI-18 (Multithreading support). This SRFI is
available at <http://srfi.schemers.org/srfi-18/srfi-18.html>. One
should keep in mind that since the Bigloo scheduler is cooperative
Bigloo threads must _cooperate_ at some point in order not to block the
execution of other threads. The functions enforcing cooperation are
`thread-yield!', `thread-sleep!', `thread-join!'  and `thread-await!'.
In addition the SRFI-18 `mutex-unlock' function enforce cooperation.

 - SRFI-18 function: mutex? OBJ
 - SRFI-18 function: make-mutex OBJ [NAME]
 - SRFI-18 function: mutex-name MUTEX
 - SRFI-18 function: mutex-specific MUTEX
 - SRFI-18 function: mutex-specific-set! MUTEX OBJ
 - SRFI-18 function: mutex-state MUTEX
 - SRFI-18 function: mutex-lock! MUTEX [TIMEOUT [THREAD]]
 - SRFI-18 function: mutex-unlock! MUTEX [CONDITION-VARIABLE [TIMEOUT]]
          (let ((m (make-mutex)))
             (thread-start!
              (make-thread (lambda ()
                              (let loop ()
                                 (if (mutex-lock! m 0)
                                     (begin
                                        (display "locked")
                                        (mutex-unlock! m))
                                     (begin
                                        (thread-yield!)
                                        (loop))))))))
            -| locked
          
          (let ((res '()))
             (define (mutex-lock-recursively! mutex)
                (if (eq? (mutex-state mutex) (current-thread))
                    (let ((n (mutex-specific mutex)))
                       (mutex-specific-set! mutex (+ n 1)))
                    (begin
                       (mutex-lock! mutex)
                       (mutex-specific-set! mutex 0))))
             (define (mutex-unlock-recursively! mutex)
                (let ((n (mutex-specific mutex)))
                   (if (= n 0)
                       (mutex-unlock! mutex)
                       (mutex-specific-set! mutex (- n 1)))))
             (thread-start!
              (make-thread
               (lambda ()
                  (let ((m (make-mutex)))
                     (mutex-lock-recursively! m)
                     (mutex-lock-recursively! m)
                     (mutex-lock-recursively! m)
                     (set! res (cons (mutex-specific m) res))
                     (mutex-unlock-recursively! m)
                     (mutex-unlock-recursively! m)
                     (mutex-unlock-recursively! m)
                     (set! res (cons (mutex-specific m) res))))))
             res)
            => (0 2)


 - SRFI-18 function: condition-variable? OBJ
 - SRFI-18 function: make-condition-variable [NAME]
 - SRFI-18 function: condition-variable-name CV
 - SRFI-18 function: condition-variable-specific! CV
 - SRFI-18 function: condition-variable-specific-set! CV OBJ
 - SRFI-18 function: condition-variable-signal! CV
 - SRFI-18 function: condition-variable-broadcast! CV
          (let ((res 0))
             (define (make-semaphore n)
                (vector n (make-mutex) (make-condition-variable)))
             (define (semaphore-wait! sema)
                (mutex-lock! (vector-ref sema 1))
                (let ((n (vector-ref sema 0)))
                   (if (> n 0)
                       (begin
                          (vector-set! sema 0 (- n 1))
                          (mutex-unlock! (vector-ref sema 1)))
                       (begin
                          (mutex-unlock! (vector-ref sema 1) (vector-ref sema 2))
                          (semaphore-wait! sema)))))
             (define (semaphore-signal-by! sema increment)
                (mutex-lock! (vector-ref sema 1))
                (let ((n (+ (vector-ref sema 0) increment)))
                   (vector-set! sema 0 n)
                   (if (> n 0)
                       (condition-variable-broadcast! (vector-ref sema 2)))
                   (mutex-unlock! (vector-ref sema 1))))
             (let ((sema (make-semaphore 10)))
                (let ((t1 (thread-start! (make-thread
                                          (lambda ()
                                             (semaphore-wait! sema)
                                             (set! res (current-time))))))
                      (t2 (thread-start! (make-thread
                                          (lambda ()
                                             (let loop ((n 10))
                                                (if (> n 0)
                                                    (begin
                                                       (semaphore-signal-by! sema 1)
                                                       (thread-yield!)
                                                       (loop (- n 1))))))))))
                   (scheduler-start!)
                   res)))
            => 2

 - SRFI-18 function: current-time [SCHEDULER]
     Returns the reaction number of SCHEDULER.

 - SRFI-18 function: time? OBJ
 - SRFI-18 function: time->seconds OBJ

 - SRFI-18 function: current-exception-handler
 - SRFI-18 function: with-exception-handler HANDLER THUNK
 - SRFI-18 function: raise OBJ
 - SRFI-18 function: join-timeout-exception? OBJ
 - SRFI-18 function: abandoned-mutex-exception? OBJ
 - SRFI-18 function: terminated-thread-exception? OBJ
 - SRFI-18 function: uncaught-exception? OBJ
 - SRFI-18 function: uncaught-exception-reason EXC


File: bigloo.info,  Node: Regular Parsing,  Next: Lalr Parsing,  Prev: Threads,  Up: Top

Regular parsing
***************

  Programming languages have poor reading libraries since the lexical
information that can be specified is directly tied to the structure of
the language. For example, in C it's hard to read a rational number
because there is no type rational.  Programs have been written to
circumvent this problem: Lex [Lesk75], for example, is one of them.  We
choose to incorporate in Bigloo a set of new functions to assist in such
parsing. The syntax for regular parser of Bigloo 2.0 (the one described
in this document) is not compatible with former Bigloo versions.

* Menu:

* A New Way of Reading::
* The Syntax of The Regular Parser::
* The Semantics Actions::
* Examples of Regular Grammar::


File: bigloo.info,  Node: A New Way of Reading,  Next: The Syntax of The Regular Parser,  Up: Regular Parsing

A new way of reading
====================

  There is only one way in Bigloo to read text, _regular reading_,
which is done by the new form:

 - bigloo procedure: read/rp regular-parser input-port
     The first argument is a regular parser and the second a Scheme
     port.  This way of reading is almost the same as the Lex's one.
     The reader tries to match the longest input, from the stream
     pointed to by INPUT-PORT, with one of several regular expressions
     contained in REGULAR-PARSER. If many rules match, the reader takes
     the first one defined in the grammar. When the regular rule has
     been found the corresponding Scheme expression is evaluated.

     _remark: _ The traditional `read' Scheme function is implemented
     as:
          (define-inline (read port)
             (read/rp scheme-grammar port))

 - bigloo variable: *about-to-read*
     When this variable is bound to a function, then each time the
     reader has filled its buffer, this function is called with an
     `input-port' as its argument.


File: bigloo.info,  Node: The Syntax of The Regular Parser,  Next: The Semantics Actions,  Prev: A New Way of Reading,  Up: Regular Parsing

The syntax of the regular parser
================================

  A regular parser is built by the means of the form `regular-grammar':

 - bigloo syntax: regular-grammar (binding ...) rule ...
     The BINDING and RULE are defined by the following grammar:

          <binding>  ==> (<variable> <re>)
          <rule>     ==> (<cre> <s-expression> <s-expression> ...)
                       | (<context> <re> <s-expression> <s-expresion> ...)
                       | (`else' <s-expression> <s-expression> ...)
          <cre>      ==> <re>
                       | (`context' <symbol> <re>)
                       | (`when' <s-expr> <re>)
                       | (`bol' <re>)
                       | (`eol' <re>)
                       | (`bof' <re>)
                       | (`eof' <re>)
          <re>       ==> <variable>
                       | <char>
                       | <string>
                       | (`:' <re> ...)
                       | (`or' <re> ...)
                       | (`*' <re>)
                       | (`+' <re>)
                       | (`?' <re>)
                       | (`=' <integer> <re>)
                       | (`>=' <integer> <re>)
                       | (`**' <integer> <integer> <re>)
                       | (`...' <integer> <re>)
                       | (`uncase' <re>)
                       | (`in' <cset> ...)
                       | (`out' <cset> ...)
                       | (`and' <cset> <cset>)
                       | (`but' <cset> <cset>)
                       | (`posix' <string>)
          <variable> ==> <symbol>
          <cset>     ==> <string>
                       | <char>
                       | (<string>)
                       | (<char> <char>)

     Here is a description of each construction.

    `(context <symbol> <re>)'
          This allows us to _protect_ an expression. A _protected_
          expression matches (or accepts) a word only if the parser has
          been set to the corresponding context. *Note The Semantics
          Actions::, for more details.

    `(when <s-expr> <re>)'
          This allows us to _protect_ an expression. A _protected_
          expression matches (or accepts) a word only if the evaluation
          of `<s-expr>' is `#t'. For instance,

               (define *g*
                  (let ((armed #f))
                     (regular-grammar ()
               	 ((when (not armed) (: "#!" (+ (or #\/ alpha))))
               	  (set! armed #t)
               	  (print "start [" (the-string) "]")
               	  (ignore))
               	 ((+ (in #\Space #\Tab))
               	  (ignore))
               	 (else
               	  (the-failure)))))
               
               (define (main argv)
                  (let ((port (open-input-string "#!/bin/sh #!/bin/zsh")))
                     (print (read/rp *g* port))))

    `(bol <re>)'
          Matches `<re>' at the beginning of line.

    `(eol <re>)'
          Matches `<re>' at the end of line.

    `(bof <re>)'
          Matches `<re>' at the beginning of file.

    `(eof <re>)'
          Matches `<re>' at the end of file.

    `<variable>'
          This is the name of a variable bound by a <binding>
          construction. In addition to user defined variables, some
          already exist. These are:

               all    == (out #\Newline)
               lower  == (in ("az"))
               upper  == (in ("AZ"))
               alpha  == (or lower upper)
               digit  == (in ("09"))
               xdigit == (uncase (in ("af09")))
               alnum  == (uncase (in ("az09")))
               punct  == (in ".,;!?")
               blank  == (in #" \t\n")
               space  == #\Space

          It is a error to reference a variable that it is not bound by
          a <binding>.  Defining a variable that already exists is
          acceptable and causes the former variable definition to be
          erased. Here is an example of a grammar that binds two
          variables, one called `ident' and one called `number'. These
          two variables are used within the grammar to match
          identifiers and numbers.

               (regular-grammar ((ident  (: alpha (* alnum)))
                                 (number (+ digit)))
                  (ident  (cons 'ident (the-string)))
                  (number (cons 'number (the-string)))
                  (else   (cons 'else (the-failure))))

    `<char>'
          The regular language described by one unique character. Here
          is an example of a grammar that accepts either the character
          `#\a' or the character `#\b':

               (regular-grammar ()
                  (#\a (cons 'a (the-string)))
                  (#\b (cons 'b (the-string)))
                  (else (cons 'else (the-failure))))

    `<string>'
          This simple form of regular expression denotes the language
          represented by the string. For instance the regular
          expression `"Bigloo"' matches only the string composed of
          `#\B #\i #\g #\l #\o #\o'. The regular expression `".*["'
          matches the string `#\. #\* #\['.

    `(: <re> ...)'
          This form constructs sequence of regular expression. That is
          a form `<re1> <re2> ... <ren>' matches the language
          construction by concatenation of the language described by
          `<re1>', `<re2>', `<ren>'. Thus, `(: "x" all "y")' matches
          all words of three letters, started by character the `#\x'
          and ended with the character `#\y'.

    `(or <re> ...)'
          This construction denotes conditions. The language described
          by `(or re1 re2)' accepts words accepted by either `re1' or
          `re2'.

    `(* <re>)'
          This is the Kleene operator, the language described by `(*
          <re>)' is the language containing, 0 or more occurrences of
          `<re>'. Thus, the language described by `(* "abc")' accepts
          the empty word and any word composed by a repetition of the
          `abc' (`abc', `abcabc', `abcabcabc', ...).

    `(+ <re>)'
          This expression described non empty repetitions. The form `(+
          re)' is equivalent to `(: re (* re))'. Thus, `(+ "abc")'
          matches the words `abc', `abcabc', etc.

    `(? <re>)'
          This expression described one or zero occurrence. Thus, `(?
          "abc")' matches the empty word or the words `abc'.

    `(= <integer> <re>)'
          This expression described a fix number of repetitions. The
          form `(= num re)' is equivalent to `(: re re ... re)'. Thus,
          the expression `(= 3 "abc")' matches the only word
          `abcabcabc'.  In order to avoid code size explosion when
          compiling, `<integer>' must be smaller than an arbitrary
          constant. In the current version that value is `81'.

    `(>= <integer> <re>)'
          The language described by the expression `(>= int re)'
          accepts word that are, at least, `int' repetitions of `re'.
          For instance, `(>= 10 #\a)', accepts words compound of, at
          least, 10 times the character `#\a'. In order to avoid code
          size explosion when compiling, `<integer>' must be smaller
          than an arbitrary constant. In the current version that value
          is `81'.

    `(** <integer> <integer> <re>)'
          The language described by the expression `(** min max re)'
          accepts word that are repetitions of `re'; the number of
          repetition is in the range `min', `max'. For instance, `(**
          10 20 #\a)'.  In order to avoid code size explosion when
          compiling, `<integer>' must be smaller than an arbitrary
          constant. In the current version that value is `81'.

    `(... <integer> <re>)'
          The subexpression `<re>' has to be a sequence of characters.
          Sequences are build by the operator `:' or by string
          literals. The language described by `(... int re)', denotes,
          the first letter of `re', or the two first letters of `re',
          or the three first letters of `re' or the `int' first letters
          of `re'. Thus, `(... 3 "begin")' is equivalent to `(or "b"
          "be" "beg")'.

    `(uncase <re>)'
          The subexpression `<re>' has to be a sequence construction.
          The language described by `(uncase re)' is the same as `re'
          where letters may be upper case or lower case. For instance,
          `(uncase "begin")', accepts the words `"begin"', `"beGin"',
          `"BEGIN"', `"BegiN"', etc.

    `(in <cset> ...)'
          Denotes union of characters. Characters may be described
          individually such as in `(in #\a #\b #\c #\d)'. They may be
          described by strings. The expression `(in "abcd")' is
          equivalent to `(in #\a #\b #\c #\d)'.  Characters may also be
          described using a range notation that is a list of two
          characters. The expression `(in (#\a #\d))' is equivalent to
          `(in #\a #\b #\c #\d)'. The Ranges may be expresses using
          lists of string. The expression `(in ("ad"))' is equivalent
          to `(in #\a #\b #\c #\d)'.

    `(out <cset> ...)'
          The language described by `(out cset ...)' is opposite to the
          one described by `(in cset ...)'. For instance, `(out
          ("azAZ") (#\0 #\9))' accepts all words of one character that
          are neither letters nor digits. One should not that if the
          character numbered zero may be used inside regular grammar,
          the `out' construction never matches it. Thus to write a rule
          that, for instances, matches every character but `#\Newline'
          including the character zero, one should write:

               (or (out #\Newline) #a000)

    `(and <cset> <cset>)'
          The language described by `(and cset1 cset2)' accepts words
          made of characters that are in both `cset1' and `cset2'.

    `(but <cset> <cset>)'
          The language described by `(but cset1 cset2)' accepts words
          made of characters of `cset1' that are not member of `cset2'.

    `(posix <string>)'
          The expression `(posix string)' allows one to use Posix string
          notation for regular expressions. So, for example, the
          following two expressions are equivalent:

               (posix "[az]+|x*|y{3,5}")
               
               (or (+ (in ("az"))) (* "x") (** 3 5 "y"))


 - bigloo syntax: string-case string rule ...
     This form dispatches on strings. it opens an input on `string' a
     read into it according to the regular grammar defined by the
     `binding' and `rule'. Example:

          (define (suffix string)
             (string-case string
                ((: (* all) ".")
                 (ignore))
                ((+ (out #\.))
                 (the-string))
                (else
                 "")))

