(* $Id: netsys_sem.mli 1802 2012-10-18 23:23:39Z gerd $ *) (** {1 Generic anonymous semaphores} *) (** This module purely exists to also support "kind of anonymous" sempahores on MacOS X (which only has named semaphores). On other OS, it is just a wrapper for the functions in {!Netsys_posix}. Note that on OS X named semaphores have a max name length of 31 characters (including the / at the beginning), and that [Netsys_sem] uses 9 characters for its own purposes, leaving 22 characters for the prefix. (On other OS this is less restricted.) *) val have_anon_semaphores : unit -> bool (** Returns [true] if anonymous semaphores are supported on this system, either natively or emulated via named semaphores. *) (** {b Constants.} *) val sem_value_max : int (** The maximum value of a semaphore, but at most [max_int] *) val sem_size : int (** The size of an anonymous semaphore in bytes ([sizeof(sem_t)]) *) (** {b Types.} *) type container (** The container of the semaphore is the shared memory object *) type prefix = string (** A name starting with a slash. Must not contain further slashes *) type anon_semaphore type sem_open_flag = Netsys_posix.sem_open_flag = | SEM_O_CREAT | SEM_O_EXCL (** {b Container functions.} *) val container : prefix -> container (** [container prefix]: The prefix shall identify the container uniquely. Once can e.g. use the path of the shared memory object. The prefix is used to construct names for persistent objects. {b Note that containers have kernel persistence! They are not automatically deleted when the process finishes. Call [drop] to delete containers, or [create_container] to force their creation as fresh objects.} If the container does not exist yet, it is created. Otherwise the container is just opened. *) val create_container : prefix -> container (** [create_container prefix]: Like [container], but the container is always created. A previous instance is first deleted. *) val prefix : container -> prefix (** Return the prefix *) val drop : container -> unit (** Drop the semaphores in this container, and delete the container. This function is a no-op if the OS supports anonymous semaphores directly (because in this case the deletion of the container will automatically destroy the semaphores). *) (** Note that there is a general problem when a container is deleted or dropped by a process while it is still being used by another one. This will generally not generate errors, but can cause a lot of confusion, because the processes will partly access the same semaphores, and partly different semaphores. *) val unlink : prefix -> unit (** Unlinks the identified container if it exists, and unlinks all possible named semaphores. *) (** {b Semaphore functions.} *) val sem_init : container -> Netsys_types.memory -> int -> bool -> int -> anon_semaphore (** [sem_init cont mem pos pshared init_value]: Initializes the memory at position [pos] to [pos + sem_size() - 1] as anonymous semaphore. If [pshared] the semaphore is shared between processes. [init_value] is the initial non-negative value (max is [sem_value_max]). *) val sem_destroy : container -> anon_semaphore -> unit (** Destroys the anonymous semaphore *) val as_sem : container -> Netsys_types.memory -> int -> anon_semaphore (** [as_sem mem pos]: Interprets the memory at position [pos] to [pos + sem_size() - 1] as anonymous semaphore. The memory region must already have been initialized. *) val sem_getvalue : anon_semaphore -> int (** Returns the value of the semaphore. If the value is bigger than what can be represented as [int], an [EINVAL] error is returned. The returned value is non-negative - if the underlying POSIX function reports a negative value zero is returned instead. {b Unavailable on MacOS.} *) val sem_post : anon_semaphore -> unit (** Unlocks the semaphore (increases the value by 1) *) type sem_wait_behavior = Netsys_posix.sem_wait_behavior = | SEM_WAIT_BLOCK | SEM_WAIT_NONBLOCK val sem_wait : anon_semaphore -> sem_wait_behavior -> unit (** Locks the semaphore (decreases the value by 1). If the semaphore value is already zero, and [SEM_WAIT_BLOCK] is given, the function waits until another process or thread posts. If [SEM_WAIT_NONBLOCK] the error [EAGAIN] is returned. [sem_wait] may be interrupted by signals. *) module Debug : sig val enable : bool ref end (**/**) val force_emulation : unit -> unit