Struct PntosCommonPlugin

Struct Documentation

struct PntosCommonPlugin

Common definitions that all plugins must provide. This structure should not be used directly (except in the case of a utility plugin), but instead is composed as the first field on all of the concrete pntOS plugin structures. For example, the transport plugin is specified as:

struct PntosTransportPlugin {
    PntosCommonPlugin common;
    ...
} PntosTransportPlugin;
Thus this structure defines a set of fields that all plugins have. The PntosCommonPlugin.init_plugin function is guaranteed to be called by pntOS when the plugin is first loaded into memory by the system.

When defining a new e.g. transport plugin, the plugin writer is responsible for implementing all fields on the PntosTransportPlugin structure. Thus, the fields of the PntosCommonPlugin nested on the PntosTransportPlugin are implemented by the plugin writer.

Public Members

PntosManagedMemory *memory
void (*init_plugin)(struct PntosCommonPlugin *self, char *plugin_resources_location, PntosMediator *mediator)

A function that will be called by pntOS once and only once when it first initializes the plugin before any other functions on the plugin are called. Here the plugin may do dynamic runtime initialization of its members, and is given the full path to the location of a data folder specific to the plugin, in case it needs to acquire additional files. A pointer to an instance of PntosMediator will be passed which the plugin should save off for later use. Whenever the plugin needs to make a request of pntOS, it should use one of the fields in the PntosMediator instance received by the plugin in this function call.

Implementation note:

This inversion of control allows the controller to implement the PntosMediator struct, and abstracts away the return communication channel from the plugin to the rest of the system. Thus, the plugin need only implement PntosMediator by simply saving a copy of the functions that the controller passes into it. Then, when the plugin later needs to make requests of the system, it may call a function in its copy of PntosMediator, without needing any knowledge of how the controller implemented PntosMediator. This allows controllers to implement arbitrary concurrency models, including single-threaded, multi-threaded, multi-process, and distributed computing.

plugin_resources_location specifies the location of the plugin’s resources. The location is determined by the controller plugin, and therefore is controller implementation specific. Plugin implementers wishing to provide a resource to their plugin should consult the documentation of the controller to determine which location scheme will be passed into this function.

mediator is NULL-able if the plugin type being initialized is a PntosControllerPlugin. Non-controller plugins may assume that the mediator parameter is not NULL.

void (*shutdown_plugin)(struct PntosCommonPlugin *self)

A function that will be called by pntOS when it is done using the plugin. Here the plugin should release any resources it has acquired (including the PntosMediator if it kept a reference to that when init_plugin was called). When this function call returns pntOS may only call the destructor function (it will not call any other functions of this plugin). The plugin may not call any function on any other plugin, mediator, or use any resource that was given to it by pntOS after it returns from this function.

PntosPluginTypes plugin_type

The type of this plugin. This field is used to determine what types a parent struct is castable to, when PntosCommonPlugin is the first field in the parent struct. For example, suppose we defined a new pntOS plugin called FooPlugin, and composed a PntosCommonPlugin inside of it:

typedef struct PntosFooPlugin {
    PntosCommonPlugin common;
    .. other fields
} PntosFooPlugin;
Then we had a function defined that takes in arbitrary plugin types:
void some_function(PntosCommonPlugin * my_plugin)
We could use the plugin_type field to identify what type of plugin we really received and cast it back in the implementation of some_function:
void some_function(PntosCommonPlugin * my_plugin) {
    if (my_plugin->plugin_type == FOO_PLUGIN_TYPE) {
        PntosFooPlugin * foo_plugin = (PntosFooPlugin *) my_plugin;
        .. use FooPlugin functionality ..
    }
}

char *identifier

A string identifier uniquely identifying this plugin. This string will be used to determine the unique space this plugin receives in the system config.