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

« back to all changes in this revision

Viewing changes to src/netplex/netplex_semaphore.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
(* $Id: netplex_semaphore.mli 1569 2011-04-05 16:08:52Z gerd $ *)
 
2
 
 
3
(** Netplex-wide semaphores *)
 
4
 
 
5
open Netplex_types
 
6
 
 
7
(** Semaphores are counters with atomic increment and decrement operations.
 
8
    They are very useful for counting the number of uses of a shared
 
9
    resource, and allow the identification of the first use (so the resource
 
10
    must be made available at all), and the last use (the resource can be
 
11
    released).
 
12
 
 
13
    This implementation works in both multi-processing and
 
14
    multi-threading netplex environments. It is, however, not very
 
15
    fast, because the counters live in the controller, and the
 
16
    increment/decrement operations are realized by RPC's. It is good
 
17
    enough when these operations are only infrequently called, e.g. in
 
18
    the post-start and pre-finish processor callbacks.
 
19
 
 
20
    This interface is designed so that a later re-implementation with
 
21
    POSIX semaphores is relatively straight-forward.
 
22
  *)
 
23
 
 
24
val plugin : plugin
 
25
  (** To enable semaphores, call the controller's [add_plugin] method 
 
26
      with this object as argument. This can e.g. be done in the
 
27
      [post_add_hook] of the processor.
 
28
   *)
 
29
 
 
30
 
 
31
(** The following functions can {b only} be invoked in container
 
32
    contexts. Outside of such a context the exception
 
33
    {!Netplex_cenv.Not_in_container_thread} is raised. 
 
34
 *)
 
35
 
 
36
val increment : string -> int64
 
37
  (** Increment the named semaphore by 1, and return the new value.
 
38
      If the semaphore does not exist yet, it is created with an initial
 
39
      value of 0, which is then incremented. 
 
40
 
 
41
      Semaphore names are global to the whole netplex system. By convention,
 
42
      these names are formed like ["service_name.local_name"], i.e. they
 
43
      are prefixed by the socket service to which they refer.
 
44
   *)
 
45
 
 
46
val decrement : ?wait:bool -> string -> int64
 
47
  (** Decrement the named semaphore by 1, and return the new value.
 
48
      Semaphore values cannot become negative. If the value is already 0,
 
49
      it is not decremented anymore if [wait = false]. However, (-1)
 
50
      is then returned nevertheless.
 
51
 
 
52
      If the value is already 0 and [wait=true], the operation waits until
 
53
      the value exceeds 0, and when this happens, the semaphore is then
 
54
      decremented again. If several waiters exist, only one waiter gets
 
55
      the chance to decrement.
 
56
   *)
 
57
 
 
58
val get : string -> int64
 
59
  (** Get the value of the named semaphore. Useful e.g. for monitoring
 
60
      the semaphore. If the semaphore does not exist, a value of 0 is
 
61
      returned.
 
62
 
 
63
      [get] can also be invoked from the controller process.
 
64
   *)
 
65
 
 
66
val create : ?protected:bool -> string -> int64 -> bool
 
67
  (** Create the semaphore with this initial value. Returns [true] if the
 
68
      creation is successful, and [false] if the semaphore already existed.
 
69
 
 
70
      If [protected], the semaphore
 
71
      is automatically decremented by some value when the container
 
72
      calling this function terminates. This value is [pi - d] where
 
73
      [pi] is the number of increments and [d] is the number
 
74
      of (successful) decrements requested by the container.
 
75
 
 
76
      A semaphore needs not to be explicitly created by calling [create].
 
77
      It is automatically created at the first use time with a value of 0
 
78
      and [protected=true].
 
79
 
 
80
      [create] can also be invoked from the controller process.
 
81
   *)
 
82
 
 
83
val destroy : string -> unit
 
84
  (** Destroy this semaphore. Any waiting [decrement] will immediately
 
85
      get (-1L).
 
86
 
 
87
      Note that there is no protection against unintended re-creation
 
88
      after [destroy].
 
89
 
 
90
      [destroy] can also be invoked from the controller process.
 
91
   *)
 
92
 
 
93
val ctrl_increment : string -> Netplex_types.container_id -> int64
 
94
  (** Increment the named semaphore from controller context, substituting
 
95
      an increment from a container (e.g. a container that terminated
 
96
      or is otherwise no longer able to do so). In this
 
97
      case the ID of the container needs to be passed 
 
98
   *)
 
99
 
 
100
 
 
101
(** Example (code fragment):
 
102
 
 
103
    Override the processor callbacks as follows to count the number of
 
104
    containers for the service:
 
105
 
 
106
  {[ 
 
107
    method post_add_hook sockserv ctrl =
 
108
      ctrl # add_plugin Netplex_semaphore.plugin
 
109
 
 
110
    method post_start_hook container =
 
111
      let sem_name = container#socket_service#name ^ ".counter" in
 
112
      let n =
 
113
        Netplex_semaphore.increment sem_name in
 
114
      if n=1 then
 
115
        prerr_endline "First container"
 
116
 
 
117
    method pre_finish_hook container =
 
118
      let sem_name = container#socket_service#name ^ ".counter" in
 
119
      let n =
 
120
        Netplex_semaphore.decrement sem_name in
 
121
      if n=0 then
 
122
        prerr_endline "Last container"
 
123
   ]}
 
124
 *)
 
125