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
|