Commit f1b2785f authored by Philipp Schafft's avatar Philipp Schafft

Feature: Changed refobject subsystem to use defined types

parent 1b6c5178
......@@ -37,16 +37,17 @@ static void __free(refobject_t self, void **userdata)
free(buffer->buffer);
}
REFOBJECT_DEFINE_TYPE(buffer_t,
REFOBJECT_DEFINE_TYPE_FREE(__free)
);
buffer_t * buffer_new(ssize_t preallocation, void *userdata, const char *name, refobject_t associated)
{
buffer_t *buffer = NULL;
refobject_t refobject = refobject_new(sizeof(*buffer), __free, userdata, name, associated);
buffer_t *buffer = refobject_new__new(buffer_t, userdata, name, associated);
if (REFOBJECT_IS_NULL(refobject))
if (!buffer)
return NULL;
buffer = REFOBJECT_TO_TYPE(refobject, buffer_t *);
if (preallocation > 0)
buffer_preallocate(buffer, preallocation);
......
......@@ -28,6 +28,8 @@
* This set of functions is intentinally not thread safe.
*/
REFOBJECT_FORWARD_TYPE(buffer_t);
/* This creates a new buffer object.
* Parameters:
* preallocation
......
......@@ -26,19 +26,19 @@
#ifdef FASTEVENT_ENABLED
struct registration {
typedef struct {
refobject_base_t __base;
fastevent_type_t type;
fastevent_cb_t cb;
fastevent_freecb_t freecb;
void *userdata;
};
} fastevent_registration_t;
struct eventrow {
size_t length;
size_t used;
struct registration **registrations;
fastevent_registration_t **registrations;
};
static struct eventrow fastevent_registrations[FASTEVENT_TYPE__END];
......@@ -54,9 +54,9 @@ static inline struct eventrow * __get_row(fastevent_type_t type)
return &(fastevent_registrations[idx]);
}
static int __add_to_row(struct eventrow * row, struct registration *registration)
static int __add_to_row(struct eventrow * row, fastevent_registration_t *registration)
{
struct registration **n;
fastevent_registration_t **n;
if (row == NULL)
return -1;
......@@ -77,7 +77,7 @@ static int __add_to_row(struct eventrow * row, struct registration *registration
return 0;
}
static int __remove_from_row(struct eventrow * row, struct registration *registration)
static int __remove_from_row(struct eventrow * row, fastevent_registration_t *registration)
{
size_t i;
......@@ -98,7 +98,7 @@ static int __remove_from_row(struct eventrow * row, struct registration *registr
static void __unregister(refobject_t self, void **userdata)
{
struct registration *registration = REFOBJECT_TO_TYPE(self, struct registration *);
fastevent_registration_t *registration = REFOBJECT_TO_TYPE(self, fastevent_registration_t *);
struct eventrow * row;
(void)userdata;
......@@ -143,11 +143,14 @@ int fastevent_shutdown(void)
return 0;
}
REFOBJECT_DEFINE_PRIVATE_TYPE(fastevent_registration_t,
REFOBJECT_DEFINE_TYPE_FREE(__unregister)
);
refobject_t fastevent_register(fastevent_type_t type, fastevent_cb_t cb, fastevent_freecb_t freecb, void *userdata)
{
struct eventrow * row;
struct registration *registration;
refobject_t ret;
fastevent_registration_t *registration;
if (cb == NULL)
return REFOBJECT_NULL;
......@@ -160,15 +163,13 @@ refobject_t fastevent_register(fastevent_type_t type, fastevent_cb_t cb, fasteve
return REFOBJECT_NULL;
}
ret = refobject_new(sizeof(struct registration), __unregister, NULL, NULL, NULL);
registration = refobject_new__new(fastevent_registration_t, NULL, NULL, NULL);
if (REFOBJECT_IS_NULL(ret)) {
if (!registration) {
thread_rwlock_unlock(&fastevent_lock);
return REFOBJECT_NULL;
}
registration = REFOBJECT_TO_TYPE(ret, struct registration *);
registration->type = type;
registration->cb = cb;
registration->freecb = freecb;
......@@ -176,12 +177,12 @@ refobject_t fastevent_register(fastevent_type_t type, fastevent_cb_t cb, fasteve
if (__add_to_row(row, registration) != 0) {
thread_rwlock_unlock(&fastevent_lock);
refobject_unref(ret);
refobject_unref((refobject_base_t*)registration);
return REFOBJECT_NULL;
}
thread_rwlock_unlock(&fastevent_lock);
return ret;
return (refobject_t)(refobject_base_t*)registration;
}
void fastevent_emit(fastevent_type_t type, fastevent_flag_t flags, fastevent_datatype_t datatype, ...)
......
......@@ -150,9 +150,13 @@ static void __listensocket_container_free(refobject_t self, void **userdata)
thread_mutex_destroy(&container->lock);
}
REFOBJECT_DEFINE_TYPE(listensocket_container_t,
REFOBJECT_DEFINE_TYPE_FREE(__listensocket_container_free)
);
listensocket_container_t * listensocket_container_new(void)
{
listensocket_container_t *self = REFOBJECT_TO_TYPE(refobject_new(sizeof(listensocket_container_t), __listensocket_container_free, NULL, NULL, NULL), listensocket_container_t *);
listensocket_container_t *self = refobject_new__new(listensocket_container_t, NULL, NULL, NULL);
if (!self)
return NULL;
......@@ -527,13 +531,17 @@ static void __listensocket_free(refobject_t self, void **userdata)
thread_mutex_destroy(&listensocket->lock);
}
REFOBJECT_DEFINE_TYPE(listensocket_t,
REFOBJECT_DEFINE_TYPE_FREE(__listensocket_free)
);
static listensocket_t * listensocket_new(const listener_t *listener) {
listensocket_t *self;
if (listener == NULL)
return NULL;
self = REFOBJECT_TO_TYPE(refobject_new(sizeof(listensocket_t), __listensocket_free, NULL, NULL, NULL), listensocket_t *);
self = refobject_new__new(listensocket_t, NULL, NULL, NULL);
if (!self)
return NULL;
......
......@@ -10,8 +10,11 @@
#define __LISTENSOCKET_H__
#include "icecasttypes.h"
#include "refobject.h"
#include "cfgfile.h"
REFOBJECT_FORWARD_TYPE(listensocket_container_t);
listensocket_container_t * listensocket_container_new(void);
int listensocket_container_configure(listensocket_container_t *self, const ice_config_t *config);
int listensocket_container_configure_and_setup(listensocket_container_t *self, const ice_config_t *config);
......@@ -20,6 +23,8 @@ connection_t * listensocket_container_accept(listensocket_container
int listensocket_container_set_sockcount_cb(listensocket_container_t *self, void (*cb)(size_t count, void *userdata), void *userdata);
ssize_t listensocket_container_sockcount(listensocket_container_t *self);
REFOBJECT_FORWARD_TYPE(listensocket_t);
int listensocket_refsock(listensocket_t *self);
int listensocket_unrefsock(listensocket_t *self);
connection_t * listensocket_accept(listensocket_t *self, listensocket_container_t *container);
......
......@@ -50,9 +50,13 @@ static void __module_container_free(refobject_t self, void **userdata)
avl_tree_free(cont->module, (avl_free_key_fun_type)refobject_unref);
}
REFOBJECT_DEFINE_TYPE(module_container_t,
REFOBJECT_DEFINE_TYPE_FREE(__module_container_free)
);
module_container_t * module_container_new(void)
{
module_container_t *ret = REFOBJECT_TO_TYPE(refobject_new(sizeof(module_container_t), __module_container_free, NULL, NULL, NULL), module_container_t *);
module_container_t *ret = refobject_new__new(module_container_t, NULL, NULL, NULL);
if (!ret)
return NULL;
......@@ -101,13 +105,13 @@ int module_container_delete_module(module_container_t *self,
module_t * module_container_get_module(module_container_t *self, const char *name)
{
refobject_t search;
refobject_base_t *search;
module_t *ret;
if (!self || !name)
return NULL;
search = refobject_new(sizeof(refobject_base_t), NULL, NULL, name, NULL);
search = refobject_new__new(refobject_base_t, NULL, name, NULL);
thread_mutex_lock(&(self->lock));
if (avl_get_by_key(self->module, REFOBJECT_TO_TYPE(search, void *), (void**)&ret) != 0) {
......@@ -168,9 +172,13 @@ static void __module_free(refobject_t self, void **userdata)
thread_mutex_destroy(&(mod->lock));
}
REFOBJECT_DEFINE_TYPE(module_t,
REFOBJECT_DEFINE_TYPE_FREE(__module_free)
);
module_t * module_new(const char *name, module_setup_handler_t newcb, module_setup_handler_t freecb, void *userdata)
{
module_t *ret = REFOBJECT_TO_TYPE(refobject_new(sizeof(module_t), __module_free, NULL, name, NULL), module_t *);
module_t *ret = refobject_new__new(module_t, NULL, name, NULL);
if (!ret)
return NULL;
......
......@@ -12,6 +12,7 @@
#include <libxml/tree.h>
#include "icecasttypes.h"
#include "refobject.h"
typedef void (*module_client_handler_function_t)(module_t *self, client_t *client);
typedef int (*module_setup_handler_t)(module_t *self, void **userdata);
......@@ -21,6 +22,9 @@ typedef struct {
module_client_handler_function_t cb;
} module_client_handler_t;
REFOBJECT_FORWARD_TYPE(module_container_t);
REFOBJECT_FORWARD_TYPE(module_t);
module_container_t * module_container_new(void);
int module_container_add_module(module_container_t *self, module_t *module);
int module_container_delete_module(module_container_t *self, const char *name);
......
......@@ -19,19 +19,29 @@
#define TO_BASE(x) REFOBJECT_TO_TYPE((x), refobject_base_t *)
refobject_t refobject_new(size_t len, refobject_free_t freecb, void *userdata, const char *name, refobject_t associated)
REFOBJECT_DEFINE_TYPE(refobject_base_t,
REFOBJECT_DEFINE_TYPE_FREE(NULL)
);
static inline int check_type(const refobject_type_t *type)
{
return type->control_length == sizeof(refobject_type_t) && type->control_version == REFOBJECT_CONTROL_VERSION &&
type->type_length >= sizeof(refobject_base_t);
}
refobject_t refobject_new__real(const refobject_type_t *type, void *userdata, const char *name, refobject_t associated)
{
refobject_base_t *ret = NULL;
if (len < sizeof(refobject_base_t))
if (!check_type(type))
return (refobject_t)ret;
ret = calloc(1, len);
ret = calloc(1, type->type_length);
if (ret == NULL)
return (refobject_t)ret;
ret->type = type;
ret->refc = 1;
ret->freecb = freecb;
ret->userdata = userdata;
thread_mutex_create(&(ret->lock));
......@@ -82,8 +92,8 @@ int refobject_unref(refobject_t self)
return 0;
}
if (base->freecb)
base->freecb(self, &(base->userdata));
if (base->type->type_freecb)
base->type->type_freecb(self, &(base->userdata));
if (base->userdata)
free(base->userdata);
......
......@@ -46,6 +46,18 @@
#define REFOBJECT_TO_TYPE(x,y) ((y)(x))
#endif
#define REFOBJECT_CONTROL_VERSION 0
#define REFOBJECT_FORWARD_TYPE(type) extern const refobject_type_t refobject_type__ ## type;
#define REFOBJECT_DEFINE_TYPE(type, extra) const refobject_type_t refobject_type__ ## type = { \
.control_length = sizeof(refobject_type_t), \
.control_version = REFOBJECT_CONTROL_VERSION, \
.type_length = sizeof(type), \
.type_name = # type, \
extra \
}
#define REFOBJECT_DEFINE_PRIVATE_TYPE(type, extra) static REFOBJECT_DEFINE_TYPE(type, extra)
#define REFOBJECT_DEFINE_TYPE_FREE(cb) .type_freecb = (cb)
/* Type used for callback called then the object is actually freed
* That is once all references to it are gone.
*
......@@ -56,18 +68,31 @@
*/
typedef void (*refobject_free_t)(refobject_t self, void **userdata);
/* Meta type used to defined types.
*/
typedef struct {
size_t control_length;
int control_version;
size_t type_length;
const char * type_name;
refobject_free_t type_freecb;
} refobject_type_t;
/* Only defined here as the size must be publically known.
* DO NOT use any of the members in here directly!
*/
struct refobject_base_tag {
const refobject_type_t* type;
size_t refc;
mutex_t lock;
void *userdata;
refobject_free_t freecb;
char *name;
refobject_t associated;
};
REFOBJECT_FORWARD_TYPE(refobject_base_t);
/* Create a new refobject
* The total length of the new object is given by len (see malloc(3)),
* the callback called on free is given by freecb (see refobject_free_t above),
......@@ -78,7 +103,8 @@ struct refobject_base_tag {
* All parameters beside len are optional and can be NULL/REFOBJECT_NULL.
* If no freecb is given the userdata is freed (see refobject_free_t above).
*/
refobject_t refobject_new(size_t len, refobject_free_t freecb, void *userdata, const char *name, refobject_t associated);
#define refobject_new__new(type, userdata, name, associated) REFOBJECT_TO_TYPE(refobject_new__real(&(refobject_type__ ## type), (userdata), (name), (associated)), type*)
refobject_t refobject_new__real(const refobject_type_t *type, void *userdata, const char *name, refobject_t associated);
/* This increases the reference counter of the object */
int refobject_ref(refobject_t self);
......
......@@ -236,6 +236,10 @@ static void __report_free(refobject_t self, void **userdata)
refobject_unref(report->root);
}
REFOBJECT_DEFINE_TYPE(reportxml_t,
REFOBJECT_DEFINE_TYPE_FREE(__report_free)
);
static reportxml_t * reportxml_new_with_root(reportxml_node_t *root)
{
reportxml_t *ret;
......@@ -243,7 +247,7 @@ static reportxml_t * reportxml_new_with_root(reportxml_node_t *root)
if (!root)
return NULL;
ret = REFOBJECT_TO_TYPE(refobject_new(sizeof(reportxml_t), __report_free, NULL, NULL, NULL), reportxml_t *);
ret = refobject_new__new(reportxml_t, NULL, NULL, NULL);
ret->root = root;
return ret;
......@@ -368,6 +372,10 @@ static void __report_node_free(refobject_t self, void **userdata)
free(node->xml_childs);
}
REFOBJECT_DEFINE_TYPE(reportxml_node_t,
REFOBJECT_DEFINE_TYPE_FREE(__report_node_free)
);
reportxml_node_t * reportxml_node_new(reportxml_node_type_t type, const char *id, const char *definition, const char *akindof)
{
reportxml_node_t *ret;
......@@ -377,7 +385,7 @@ reportxml_node_t * reportxml_node_new(reportxml_node_type_t type, const cha
if (!nodedef)
return NULL;
ret = REFOBJECT_TO_TYPE(refobject_new(sizeof(reportxml_node_t), __report_node_free, NULL, NULL, NULL), reportxml_node_t *);
ret = refobject_new__new(reportxml_node_t, NULL, NULL, NULL);
if (ret == NULL)
return NULL;
......@@ -975,9 +983,13 @@ static int __compare_definitions(void *arg, void *a, void *b)
return ret;
}
REFOBJECT_DEFINE_TYPE(reportxml_database_t,
REFOBJECT_DEFINE_TYPE_FREE(__database_free)
);
reportxml_database_t * reportxml_database_new(void)
{
reportxml_database_t *ret = REFOBJECT_TO_TYPE(refobject_new(sizeof(reportxml_database_t), __database_free, NULL, NULL, NULL), reportxml_database_t *);
reportxml_database_t *ret = refobject_new__new(reportxml_database_t, NULL, NULL, NULL);
if (!ret)
return NULL;
......
......@@ -15,6 +15,7 @@
#include "icecasttypes.h"
#include "compat.h"
#include "refobject.h"
/* XML Tag Types
* While a hint of what the nodes are used for is given, see the specification for more details.
......@@ -60,11 +61,13 @@ typedef enum {
REPORTXML_NODE_TYPE_EXTENSION
} reportxml_node_type_t;
REFOBJECT_FORWARD_TYPE(reportxml_t);
REFOBJECT_FORWARD_TYPE(reportxml_node_t);
REFOBJECT_FORWARD_TYPE(reportxml_database_t);
/* ---[ Document level ]--- */
/* The document object is NOT thread safe. */
/* This creates a new, empty report XML document */
reportxml_t * reportxml_new(void);
/* This gets the root node of a report XML document */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment