~ubuntu-branches/ubuntu/trusty/ocamlnet/trusty

« back to all changes in this revision

Viewing changes to src/equeue/unixqueue.mli

  • Committer: Bazaar Package Importer
  • Author(s): Stéphane Glondu
  • Date: 2011-09-02 14:12:33 UTC
  • mfrom: (18.2.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110902141233-zbj0ygxb92u6gy4z
Tags: 3.4-1
* New upstream release
  - add a new NetcgiRequire directive to ease dependency management
    (Closes: #637147)
  - remove patches that were applied upstream:
    + Added-missing-shebang-lines-in-example-shell-scripts
    + Try-also-ocamlc-for-POSIX-threads

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
(* 
2
 
 * $Id: unixqueue.mli 459 2006-04-30 19:49:19Z gerd $
 
2
 * $Id: unixqueue.mli 1616 2011-06-10 15:08:57Z gerd $
3
3
 *)
4
4
 
5
5
open Unix;;
6
6
open Sys;;
7
7
 
8
 
(**********************************************************************)
9
 
(*                          System events                             *)
10
 
(**********************************************************************)
11
 
 
12
 
(* written by Gerd Stolpmann *)
13
 
 
14
 
(** This module generalizes the [Unix.select] function. The idea is to have
15
 
 * an event queue (implemented by {!Equeue}) that manages all file events that
16
 
 * can be watched by a [Unix.select] call. As {b event} is considered when there
17
 
 * is something to do for a file descriptor (reading, writing, accepting 
18
 
 * out-of-band data), but also the condition that for a certain period 
19
 
 * of time ("timeout") nothing
20
 
 * has happened. Furthermore, a signal is also considered as an event,
21
 
 * and it is also possible to have user-generated extra events.
22
 
 *
23
 
 * These events are queued up, and they are presented to event handlers
24
 
 * that may process them.
25
 
 *
26
 
 * You can describe what types of event conditions are watched by adding
27
 
 * "resources". You can think a resource being a condition (bound to
28
 
 * a real resource of the operating system) for which 
29
 
 * events are generated if the condition becomes true.
30
 
 *)
31
 
 
32
 
(** {b THREAD-SAFETY}
33
 
 * 
34
 
 * Since release 1.2 of Equeue, this module serializes automatically.
35
 
 * You can call functions for the same event system from different
36
 
 * threads. This requires some special initialization, see {!Unixqueue_mt}.
37
 
 *
38
 
 * Note that the underlying {!Equeue} module is reentrant, but not
39
 
 * serializing. (It is not recommended (and not necessary) to call
40
 
 * functions of the Equeue module directly in multi-threaded programs.)
41
 
 *
42
 
 * The TCL extension is not thread-safe.
43
 
 *)
44
 
 
45
 
type group
 
8
(** Unixqueues are one of the two forms of system event loops provided
 
9
    by Ocamlnet. Besides Unixqueue, there is also pollset (see
 
10
    {!Netsys_pollset}). The pollsets are much simpler (there is no
 
11
    queuing of events), and nowadays Unixqueue bases upon pollset,
 
12
    and extends its functionality. Historically, however, Unixqueue
 
13
    precede pollset, and there are still implementations of the former
 
14
    in Ocamlnet not using pollset as its base data structure.
 
15
 
 
16
    The common idea of both data structures is the generalization of 
 
17
    watching for events, as it is also provided by the [Unix.select]
 
18
    function. Note, however, that recent implementations no longer
 
19
    use [Unix.select], but better system interfaces for the same.
 
20
 
 
21
    When there is something to do for a file descriptor (reading, 
 
22
    writing, accepting out-of-band data), this is called an {b event},
 
23
    and the task of Unixqueue is to check when events happen, and to
 
24
    tell some consumer about the events.
 
25
 
 
26
    There are three further types of events: Timeout events, signal
 
27
    events, and user-defined events.
 
28
 
 
29
    The events are queued up, and they are presented to event handlers
 
30
    that may process them.
 
31
 
 
32
    You can describe what types of event conditions are watched by adding
 
33
    {b resources}. You can think a resource being a condition (bound to
 
34
    a real resource of the operating system) for which 
 
35
    events are generated if the condition becomes true. Currently, only
 
36
    file descriptors and timers are supported as resources.
 
37
 *)
 
38
 
 
39
(** {b Relation to other modules.} This module is thought as the primary
 
40
    interface to Unixqueues. If there isn't any specialty one has to deal
 
41
    with, just use this module:
 
42
 
 
43
    - It defines all required types like [group], [wait_id], etc. Note that
 
44
      these types are reexported from [Unixqueue_util]. Please consider
 
45
      this as implementation detail, and don't use it in your code.
 
46
    - It defines a standard implementation [standard_event_system], which
 
47
      is a good default implementation, although it might not be the best
 
48
      available for all purposes.
 
49
    - It defines a set of access functions like [add_event] which 
 
50
      simply call the methods of the event system object of the same name.
 
51
      Note that these functions work for all event system implementation,
 
52
      not only for [standard_event_system].
 
53
 
 
54
    There are further modules that have to do with Unixqueue:
 
55
 
 
56
    - {!Unixqueue_pollset} is the implementation behind 
 
57
      [standard_event_system]. If you want to use other pollsets than
 
58
      the standard one, it is possible to create Unixqueues on top of these
 
59
      by using this module directly.
 
60
    - {!Unixqueue_select} is the historic default implementation. It
 
61
      calls directly [Unix.select]. It is still available because it 
 
62
      serves as a reference implementation for now.
 
63
    - [Unixqueue_util] is an internal module with implementation details.
 
64
      Please don't call it directly.
 
65
    - {!Uq_gtk} is an implementation of Unixqueue mapping to the 
 
66
      GTK event loop. Useful for multiplexing event-based I/O and
 
67
      GTK graphics operations.
 
68
    - {!Uq_tcl} is an implementation of Unixqueue mapping to the 
 
69
      TCL event loop. Useful for multiplexing event-based I/O and
 
70
      event-based code written in TCL (especially TK).
 
71
 *)
 
72
 
 
73
(** {b Thread safety.} The default implementation of Unixqueue is
 
74
    thread-safe, and operations can be called from different threads.
 
75
    For other implementations, please look at the modules implementing
 
76
    them.
 
77
 **)
 
78
 
 
79
 
 
80
(** {1 Types and exceptions} *)
 
81
 
 
82
 
 
83
type group = Unixqueue_util.group
46
84
  (** A group is an abstract tag for a set of events, resources, and
47
85
   * event handlers. Usually every event handler creates a new group,
48
86
   * and all events and resources processed by the handler are 
58
96
   * First argument is the group. The second argument
59
97
   * is an arbitrary exception (must not be [Abort] again) which is
60
98
   * passed to the abort action.
 
99
   *
 
100
   * Abort handlers are a questionable feature of Unixqueues. You
 
101
   * can also call the [clear] operation, and raise the exception
 
102
   * directly. {b Do not use in new code!}
61
103
   *)
62
104
 
63
105
 
64
 
type wait_id
 
106
type wait_id = Unixqueue_util.wait_id
65
107
  (** A wait identifier is used to distinguish between several
66
108
   * timers, see type [operation].
67
109
   *)
68
110
 
69
111
 
70
 
type operation =
 
112
type operation = Unixqueue_util.operation =
71
113
    Wait_in  of file_descr          (** wait for input data *)
72
114
  | Wait_out of file_descr          (** wait until output can be written *)
73
115
  | Wait_oob of file_descr          (** wait for out-of-band data *)
77
119
   *)
78
120
 
79
121
 
80
 
type event =
 
122
type event = Unixqueue_util.event =
81
123
    Input_arrived of    (group * file_descr)  (** Input data has arrived *)
82
124
  | Output_readiness of (group * file_descr)  (** Output is possible now *)
83
125
  | Out_of_band of      (group * file_descr)  (** OOB data has arrived *)
84
126
  | Timeout of          (group * operation)   (** A timer has expired *)
85
127
  | Signal                                    (** A signal has happened *)
86
128
  | Extra of exn                              (** User-generated event *)
 
129
  | Immediate of (group * (unit -> unit))     (** immediate event *)
87
130
  (** An [event] is triggered when the condition of an [operation]
88
131
   * becomes true, when a signal happens, or when the event is
89
132
   * (artificially) added to the event queue ([add_event], below).
103
146
   * The event [Extra] can only be artificially added to the queue,
104
147
   * and the argument of [Extra] is an exception value that distinguishes
105
148
   * between several kinds of user-generated events.
 
149
   *
 
150
   * The event [Immediate(g,f)] also can only be artificially added to
 
151
   * the queue. In contrast to other events, it is not passed to handlers
 
152
   * when the event is processed. Instead, an immediate event is processed
 
153
   * by calling [f()]. This is a more direct way of notification, and
 
154
   * it is not necessary to define a handler. Even an immediate event is
 
155
   * member of a group [g], and if the [clear] function is called for [g],
 
156
   * the callback function [f] will no longer be called.
106
157
   *)
107
158
 
108
159
class type event_system =
112
163
  method new_wait_id : unit -> wait_id
113
164
  method exists_resource : operation -> bool
114
165
  method add_resource : group -> (operation * float) -> unit
 
166
  method add_weak_resource : group -> (operation * float) -> unit
115
167
  method add_close_action : group -> (file_descr * (file_descr -> unit)) -> unit
116
168
  method add_abort_action : group -> (group -> exn -> unit) -> unit
117
169
  method remove_resource : group -> operation -> unit
120
172
  method clear : group -> unit
121
173
  method run : unit -> unit
122
174
  method is_running : bool
123
 
  method once : group -> float -> (unit -> unit) -> unit
124
 
  method exn_log : ?suppressed:bool -> ?to_string:(exn -> string) -> ?label:string -> exn -> unit
125
 
  method debug_log : ?label:string -> string -> unit
126
 
  (* Protected interface *)
127
 
  method private setup : unit -> (file_descr list * file_descr list * file_descr list * float)
128
 
  method private queue_events : (file_descr list * file_descr list * file_descr list) -> bool
129
 
  method private source : event Equeue.t -> unit
 
175
  method when_blocking : (unit -> unit) -> unit
130
176
end
131
177
  (** The [event_system] manages events, handlers, resources, groups,
132
178
   * etc. It is now a class type, and you may invoke the operations directly
180
226
   * 
181
227
   *)
182
228
 
 
229
(** {1 Creating event systems} *)
 
230
 
 
231
class standard_event_system : unit -> event_system
 
232
  (** The standard implementation of an event system. It uses 
 
233
      {!Unixqueue_pollset.pollset_event_system} on top of
 
234
      {!Netsys_pollset_generic.standard_pollset}.
 
235
   *)
 
236
 
 
237
val standard_event_system : unit -> event_system
 
238
  (** Create a new, empty, standard event system *)
 
239
 
183
240
class unix_event_system : unit -> event_system
184
 
  (** The standalone implementation of an event system *)
 
241
  (** An alternate name for [standard_event_system], provided for
 
242
      backward compatibility.
 
243
   *)
185
244
 
186
245
val create_unix_event_system : unit -> event_system
187
 
  (** Create a new, empty event system *)
 
246
  (** An alternate name for [standard_event_system], provided for
 
247
      backward compatibility.
 
248
   *)
 
249
 
 
250
 
 
251
(** {1 Using event systems} *)
 
252
 
 
253
(** The following functions work for all kinds of event systems, not
 
254
    only for the ones returned by [standard_event_system].
 
255
 *)
 
256
 
188
257
 
189
258
val new_group : event_system -> group
190
259
  (** Create a new, empty group for the event system *)
213
282
   * period starts again in this case.
214
283
   *)
