Docs GODI Archive
Projects Blog Link DB

Search GODI:


More options
File lib/ocaml/pkg-lib/equeue/unixqueue.mli GODI Package godi-ocamlnet
Library equeue
 
   Unixqueue.html    unixqueue.cmi_pretty    unixqueue.mli    Sources  
(* 
 * $Id: unixqueue.mli 459 2006-04-30 19:49:19Z gerd $
 *)

open Unix;;
open Sys;;

(**********************************************************************)
(*                          System events                             *)
(**********************************************************************)

(* written by Gerd Stolpmann *)

(** This module generalizes the [Unix.select] function. The idea is to have
 * an event queue (implemented by {!Equeue}) that manages all file events that
 * can be watched by a [Unix.select] call. As {b event} is considered when there
 * is something to do for a file descriptor (reading, writing, accepting 
 * out-of-band data), but also the condition that for a certain period 
 * of time ("timeout") nothing
 * has happened. Furthermore, a signal is also considered as an event,
 * and it is also possible to have user-generated extra events.
 *
 * These events are queued up, and they are presented to event handlers
 * that may process them.
 *
 * You can describe what types of event conditions are watched by adding
 * "resources". You can think a resource being a condition (bound to
 * a real resource of the operating system) for which 
 * events are generated if the condition becomes true.
 *)

(** {b THREAD-SAFETY}
 * 
 * Since release 1.2 of Equeue, this module serializes automatically.
 * You can call functions for the same event system from different
 * threads. This requires some special initialization, see {!Unixqueue_mt}.
 *
 * Note that the underlying {!Equeue} module is reentrant, but not
 * serializing. (It is not recommended (and not necessary) to call
 * functions of the Equeue module directly in multi-threaded programs.)
 *
 * The TCL extension is not thread-safe.
 *)

type group
  (** A group is an abstract tag for a set of events, resources, and
   * event handlers. Usually every event handler creates a new group,
   * and all events and resources processed by the handler are 
   * members of this group.
   *)

exception Abort of (group * exn);;
  (** Event handlers can raise this exception to cancel a group 
   * of handlers, events, and resources. If an abort action
   * is defined for the group, it will be executed. Next, all members
   * of the group are removed from the event system. 
   *
   * First argument is the group. The second argument
   * is an arbitrary exception (must not be [Abort] again) which is
   * passed to the abort action.
   *)


type wait_id
  (** A wait identifier is used to distinguish between several
   * timers, see type [operation].
   *)


type operation =
    Wait_in  of file_descr          (** wait for input data *)
  | Wait_out of file_descr          (** wait until output can be written *)
  | Wait_oob of file_descr          (** wait for out-of-band data *)
  | Wait of wait_id                 (** wait only for timeout *)
  (** An [operation] specifies the condition to wait for. Every kind
   * of operation may have an associated timer (not only [Wait]).
   *)


type event =
    Input_arrived of    (group * file_descr)  (** Input data has arrived *)
  | Output_readiness of (group * file_descr)  (** Output is possible now *)
  | Out_of_band of      (group * file_descr)  (** OOB data has arrived *)
  | Timeout of          (group * operation)   (** A timer has expired *)
  | Signal                                    (** A signal has happened *)
  | Extra of exn                              (** User-generated event *)
  (** An [event] is triggered when the condition of an [operation]
   * becomes true, when a signal happens, or when the event is
   * (artificially) added to the event queue ([add_event], below).
   * The events resulting from an [operation] carry the group of
   * the resource with them. 
   *
   * The event [Signal] is triggered when the [EINTR] condition is
   * caught; this normally means that a signal has just been delivered.
   * The generation of [Signal] events should be considered as
   * unreliable, not every signal delivery can be detected. Reasons for
   * the unrealiability are that user-supplied code happens to
   * get the [EINTR] condition and not the [Unixqueue] event loop,
   * and that there are known race conditions in the O'Caml signal
   * handling routines that may cause signals to be lost. However,
   * it can be expected that almost all signals will trigger [Signal].
   *
   * The event [Extra] can only be artificially added to the queue,
   * and the argument of [Extra] is an exception value that distinguishes
   * between several kinds of user-generated events.
   *)

