module Netplex_semaphore:Netplex-wide semaphoressig..end
This implementation works in both multi-processing and multi-threading netplex environments. It is, however, not very fast, because the counters live in the controller, and the increment/decrement operations are realized by RPC's. It is good enough when these operations are only infrequently called, e.g. in the post-start and pre-finish processor callbacks.
    This interface is designed so that a later re-implementation with
    POSIX semaphores is relatively straight-forward.
val plugin : Netplex_types.pluginadd_plugin method 
      with this object as argument. This can e.g. be done in the
      post_add_hook of the processor.Netplex_cenv.Not_in_container_thread is raised.val increment : string -> int64
      Semaphore names are global to the whole netplex system. By convention,
      these names are formed like "service_name.local_name", i.e. they
      are prefixed by the socket service to which they refer.
val decrement : ?wait:bool -> string -> int64wait = false. However, (-1)
      is then returned nevertheless.
      If the value is already 0 and wait=true, the operation waits until
      the value exceeds 0, and when this happens, the semaphore is then
      decremented again. If several waiters exist, only one waiter gets
      the chance to decrement.
val get : string -> int64val create : ?protected:bool -> string -> int64 -> booltrue if the
      creation is successful, and false if the semaphore already existed.
      If protected, the semaphore
      is automatically decremented by some value when the container
      calling this function terminates. This value is pi - d where
      pi is the number of increments and d is the number
      of (successful) decrements requested by the container.
      A semaphore needs not to be explicitly created by calling create.
      It is automatically created at the first use time with a value of 0
      and protected=true.
Override the processor callbacks as follows to count the number of containers for the service:
 
    method post_add_hook sockserv ctrl =
      ctrl # add_plugin Netplex_semaphore.plugin
    method post_start_hook container =
      let sem_name = container#socket_service#name ^ ".counter" in
      let n =
        Netplex_semaphore.increment sem_name in
      if n=1 then
        prerr_endline "First container"
    method pre_finish_hook container =
      let sem_name = container#socket_service#name ^ ".counter" in
      let n =
        Netplex_semaphore.decrement sem_name in
      if n=0 then
        prerr_endline "Last container"
   