215
284
 
 
285
val add_weak_resource : event_system -> group -> (operation * float) -> unit
 
286
  (** Similar to [add_resource], but the resource is weak. Such resources
 
287
    * do not keep the event system running when only weak resources remain.
 
288
    * Normally, [Unixqueue.run] returns to the caller not before
 
289
    * all resources are removed and all events are processed. Weak
 
290
    * resources do not count for this condition, i.e. [Unixqueue.run]
 
291
    * also returns when there are only weak resources left.
 
292
    * As an example, weak resources can be used to time out unused
 
293
    * file descriptors.
 
294
    *
 
295
    * Weak resources can be removed with [remove_resource].
 
296
    *
 
297
    * {b New in Ocamlnet 3.}
 
298
   *)
216
299
 
217
300
val add_close_action : 
218
301
  event_system -> group -> (file_descr * (file_descr -> unit)) 
228
311
   * is called.
229
312
   *
230
313
   * You can only add (set) one close action for every descriptor.
 
314
   *
 
315
   * Of course, the idea is to do [add_close_action ... Unix.close]. Note
 
316
   * that there is a problem with multi-threaded programs, and this construct
 
317
   * must not be used there. In particular, the close action is called from
 
318
   * [remove_resource] or [clear], but it is possible that the event system
 