class type event_system =
object
  (* Public interface *)
  method new_group : unit -> group
  method new_wait_id : unit -> wait_id
  method exists_resource : operation -> bool
  method add_resource : group -> (operation * float) -> unit
  method add_close_action : group -> (file_descr * (file_descr -> unit)) -> unit
  method add_abort_action : group -> (group -> exn -> unit) -> unit
  method remove_resource : group -> operation -> unit
  method add_handler : group -> (event_system -> event Equeue.t -> event -> unit) -> unit
  method add_event : event -> unit
  method clear : group -> unit
  method run : unit -> unit
  method is_running : bool
  method once : group -> float -> (unit -> unit) -> unit
  method exn_log : ?suppressed:bool -> ?to_string:(exn -> string) -> ?label:string -> exn -> unit
  method debug_log : ?label:string -> string -> unit
  (* Protected interface *)
  method private setup : unit -> (file_descr list * file_descr list * file_descr list * float)
  method private queue_events : (file_descr list * file_descr list * file_descr list) -> bool
  method private source : event Equeue.t -> unit
end
  (** The [event_system] manages events, handlers, resources, groups,
   * etc. It is now a class type, and you may invoke the operations directly
   * for the class. The operations are still available as functions (below).
   *
   * A {b resource} is an operation with an optional timer. The operation
   * describes the condition to watch for, and the timer defines the
   * maximum period of time for that. If the condition becomes true,
   * an [Input_arrived], [Output_readiness], or [Out_of_band] event
   * will be triggered. If the timer expires, a [Timeout] event will be
   * generated. After the event the resource remains active, and the
   * timeout period begins anew.
   *
   * A resource is usually bound to a file descriptor. It is allowed
   * to watch the same descriptor for several different conditions,
   * but it is forbidden to watch the same descriptor for the same kind
   * of condition several times.
   *
   * As a special case, the operation [Wait] is not bound to a
   * file descriptor, but simply starts a timer. The argument of [Wait]
   * can be used to distinguish between several timers that are active
   * at the same time.
   *
   * {b Event handlers} get the events one after the other, and 
   * process them. When a handler is called for an event, there are
   * several possible reactions: (1) The handler can return normally,
   * which means that the event has been accepted, and will not be
   * passed to any other handler. (2) The handler can raise
   * {!Equeue.Reject}, which means that the handler cannot process
   * the event, and that another handler should get it. (3) The handler
   * can raise {!Equeue.Terminate} which means that the event has been
   * accepted, and that the handler is terminated (it will never be
   * called again). (4) The handler can raise [Abort] which means that
   * the event is deferred, and that a special abort mechanism is
   * triggered (see the description for [Abort] above), this is also
   * terminates the handler. The deferred event will again be processed
   * in the future. (5) The handler can raise any other exception.
   * This causes that the event is deferred, and the exception falls
   * through to the caller of [run].
   *
   * {b Groups} are used to simplify the association of events to
   * handlers, and to simplify the termination of handlers (see [clear]).
   * If an event is associated with a group, only handlers associated with
   * the same group will get them.
   *
   * There is a special {b Close handler} which is useful to close file
   * descriptors no longer needed. It is called when all resources are
   * removed from the event system dealing with the file descriptor. 
   * The close handler should close the descriptor. Note that close handlers
   * are only useful under certain circumstances.
   * 
   *)

class unix_event_system : unit -> event_system
  (** The standalone implementation of an event system *)

val create_unix_event_system : unit -> event_system
  (** Create a new, empty event system *)

val new_group : event_system -> group
  (** Create a new, empty group for the event system *)


val new_wait_id : event_system -> wait_id
  (** Create a new unique wait identifier *)


val exists_resource : event_system -> operation  -> bool
  (** Find out if a specific resource already exists (or better: is
   * already watched by an operation).
   *)


val add_resource : event_system -> group -> (operation * float) -> unit
  (** Add a resource such that it is watched for conditions described
   * by the [operation] for the period given by the [float] number.
   * A negative number means that the resource is watched for an infinite
   * period. The resource becomes a member of the [group].
   *
   * You cannot add the same operation several times;
   * if you try it the second operation is silently dropped.
   *
   * The resource remains even if it has generated an event. The timeout
   * period starts again in this case.
   *)


val add_close_action : 
  event_system -> group -> (file_descr * (file_descr -> unit)) 
    -> unit