Simple handler installation and uninstallation


Overview

This part of the dispatcher interface allows manipulation of a single binding: its creation, activation and deactivation.

Interface


PROCEDURE Create(event: PROCANY;
                 guard: PROCANY;
                 handler: PROCANY;
                 guardClosure: REFANY := NIL;
                 handlerClosure: REFANY := NIL;
                 options: Options := DefaultOptions;
                 key : Auth.Key := NIL
                ): Binding
                RAISES { Error };

PROCEDURE Install (binding: Binding) 
                  RAISES { Error };

PROCEDURE Uninstall (binding: Binding) 
                    RAISES { Error };

PROCEDURE InstallHandler(event: PROCANY;
	                 guard: PROCANY;
        	         handler: PROCANY;
                	 guardClosure: REFANY := NIL;
	                 handlerClosure: REFANY := NIL;
        	         options: Options := DefaultOptions;
			 key: Auth.Key := NIL
	                ): Binding
        	        RAISES { Error };

Usage

Create is used to create an inactive binding. A binding descriptor returned as the result of this procedure can be subsequently used to install and uninstall the binding as well as change properties of the binding.

The required parameters of binding creation are: the event on which the handler will be installed, the handler procedure and the guard procedure. Neither event nor handler procedure can be NIL. If the guard procedure is NIL then the handler will be invoked unconditionally (each time the event is raised). Optional parameters include closures and installation options. A closure can be specified for either a guard or a handler. If a handler or a guard procedure takes a closure then it is passed to it then the closure will be passed to the procedure as the first argument.

Install is used to activate a single binding. Uninstall is used to deactivate a single binding. These two procedures guarantee atomicity of installation and uninstallation with respect to on-going event invocations. (In other words, handlers can be installed and uninstalled on the fly.) They do not provide any atomicity across a single call, for example, if two handlers are swapped on an event by uninstalling one through a call to Uninstall and installing another through a call to Install there is a period of time between the two calls during which none of them is installed. Use the ChangeHandlers procedure where such atomicity is required.

InstallHandler creates an active binding. It takes the same arguments as Create and in fact it is equivalent to:

	VAR binding : Binding := Create(...);
	Install(binding);
	RETURN binding;
Since this is the most common case of handler installation a separate procedure is exported by the dispatcher.

Explicit pair of calls to Create and Install should be used instead of InstallHandler either if the installation has to be synchronized with other event operations (see ChangeHandlers) or to speed up initialization be removing creation, which includes typechecking and authorization, out of a critical path.

Typing rules

The dispatcher dynamically checks the types of procedures at the time a binding is created according to the following rules:

Examples

Installation of a simple handler which is always executed:
MODULE Counter;
        
VAR 
  binding : Dispatcher.Binding;
  counter : INTEGER;

PROCEDURE Counter(...) =
  BEGIN
    INC(counter);
  END Counter;

PROCEDURE Start () =
  BEGIN
    counter := 0;
    binding := Dispatcher.InstallHandler(IP.PacketRecv, Count, NIL);
  END Start;

PROCEDURE Stop (): INTEGER =
  BEGIN
    Dispatcher.Uninstall(binding);
    RETURN counter;
  END Stop;

BEGIN
END Counter;
Note that: Alternatively one could reuse the same binding:
MODULE Counter;
        
VAR 
  binding : Dispatcher.Binding;
  counter : INTEGER;

PROCEDURE Counter(...) =
  BEGIN
    INC(counter);
  END Counter;

PROCEDURE Start () =
  BEGIN
    counter := 0;
    Dispatcher.Install(binding);
  END Start;

PROCEDURE Stop (): INTEGER =
  BEGIN
    Dispatcher.Uninstall(binding);
    RETURN counter;
  END Stop;

BEGIN
  binding := Dispatcher.Create(IP.PacketRecv, Count, NIL);
END Counter;
Note that:


Przemek Pardyak, May 20th, 1996