319
   * is running, so a watched descriptor might be closed. This has undesired
 
320
   * effects. What you should better do is to delay the closure of the
 
321
   * descriptor to a sane moment, e.g. by calling
 
322
   *   {[ Unixqueue.once esys g 0.0 (fun () -> Unix.close fd) ]}
 
323
   * from the close action.
231
324
   *)
232
325
 
233
326
 
312
405
   * group, the timer is deleted, too.
313
406
   *)
314
407
 
315
 
val exn_log : event_system ->
 
408
val weak_once : event_system -> group -> float -> (unit -> unit) -> unit
 
409
  (** Same as [once], but the timer does not keep the event system running
 
410
      if it is the only remaining resource.
 
411
   *)
 
412
 
 
413
val epsilon : event_system -> (unit -> unit) -> unit
 
414
  (** The execution of the function is pushed onto the event queue
 
415
      (minimal delay)
 
416
   *)
 
417
 
 
418
 
 
419
(** {1 Debugging} *)
 
420
 
 
421
 
 
422
module Debug : sig
 
423
  (** This module controls debugging of all [Unixqueue_*] modules *)
 
424
 
 
425
  val enable : bool ref
 
426
    (** Enable {!Netlog} debugging *)
 
427
 
 
428
  val set_debug_mode : bool -> unit
 
