Fusion:Reactor

A reactor keeps track of a bunch of callback functions that will be called when the reactor is told to “dispatch.” The callbacks are known as reactions and to have them called back during a dispatch you first attach them to the reactor.

A reactor is first created with fusion_reactor_new, and will eventually be destroyed with fusion_reactor_free. There is no special notification if a reactor should be destroyed while reactions are attached to it.

Reactions are attached to the reactor with fusion_reactor_attach, to which you provide a pointer to the reaction callback function as well as a context. The context is just a pointer that will be passed verbatim to the reaction callback. If you don’t want the reaction to be called anymore, use fusion_reactor_detach.

When it’s time for the attached reactions to be called, use fusion_reactor_dispatch on the reactor. You should not rely on the overall order the reactions are called, but for a given fusionee they are called from the most-recently attached reaction first to the least-recently attached last. The self parameter lets you specify whether your own reactions should be called or not, and if they are then they will be called before reactions in other fusionees.

In addition to the reactions, globals may be attached to a reactor. When attaching globals, you provide an index rather a callback pointer. The index is used to select one function from an array of functions pointers that is provided at the time the dispatch occurs. Globals are generally used when a reactor is the basis for a dispatch mechanism of a larger abstraction (e.g. dfb_input) that provides its own callback functions to process the attached globals (and therefore gives specific meaning to the indices). Any attached globals are called before the attached reactions.

When a reaction is attached to a reactor, the information about the reaction is kept locally within the fusionee. The only information kept in the kernel driver is a count of how many reactions in each fusionee are attached to the reactor. That way the kernel module only sends a single message to each fusionee affected by a dispatch, and the iteration of the actual reactions is handled locally within each fusionee.

If a reaction (or a global) returns RS_REMOVE, it will be detached from the reactor so it won’t be called again for future dispatches. In the single-app configuration, if a reaction returns RS_DROP the current dispatch will terminate without calling any more reactions.