The interface of the Unixqueue module.
open Unix open Sys type group (* Groups of events *) type wait_id (* Wait ticket *) 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 *) type event = Input_arrived of (group * file_descr) | Output_readiness of (group * file_descr) | Out_of_band of (group * file_descr) | Timeout of (group * operation) | Signal | Extra of exn type event_system exception Abort of (group * exn);; val create_unix_event_system : unit -> event_system val new_group : event_system -> group val new_wait_id : event_system -> wait_id val exists_resource : event_system -> operation -> bool val add_resource : event_system -> group -> (operation * float) -> unit val add_close_action : event_system -> group -> (file_descr * (file_descr -> unit)) -> unit val add_abort_action : event_system -> group -> (group -> exn -> unit) -> unit val remove_resource : event_system -> group -> operation -> unit val add_handler : event_system -> group -> (event_system -> event Equeue.t -> event -> unit) -> unit val add_event : event_system -> event -> unit val clear : event_system -> group -> unit val run : event_system -> unit val once : event_system -> group -> float -> (unit -> unit) -> unit
Theme of this module are four types of operations: Waiting for input data, waiting for output readiness, waiting for out-of-band data, and waiting for a period of time. You can associate resources which simply means that it is waited until one of the operations becomes possible or is timed out. Resources are the combination of an operation and a time-out value.
This module already implements an event source which checks whether the operations are possible or timed-out, and which generates events describing what has happended. As with Equeue you can add events yourself, and you can add handlers which perform actions on certain events. As Unixqueue is based on Equeue, the queue model is simply the same.
Resources, handlers and events are grouped, i.e. you can reference to a bundle of resources/events by specifying the group they belong to. Group are created by Unixqueue.new_group, and every resource must belong to a group. The events caused by a resource belong to the same group as the resource. Handlers have a group, too, and the handlers only get events of the same group (this has been changed between Equeue 1.1 and 1.2). Furthermore, the groups simplify clean-up actions.
You can associate a close action with a resource. The close action is automatically called if the resource is removed from the queue. The close action should then close the underlying file descriptor.
You can remove all handlers and resouces belonging to a group with only one function call (clear).
There is special support for aborting groups. Aborting means that an exception is to be raised, but there needs to be some cleanup before the event queue is in a sane state. Because of this, it is possible to asscociate an abort action with a group. The abort action is automatically performed if the special Abort exception is raised within a handler.
Details:
Unixqueue.create_unix_event_system(): Returns a fresh event system with empty queue, no handlers, but already including the built-in event source.
new_group ues: Returns a new group descriptor for the event system ues.
new_wait_id ues: Returns a new wait-only identifier for the event system ues. You need such an ID to form a Wait operation. In constrast to the operations for file I/O, the various wait-only operations would otherwise not be distinguishable.
add_resource ues g (op,t): Adds a new resource to the event system ues. The resource belongs to the group g, and watches the operation op with the timeout value t (in seconds). A negative timeout value means no timeout. If you try to add two resources for the same operation, the secondly added resource is silently ignored.
exists_resource ues op: Returns true iff the event system ues contains a resource for operation op.
remove_resource ues g op: Removes the resource from the event system ues which belongs to group g and watches the operation op. If there is no such resource, Not_found is raised. If a file descriptor is no longer contained in any resource because of this removal, the associated close action is performed.
add_close_action ues g (fd, action): Adds the close action action to the file descriptor fd in the event system ues. There must already be some resource watching the file descriptor fd. The group g associates the close action to a group; see clear. The close action is called if the last resource for the specified file descriptor is removed. - If several close actions are added for the same file descriptor, the last added action hides the previous ones.
add_handler ues g handler: Adds the handler to the event system ues, and associates it to the group g.
add_abort_action ues g action: Adds the abort action action for group g to the event system ues. The abort action is invoked if the exception Abort(g,x) is raised within a handler. After the action has been performed, the exception x is raised. - If several abort actions are added for the same group, the last added action hides the previous ones.
clear ues g: Removes all entities associated with group g in the event system ues. This means that all resources, handlers, close actions, and abort actions belonging to the group are deleted. Note that the removal of resources may still trigger the close action if the last resource for a certain file descriptor is deleted. Furthermore, the cleared group can no longer be used for regular operations (in Equeue 1.2, this is enforced: handlers of cleared groups do not get any events; and it is not possible to add new handlers for a cleared group).
add_event ues e: Adds the event e to the event system ues.
once ues g t action: Adds a resource and a handler such that the action will be invoked after t seconds. The new entities are associated with the group g. The resource and the handler are removed once the action is over.
run ues: Starts the event system.
Object-oriented interface. In addition to the functional interface, there is also an object-oriented interface. Instead of calling one of the above functions f, one can also invoke the method with the same name. For example, the call
add_resource ues g (op,t)can also be written as
ues # add_resource g (op,t)Both styles can be used in the same program, and there is absolutely no difference (actually, the object-oriented interface is even the fundamental interface, and the functions are just wrappers for the method calls).
Instead of creating the event system with
let ues = create_unix_event_system()one can also use
let ues = new unix_event_system()Again, both calls do exactly the same.
The object-oriented interface has been introduced to support other implementations of file descriptor polling than [Unix.select]. The integration into the Tcl and Glib event systems has been implemented by defining additional classes that are compatible with Unixqueue.unix_event_system, but internally base on different polling mechanisms.