429
    (** Sets [enable].
 
430
     *)
 
431
 
 
432
  val set_debug_target : Equeue.Debug.debug_target -> unit
 
433
    (** Restricts debugging to this target. 
 
434
     *)
 
435
end
 
436
 
 
437
(*
 
438
(** The status of the following functions is currently a bit unclear.
 
439
    When a Ocamlnet-wide logging concept is introduced, these functions
 
440
    probably disappear. They are used by other Ocamlnet modules to
 
441
    implement debug logging.
 
442
 *)
 
443
 
 
444
(* val exn_log : event_system ->
316
445
              ?suppressed:bool -> ?to_string:(exn -> string) -> 
317
 
              ?label:string -> exn -> unit
 
446
              ?label:string -> exn -> unit *)
318
447
  (** Exceptions log: In event-based programming, it is sometimes not
319
448
   * possible to handle exceptions appropriately. It is also bad not
320
449
   * to handle them at all. For these cases, the exceptions log might
351
480
   *   useful to describe where the log message is generated.
352
481
   *)
353
482
 
354
 
val debug_log : event_system -> ?label:string -> string -> unit
 
483
(* val debug_log : event_system -> ?label:string -> string -> unit*)
355
484
  (** Outputs a message in the debug log (when enabled).
356
485
   *
357
486
   * @param label The label is included in the log output. This is
358
487
   *   useful to describe where the log message is generated.
359
488
   *)
360
489
 
361
 
val set_debug_mode : bool -> unit
 
490
(* val set_debug_mode : bool -> unit *)
362
491
  (** Whether to output debug messages. Output goes to stderr.
363
492
   * Setting the debug mode implies setting Equeue's debug mode.
364
493
   *
367
496
   * is required to interpret debug protocols.
368
497
   *)
369
498
 
370
 
(* val attach_to_tcl_queue : event_system -> (event_system -> unit) -> unit
371
 
 *
372
 
 * This is no longer supported here. Look into Uq_tcl for the modern
373
 
 * way to integrate with the tcl/tk event system
 
499
(* val set_debug_target : Equeue.debug_target -> unit *)
 
500
  (** More fine-grained debug control *)
374
501
 *)
375
 
 
376
 
(**/**)
377
 
 
378
 
val init_mt : (unit -> ((unit -> unit) * (unit -> unit))) -> unit
379
 
(* A private function to initialize multi-threading. *)
380