
events_nodefer

   Allow event handling

Type
   Event Handling

Description
    	Reenable event handling after it was previously deferred by
        
	    entering the handler for an event with the defer-property
		(see event_create/3 and set_event_handler/2).
	    a call to events_defer/0
        
	The purpose of this feature is to
	
	    sequence event handlers so they don't interrupt each other
	    protect accesses to global data structures from being interrupted
		or preempted by events.
	
	Events whose handling will be deferred are:
	
	   events raised by the builtin event/1
	   events posted from external code using ec_post_event()
	   events raised by interrupts whose handler is event/1
	
	Events that are raised while event handling is deferred will be
	queued and handled later. A handler for an event with the defer-
	property must always call events_nodefer/0 before exiting, e.g.
	
	deferring_event_handler :-
		writeln("This event handler"),
		writeln("will not be interrupted"),
		writeln("by other events!"),
		events_nodefer.
	
    
	CAUTION: events_nodefer/0 is a low-level primitive that must be
	used with great care. Part of ECLiPSe's functionality (e.g. timeout,
	branch-and-bound) relies on event handling and will not work
	properly while event handling is deferred. Deferring and undeferring
	events are nonlogical operations which are not undone on backtracking.
	The programmer must therefore make sure that every time event handling
	is deferred, it is eventually reenabled by a call to events_nodefer/0,
	even in case of failure or abort in the deferred code sequence.
    
    

Modes and Determinism
   events_nodefer is det

Examples
       % Without deferring, event handlers interrupt each other, which
    % makes it seem as if events were handled in reverse order:

    simple_handler(E) :-
    	writeln(simple_handling(E)).

    ?- set_event_handler(e1, simple_handler/1),
       set_event_handler(e2, simple_handler/1),
       set_event_handler(e3, simple_handler/1).
    Yes (0.00s cpu)

    ?-  event([e1,e2,e3]).
    simple_handling(e3)
    simple_handling(e2)
    simple_handling(e1)
    Yes (0.00s cpu)


    % With deferring, event handlers are sequenced, i.e. every
    % handler is allowed to finish before the next one executes:

    deferred_handler(E) :-
    	writeln(defered_handling(E)),
	events_nodefer.

    ?- set_event_handler(e1, defers(deferred_handler/1)),
       set_event_handler(e2, defers(deferred_handler/1)),
       set_event_handler(e3, defers(deferred_handler/1)).
    Yes (0.00s cpu)

    ?- event([e1,e2,e3]).
    defered_handling(e1)
    defered_handling(e2)
    defered_handling(e3)
    Yes (0.00s cpu)
    

See Also
   event_create / 3, event / 1, events_defer / 0, set_event_handler / 2
