This way we can store some module-specific things.
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
};
static int collecty_daemon_modules_init(sd_event_source* source, void* data) {
- collecty_ctx* ctx = data;
+ collecty_daemon* daemon = data;
// Initialize all modules
- return collecty_modules_init(ctx);
+ return collecty_modules_init(daemon->ctx, daemon);
}
static int collecty_daemon_modules_shutdown(sd_event_source* source, void* data) {
- collecty_ctx* ctx = data;
+ collecty_daemon* daemon = data;
// Shutdown all modules
- return collecty_modules_shutdown(ctx);
+ return collecty_modules_shutdown(daemon->ctx, daemon);
}
static int collecty_daemon_terminate(sd_event_source* source,
// Initialize all modules when the loop starts
r = sd_event_add_defer(self->loop, &self->events.modules_init,
- collecty_daemon_modules_init, self->ctx);
+ collecty_daemon_modules_init, self);
if (r < 0) {
ERROR(self->ctx, "Failed to register module init: %s\n", strerror(-r));
return r;
// Shutdown all modules when the loop exits
r = sd_event_add_exit(self->loop, &self->events.modules_shutdown,
- collecty_daemon_modules_shutdown, self->ctx);
+ collecty_daemon_modules_shutdown, self);
if (r < 0) {
ERROR(self->ctx, "Failed to register module shutdown: %s\n", strerror(-r));
return r;
# #
#############################################################################*/
+#include <errno.h>
+#include <stdlib.h>
#include <string.h>
#include "ctx.h"
+#include "daemon.h"
#include "module.h"
-int collecty_module_init(collecty_ctx* ctx, collecty_module* module) {
+struct collecty_module {
+ collecty_ctx* ctx;
+ int nrefs;
+
+ // Daemon
+ collecty_daemon* daemon;
+
+ // Methods
+ const collecty_module_methods* methods;
+};
+
+static int collecty_module_init(collecty_module* self) {
int r;
- // Nothing to do if the module does not have an init method
- if (!module->init)
+ // Do nothing if there is no init function
+ if (!self->methods->init)
return 0;
- DEBUG(ctx, "Initializing %s...\n", module->name);
-
// Initialize the module
- r = module->init(ctx);
+ r = self->methods->init(self->ctx);
if (r < 0) {
- ERROR(ctx, "Failed to initialize %s: %s\n", module->name, strerror(-r));
- return r;
+ ERROR(self->ctx, "Failed to initialize %s: %s\n",
+ collecty_module_name(self), strerror(-r));
}
- return 0;
+ return r;
+}
+
+static void collecty_module_free(collecty_module* self) {
+ if (self->methods->free)
+ self->methods->free(self->ctx);
+
+ if (self->daemon)
+ collecty_daemon_unref(self->daemon);
+ if (self->ctx)
+ collecty_ctx_unref(self->ctx);
}
-int collecty_module_shutdown(collecty_ctx* ctx, collecty_module* module) {
+int collecty_module_create(collecty_module** module,
+ collecty_ctx* ctx, collecty_daemon* daemon, const collecty_module_methods* methods) {
+ collecty_module* self = NULL;
int r;
- // Nothing to do if the module does not have an shutdown method
- if (!module->shutdown)
- return 0;
+ // Allocate some memory
+ self = calloc(1, sizeof(*self));
+ if (!self)
+ return -errno;
- DEBUG(ctx, "Shutting down %s...\n", module->name);
+ // Initialize the reference counter
+ self->nrefs = 1;
- // Shut down the module
- r = module->shutdown(ctx);
- if (r < 0) {
- ERROR(ctx, "Failed to shutdown %s: %s\n", module->name, strerror(-r));
- return r;
- }
+ // Store a reference to the context
+ self->ctx = collecty_ctx_ref(ctx);
+
+ // Store a reference to the daemon
+ self->daemon = collecty_daemon_ref(daemon);
+ // Store the methods
+ self->methods = methods;
+
+ // Initialize the module
+ r = collecty_module_init(self);
+ if (r < 0)
+ goto ERROR;
+
+ // Return the pointer
+ *module = self;
return 0;
+
+ERROR:
+ if (self)
+ collecty_module_unref(self);
+
+ return r;
+}
+
+collecty_module* collecty_module_ref(collecty_module* self) {
+ ++self->nrefs;
+ return self;
+}
+
+collecty_module* collecty_module_unref(collecty_module* self) {
+ if (--self->nrefs > 0)
+ return self;
+
+ collecty_module_free(self);
+ return NULL;
+}
+
+const char* collecty_module_name(collecty_module* self) {
+ return self->methods->name;
}
#define COLLECTY_MODULE_H
#include "ctx.h"
+#include "daemon.h"
-typedef struct collecty_module {
+typedef struct collecty_module_methods {
const char* name;
// Init
int (*init)(collecty_ctx* ctx);
- // Shutdown
- int (*shutdown)(collecty_ctx* ctx);
-} collecty_module;
+ // Free
+ int (*free)(collecty_ctx* ctx);
+} collecty_module_methods;
-int collecty_module_init(collecty_ctx* ctx, collecty_module* module);
-int collecty_module_shutdown(collecty_ctx* ctx, collecty_module* module);
+typedef struct collecty_module collecty_module;
+
+int collecty_module_create(collecty_module** module,
+ collecty_ctx* ctx, collecty_daemon* daemon, const collecty_module_methods* methods);
+
+collecty_module* collecty_module_ref(collecty_module* self);
+collecty_module* collecty_module_unref(collecty_module* self);
+
+const char* collecty_module_name(collecty_module* self);
#endif /* COLLECTY_MODULE_H */
#############################################################################*/
#include <stddef.h>
+#include <sys/queue.h>
#include "ctx.h"
+#include "daemon.h"
#include "module.h"
#include "modules.h"
#include "modules/loadavg.h"
// Register all modules
-static collecty_module* modules[] = {
+static const collecty_module_methods* available_modules[] = {
&loadavg_module,
NULL,
};
-int collecty_modules_init(collecty_ctx* ctx) {
+struct module {
+ collecty_module* module;
+ STAILQ_ENTRY(module) nodes;
+};
+
+STAILQ_HEAD(modules, module) modules;
+
+int collecty_modules_init(collecty_ctx* ctx, collecty_daemon* daemon) {
+ collecty_module* module = NULL;
int r;
+ // Initialize the queue
+ STAILQ_INIT(&modules);
+
DEBUG(ctx, "Initializing all modules...\n");
// Initialize all modules
- for (collecty_module** m = modules; *m; m++) {
- r = collecty_module_init(ctx, *m);
+ for (const collecty_module_methods** m = available_modules; *m; m++) {
+ r = collecty_module_create(&module, ctx, daemon, *m);
if (r < 0)
return r;
}
return 0;
}
-int collecty_modules_shutdown(collecty_ctx* ctx) {
+int collecty_modules_shutdown(collecty_ctx* ctx, collecty_daemon* daemon) {
int r;
DEBUG(ctx, "Shutting down all modules...\n");
+#if 0
// Shutdown all modules
for (collecty_module** m = modules; *m; m++) {
r = collecty_module_shutdown(ctx, *m);
if (r < 0)
return r;
}
+#endif
return 0;
}
#define COLLECTY_MODULES_H
#include "ctx.h"
+#include "daemon.h"
-int collecty_modules_init(collecty_ctx* ctx);
-int collecty_modules_shutdown(collecty_ctx* ctx);
+int collecty_modules_init(collecty_ctx* ctx, collecty_daemon* daemon);
+int collecty_modules_shutdown(collecty_ctx* ctx, collecty_daemon* daemon);
#endif /* COLLECTY_MODULES_H */
#include "../ctx.h"
#include "loadavg.h"
-collecty_module loadavg_module = {
+const collecty_module_methods loadavg_module = {
.name = "loadavg",
};
#include "../module.h"
-extern collecty_module loadavg_module;
+extern const collecty_module_methods loadavg_module;
#endif /* COLLECTY_MODULE_LOADAVG_H */