Default handler and result handling


Overview

If an event returns a result then some mechanism must be used to determine what the final result of the invocation is in case more than one handler is invoked. In SPIN, the result handling protocol is specified as a procedure (called result handler ) installed to process handlers' results. Results from all the handlers are passed to that procedure one by one as each of the invoked handlers return, and the procedure returns the final result of the invocation. If no result handler is installed then the result from the last invoked handler is returned as the final result of event invocation.

The dispatcher raises an exception in case no handler is invoked in response of raising an event that should return a result. Otherwise an unspecified result would be returned violating typesafety of invocation. To avoid the exception, and return a meaningful result in this case, a handler (called default handler ) can be installed to run in case no other handler is called.

Because all the callers and handlers depend on result handler and the default handler, they can be changed only by the primary implementation module for that event.

The default state of result handling is no result handler and no default handler.

Interface

PROCEDURE InstallResultHandler (event   : PROCANY;
                                handler : PROCANY;
                                module  : RTCode.Module;
                                closure : REFANY := NIL) 
                               RAISES { Error };

PROCEDURE InstallDefaultHandler (event   : PROCANY;
                                 handler : PROCANY;
                                 module  : RTCode.Module;
                                 closure : REFANY := NIL) 
                                RAISES { Error };

Typing rules

The dispatcher dynamically checks the types of result and default handlers at the time of their installation according to the following rules:

Usage

A result handler is installed using the InstallResultHandler procedure in the Dispatcher interface and the default handler is installed using the InstallDefaultHandler procedure in that interface. Their arguments are the event for which the handler is being installed, the handler, and the identification of a primary implementation module for that event. Optionally, a closure may be added for the handler. Both procedures raise an exception if the module argument is not the primary implementation module for the event, if the types of the event, the handler, and the closure do not match, or if either the event or the handler is not a legal procedure.

If NIL is passed as either of the handlers then the default state of result handling is reinstated.

Example

Consider an event that returns a BOOLEAN result. The module that implements the event installs the procedure HandleResult as a result handler to ensure that the final result of the event invocation or a logical OR and DefaultResult as the default handler to ensure that FALSE is returned if no handler is invoked as result or event raise.
MODULE Example;

PROCEDURE Event(...): BOOLEAN =
  BEGIN
    ...
  END Event;

PROCEDURE HandleResult(result: BOOLEAN; prevResult: BOOLEAN): BOOLEAN =
  BEGIN
    RETURN result OR prevResult;
  END HandleResult;

PROCEDURE DefaultResult(...): BOOLEAN =
  BEGIN
    RETURN FALSE;
  END DefaultResult;

BEGIN
  Dispatcher.InstallResultHandler(Event, HandleResult, THIS_MODULE());
  Dispatcher.InstallDefaultHandler(Event, DefaultResult, THIS_MODULE());
END Example.


Przemek Pardyak, May 20th, 1996