From ae3324ade282506976a21dbab487e99e41935b88 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Fri, 22 Mar 2013 20:01:57 -0700 Subject: [PATCH] object system: Introduced a concept of types. A type is defined by its size and init/destroy functions. This is now used when creating a new object (of that type) rather than passing all required callbacks to the object create function. --- src/core/object.c | 34 ++++++++++++++++++++-------------- src/core/plugin.c | 25 +++++++++++++++++++++---- src/core/store.c | 34 ++++++++++++++++++++++++++++------ src/include/core/object.h | 33 +++++++++++++++++++++++---------- 4 files changed, 92 insertions(+), 34 deletions(-) diff --git a/src/core/object.c b/src/core/object.c index 5ebcff2..8389c51 100644 --- a/src/core/object.c +++ b/src/core/object.c @@ -33,7 +33,7 @@ #include /* - * private helper functions + * private types */ static int @@ -62,26 +62,35 @@ sdb_object_wrapper_destroy(sdb_object_t *obj) SDB_OBJ_WRAPPER(obj)->data = NULL; } /* sdb_object_wrapper_destroy */ +static sdb_type_t sdb_object_wrapper_type = { + sizeof(sdb_object_wrapper_t), + + sdb_object_wrapper_init, + sdb_object_wrapper_destroy +}; + /* * public API */ sdb_object_t * -sdb_object_create(size_t size, int (*init)(sdb_object_t *, va_list), - void (*destructor)(sdb_object_t *), ...) +sdb_object_create(sdb_type_t type, ...) { sdb_object_t *obj; - obj = malloc(size); + if (type.size <= 0) + return NULL; + + obj = malloc(type.size); if (! obj) return NULL; memset(obj, 0, sizeof(*obj)); - if (init) { + if (type.init) { va_list ap; - va_start(ap, destructor); + va_start(ap, type); - if (init(obj, ap)) { + if (type.init(obj, ap)) { obj->ref_cnt = 1; sdb_object_deref(obj); va_end(ap); @@ -91,18 +100,15 @@ sdb_object_create(size_t size, int (*init)(sdb_object_t *, va_list), va_end(ap); } + obj->type = type; obj->ref_cnt = 1; - obj->destructor = destructor; - obj->size = size; return obj; } /* sdb_object_create */ sdb_object_t * sdb_object_create_wrapper(void *data, void (*destructor)(void *)) { - return sdb_object_create(sizeof(sdb_object_wrapper_t), - sdb_object_wrapper_init, sdb_object_wrapper_destroy, - data, destructor); + return sdb_object_create(sdb_object_wrapper_type, data, destructor); } /* sdb_object_create_wrapper */ void @@ -115,8 +121,8 @@ sdb_object_deref(sdb_object_t *obj) if (obj->ref_cnt > 0) return; - if (obj->destructor) - obj->destructor(obj); + if (obj->type.destroy) + obj->type.destroy(obj); free(obj); } /* sdb_object_deref */ diff --git a/src/core/plugin.c b/src/core/plugin.c index 5df7059..4312642 100644 --- a/src/core/plugin.c +++ b/src/core/plugin.c @@ -184,6 +184,10 @@ sdb_plugin_find_by_name(sdb_llist_t *list, const char *name) return SDB_PLUGIN_CB(obj); } /* sdb_plugin_find_by_name */ +/* + * private types + */ + static int sdb_plugin_cb_init(sdb_object_t *obj, va_list ap) { @@ -223,6 +227,20 @@ sdb_plugin_cb_destroy(sdb_object_t *obj) sdb_object_deref(SDB_PLUGIN_CB(obj)->cb_user_data); } /* sdb_plugin_cb_destroy */ +static sdb_type_t sdb_plugin_cb_type = { + sizeof(sdb_plugin_cb_t), + + sdb_plugin_cb_init, + sdb_plugin_cb_destroy +}; + +static sdb_type_t sdb_plugin_collector_cb_type = { + sizeof(sdb_plugin_collector_cb_t), + + sdb_plugin_cb_init, + sdb_plugin_cb_destroy +}; + static int sdb_plugin_add_callback(sdb_llist_t **list, const char *type, const char *name, void *callback, sdb_object_t *user_data) @@ -239,8 +257,8 @@ sdb_plugin_add_callback(sdb_llist_t **list, const char *type, if (! *list) return -1; - obj = sdb_object_create(sizeof(sdb_plugin_cb_t), sdb_plugin_cb_init, - sdb_plugin_cb_destroy, list, type, name, callback, user_data); + obj = sdb_object_create(sdb_plugin_cb_type, + list, type, name, callback, user_data); if (! obj) return -1; @@ -435,8 +453,7 @@ sdb_plugin_register_collector(const char *name, sdb_plugin_collector_cb callback if (! collector_list) return -1; - obj = sdb_object_create(sizeof(sdb_plugin_collector_cb_t), - sdb_plugin_cb_init, sdb_plugin_cb_destroy, + obj = sdb_object_create(sdb_plugin_collector_cb_type, &collector_list, "collector", name, callback, user_data); if (! obj) return -1; diff --git a/src/core/store.c b/src/core/store.c index 4e841ba..db57d2e 100644 --- a/src/core/store.c +++ b/src/core/store.c @@ -82,6 +82,10 @@ sdb_cmp_store_obj_with_name(const sdb_object_t *a, const sdb_object_t *b) return strcasecmp(obj->name, lookup->obj_name); } /* sdb_cmp_store_obj_with_name */ +/* + * private types + */ + static int sdb_host_init(sdb_object_t *obj, va_list ap) { @@ -175,6 +179,27 @@ sdb_svc_destroy(sdb_object_t *obj) free(SDB_SVC(obj)->_name); } /* sdb_svc_destroy */ +static sdb_type_t sdb_host_type = { + sizeof(sdb_host_t), + + sdb_host_init, + sdb_host_destroy +}; + +static sdb_type_t sdb_attr_type = { + sizeof(sdb_attribute_t), + + sdb_attr_init, + sdb_attr_destroy +}; + +static sdb_type_t sdb_svc_type = { + sizeof(sdb_service_t), + + sdb_svc_init, + sdb_svc_destroy +}; + /* * public API */ @@ -187,8 +212,7 @@ sdb_host_create(const char *name) if (! name) return NULL; - obj = sdb_object_create(sizeof(sdb_host_t), sdb_host_init, - sdb_host_destroy, name); + obj = sdb_object_create(sdb_host_type, name); if (! obj) return NULL; return SDB_HOST(obj); @@ -340,8 +364,7 @@ sdb_attribute_create(const char *hostname, if ((! hostname) || (! name) || (! value)) return NULL; - obj = sdb_object_create(sizeof(sdb_attribute_t), sdb_attr_init, - sdb_attr_destroy, hostname, name, value); + obj = sdb_object_create(sdb_attr_type, hostname, name, value); if (! obj) return NULL; return SDB_ATTR(obj); @@ -440,8 +463,7 @@ sdb_service_create(const char *hostname, const char *name) if ((! hostname) || (! name)) return NULL; - obj = sdb_object_create(sizeof(sdb_service_t), sdb_svc_init, - sdb_svc_destroy, hostname, name); + obj = sdb_object_create(sdb_svc_type, hostname, name); if (! obj) return NULL; return SDB_SVC(obj); diff --git a/src/include/core/object.h b/src/include/core/object.h index f2992c7..cab77d0 100644 --- a/src/include/core/object.h +++ b/src/include/core/object.h @@ -35,15 +35,25 @@ extern "C" { #endif +struct sdb_type; +typedef struct sdb_type sdb_type_t; + struct sdb_object; typedef struct sdb_object sdb_object_t; -struct sdb_object { - int ref_cnt; - void (*destructor)(sdb_object_t *); +struct sdb_type { size_t size; + + int (*init)(sdb_object_t *, va_list); + void (*destroy)(sdb_object_t *); }; -#define SDB_OBJECT_INIT { 1, NULL, 0 } +#define SDB_TYPE_INIT { 0, NULL, NULL } + +struct sdb_object { + sdb_type_t type; + int ref_cnt; +}; +#define SDB_OBJECT_INIT { SDB_TYPE_INIT, 1 } typedef struct { sdb_object_t super; @@ -56,14 +66,15 @@ typedef struct { /* * sdb_object_create: - * Allocates a new sdb_object_t of the specified 'size'. The object will be + * Allocates a new sdb_object_t of the specified 'type'. The object will be * initialized to zero and then passed on to the 'init' function (if - * specified). If specified, the 'destructor' will be called, when the + * specified). If specified, the 'destroy' callback will be called, when the * reference count drops to zero and before freeing the memory allocated by * the object itself. * - * If the init function fails (returns a non-zero value), the object will be - * destructed and destroyed. + * The init function will be called with the remaining arguments passed to + * sdb_object_create. If the init function fails (returns a non-zero value), + * the object will be destructed and destroyed. * * The reference count of the new object will be 1. * @@ -72,12 +83,14 @@ typedef struct { * - NULL on error */ sdb_object_t * -sdb_object_create(size_t size, int (*init)(sdb_object_t *, va_list), - void (*destructor)(sdb_object_t *), ...); +sdb_object_create(sdb_type_t type, ...); /* * sdb_object_create_wrapper: * Create a new sdb_object_t wrapping some arbitrary other object. + * + * Creation and initialization of the wrapped object needs to happen outside + * of the SysDB object system. */ sdb_object_t * sdb_object_create_wrapper(void *data, void (*destructor)(void *)); -- 2.30.2