aboutsummaryrefslogtreecommitdiffstats
path: root/include/plugins.h
blob: cbd841df141970dd89b65246315cecb09d471dc1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#ifndef PTX_PLUGINS_H_INCLUDED
#define PTX_PLUGINS_H_INCLUDED

#include <stddef.h>
#include "macros.h"

typedef struct ptx__plugin_manager_tag ptx_plugin_manager_t;
typedef struct ptx__plugin_handle_tag ptx_plugin_t;

/* returns:
 * - < 0 for plugin loading error (plugin will not be loaded)
 * - 0 for successful plugin startup
 * - (don't return values greater than 0 at this time)
 * usage:
 * Function will be called with this plugin instance and the "resume" pointer.
 *
 * The "resume" pointer will be NULL if the plugin is not being resumed. For this reason, it is not advised
 * to use NULL as a flag value in the restart function itself.
 */
typedef int (ptx_plugin_init_proc_t)(ptx_plugin_t * /*plugin*/, void * /*resume*/);

enum {
  /* This plugin cannot be resumed at this time. The plugin manager will not unload it if it expects a "seamless" reload.
   * The plugin is expected to act as if this function was not called. */
  PTX_PLUGIN_CANNOT_RESUME = -1,

  /* The plugin supports being resumed, but due to a transient error condition (malloc failure?) the plugin could not set itself up for
   * resuming. If a plugin returns this value to the plugin manager, it is expected to act as if the function was not called. */
  PTX_PLUGIN_RESUME_ERR = -2,

  /* The plugin supports being resumed, but due to a transient error condition, the plugin could not set itself up for resuming.
   * Additionally, as a part of preparing to be reloaded, the plugin performed operations it could not roll back. Likely, an error
   * will be reported to the user, and the plugin will be unloaded. The plugin manager makes no assumptions about the behavior of the
   * plugin at this time. */
  PTX_PLUGIN_RESUME_ERR_UNRECOVERABLE = -3,

  /* The plugin is ready to be resumed. */
  PTX_PLUGIN_RESUME_OK = 0
};

/* returns:
 * - one of the PTX_PLUGIN_* values in the above enum. if the return value is anything else, the plugin manager's behavior is not defined.
 */
typedef int (ptx_plugin_restart_proc_t)(ptx_plugin_t * /*plugin*/, void ** /*presume*/);

#define PTX_MOD_VERSION (1u)

/* the fields of this struct are public. ABI changes should be marked by incrementing PTX_MOD_VERSION */
struct ptx_plugin_desc
{
  size_t desc_len;
  unsigned desc_ver;
  unsigned reserved;

  ptx_plugin_init_proc_t *init_proc;
  ptx_plugin_restart_proc_t *restart_proc;

  const char *name;
  const char *description;
  const char *version;
};

/* for testing */
#ifdef _CLANGD
#undef PTX_PLUGIN
#define PTX_PLUGIN 1
#endif

#define PTX__INTERNAL_PLUGIN_DESC_SYM ptx__plugin_spec

#ifdef PTX_PLUGIN
#define PTX_PLUGIN_DESC_START PTX_EXPORT \
  const struct ptx_plugin_desc PTX__INTERNAL_PLUGIN_DESC_SYM = { \
    .desc_len = sizeof(struct ptx_plugin_desc), \
    .desc_ver = PTX_MOD_VERSION,

#define PTX_PLUGIN_NAME(_x)        .name = _x,
#define PTX_PLUGIN_DESCRIPTION(_x) .description = _x,
#define PTX_PLUGIN_VERSION(_x)     .version = _x,

#define PTX_PLUGIN_INIT(_x)        .init_proc = _x,
#define PTX_PLUGIN_RESTART(_x)     .restart_proc = _x,

#define PTX_PLUGIN_DESC_END };
#endif

PTX_INTERNAL(ptx_plugin_manager_t *ptx_plugin_manager_new(void) ATTR_MALLOC() ATTR_MALLOC((ptx_plugin_manager_free, 1)) ATTR_WUR);
PTX_INTERNAL(void ptx_plugin_manager_free(ptx_plugin_manager_t *mgr));

PTX_INTERNAL(int ptx_plugin_manager_load_dir(ptx_plugin_manager_t *mgr, const char *dir));

#endif