Commit ed78741e authored by Philipp Schafft's avatar Philipp Schafft

Merge branch 'ph3-update-refobject'

parents 07899c4a d8c887aa
......@@ -37,16 +37,18 @@ static void __free(refobject_t self, void **userdata)
free(buffer->buffer);
}
REFOBJECT_DEFINE_TYPE(buffer_t,
REFOBJECT_DEFINE_TYPE_FREE(__free),
REFOBJECT_DEFINE_TYPE_NEW_NOOP()
);
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_ext(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);
......@@ -55,7 +57,7 @@ buffer_t * buffer_new(ssize_t preallocation, void *userdata, const char *name,
buffer_t * buffer_new_simple(void)
{
return buffer_new(-1, NULL, NULL, REFOBJECT_NULL);
return refobject_new(buffer_t);
}
void buffer_preallocate(buffer_t *buffer, size_t request)
......
......@@ -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
......@@ -37,7 +39,9 @@
*/
buffer_t * buffer_new(ssize_t preallocation, void *userdata, const char *name, refobject_t associated);
/* This creates a new buffer with defaults.
/* Depreciated: This creates a new buffer with defaults.
* Do NOT use this. Use refobject_new(buffer_t)
*
* This is the same as:
* buffer_new(-1, NULL, NULL, REFOBJECT_NULL)
*/
......
......@@ -232,7 +232,7 @@ void config_init_configuration(ice_config_t *configuration)
{
memset(configuration, 0, sizeof(ice_config_t));
_set_defaults(configuration);
configuration->reportxml_db = reportxml_database_new();
configuration->reportxml_db = refobject_new(reportxml_database_t);
}
static inline void __read_int(xmlDocPtr doc, xmlNodePtr node, int *val, const char *warning)
......
......@@ -661,7 +661,7 @@ reportxml_t *client_get_reportxml(const char *state_definition, const char *stat
if (!report) {
reportxml_node_t *rootnode, *incidentnode, *statenode;
report = reportxml_new();
report = refobject_new(reportxml_t);
rootnode = reportxml_get_root_node(report);
incidentnode = reportxml_node_new(REPORTXML_NODE_TYPE_INCIDENT, NULL, NULL, NULL);
statenode = reportxml_node_new(REPORTXML_NODE_TYPE_STATE, NULL, state_definition, state_akindof);
......
......@@ -1703,7 +1703,7 @@ void connection_setup_sockets (ice_config_t *config)
allowed_ip = matchfile_new(config->allowfile);
}
global.listensockets = listensocket_container_new();
global.listensockets = refobject_new(listensocket_container_t);
listensocket_container_configure(global.listensockets, config);
global_unlock();
......
......@@ -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_FROM_TYPE(registration));
return REFOBJECT_NULL;
}
thread_rwlock_unlock(&fastevent_lock);
return ret;
return REFOBJECT_FROM_TYPE(registration);
}
void fastevent_emit(fastevent_type_t type, fastevent_flag_t flags, fastevent_datatype_t datatype, ...)
......
......@@ -15,7 +15,7 @@
#endif
#include <stdarg.h>
#include <refobject.h>
#include "refobject.h"
typedef enum {
FASTEVENT_TYPE_SLOWEVENT = 0,
......
......@@ -38,7 +38,7 @@ void global_initialize(void)
global.clients = 0;
global.sources = 0;
global.source_tree = avl_tree_new(source_compare_sources, NULL);
global.modulecontainer = module_container_new();
global.modulecontainer = refobject_new(module_container_t);
thread_mutex_create(&_global_mutex);
}
......
......@@ -150,22 +150,25 @@ static void __listensocket_container_free(refobject_t self, void **userdata)
thread_mutex_destroy(&container->lock);
}
listensocket_container_t * listensocket_container_new(void)
int __listensocket_container_new(refobject_t self, const refobject_type_t *type, va_list ap)
{
listensocket_container_t *self = REFOBJECT_TO_TYPE(refobject_new(sizeof(listensocket_container_t), __listensocket_container_free, NULL, NULL, NULL), listensocket_container_t *);
if (!self)
return NULL;
listensocket_container_t *ret = REFOBJECT_TO_TYPE(self, listensocket_container_t*);
self->sock = NULL;
self->sock_len = 0;
self->sockcount_cb = NULL;
self->sockcount_userdata = NULL;
ret->sock = NULL;
ret->sock_len = 0;
ret->sockcount_cb = NULL;
ret->sockcount_userdata = NULL;
thread_mutex_create(&self->lock);
thread_mutex_create(&ret->lock);
return self;
return 0;
}
REFOBJECT_DEFINE_TYPE(listensocket_container_t,
REFOBJECT_DEFINE_TYPE_FREE(__listensocket_container_free),
REFOBJECT_DEFINE_TYPE_NEW(__listensocket_container_new)
);
static inline void __find_matching_entry(listensocket_container_t *self, const listener_t *listener, listensocket_t ***found, int **ref)
{
const listener_t *b;
......@@ -527,13 +530,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,20 +50,22 @@ static void __module_container_free(refobject_t self, void **userdata)
avl_tree_free(cont->module, (avl_free_key_fun_type)refobject_unref);
}
module_container_t * module_container_new(void)
int __module_container_new(refobject_t self, const refobject_type_t *type, va_list ap)
{
module_container_t *ret = REFOBJECT_TO_TYPE(refobject_new(sizeof(module_container_t), __module_container_free, NULL, NULL, NULL), module_container_t *);
if (!ret)
return NULL;
module_container_t *ret = REFOBJECT_TO_TYPE(self, module_container_t*);
thread_mutex_create(&(ret->lock));
ret->module = avl_tree_new(compare_refobject_t_name, NULL);
return ret;
return 0;
}
REFOBJECT_DEFINE_TYPE(module_container_t,
REFOBJECT_DEFINE_TYPE_FREE(__module_container_free),
REFOBJECT_DEFINE_TYPE_NEW(__module_container_new)
);
int module_container_add_module(module_container_t *self, module_t *module)
{
if (!self)
......@@ -101,13 +103,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 +170,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,7 +22,9 @@ typedef struct {
module_client_handler_function_t cb;
} module_client_handler_t;
module_container_t * module_container_new(void);
REFOBJECT_FORWARD_TYPE(module_container_t);
REFOBJECT_FORWARD_TYPE(module_t);
int module_container_add_module(module_container_t *self, module_t *module);
int module_container_delete_module(module_container_t *self, const char *name);
module_t * module_container_get_module(module_container_t *self, const char *name);
......
......@@ -19,19 +19,35 @@
#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)
int refobject_new__return_zero(refobject_t self, const refobject_type_t *type, va_list ap)
{
(void)self, (void)type, (void)ap;
return 0;
}
REFOBJECT_DEFINE_TYPE(refobject_base_t,
REFOBJECT_DEFINE_TYPE_NEW_NOOP()
);
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));
......@@ -56,6 +72,34 @@ refobject_t refobject_new(size_t len, refobject_free_t freecb, void *userdat
return (refobject_t)ret;
}
refobject_t refobject_new__simple(const refobject_type_t *type, void *userdata, const char *name, refobject_t associated, ...)
{
refobject_t ret;
int res;
va_list ap;
if (!check_type(type))
return REFOBJECT_NULL;
if (!type->type_newcb)
return REFOBJECT_NULL;
ret = refobject_new__real(type, userdata, name, associated);
if (REFOBJECT_IS_NULL(ret))
return REFOBJECT_NULL;
va_start(ap, associated);
res = type->type_newcb(ret, type, ap);
va_end(ap);
if (res != 0) {
refobject_unref(ret);
return REFOBJECT_NULL;
}
return ret;
}
int refobject_ref(refobject_t self)
{
if (REFOBJECT_IS_NULL(self))
......@@ -82,8 +126,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);
......
......@@ -17,6 +17,8 @@
#include <config.h>
#endif
#include <stdarg.h>
#include "common/thread/thread.h"
#include "icecasttypes.h"
......@@ -35,17 +37,82 @@
* as the operation is only defined for it's members.
* REFOBJECT_TO_TYPE(type,x)
* This casts the refobject (x) to the type (type).
* REFOBJECT_FROM_TYPE(x)
* Converts an object to a (refobject_t). This is the inverse of REFOBJECT_TO_TYPE().
* REFOBJECT_GET_TYPENAME(x)
* Get the name of the type of the object.
* REFOBJECT_IS_VALID(x,type)
* This returns true if x is not NULL and of type type.
* REFOBJECT_GET_BASE(x)
* REFOBJECT_GET_TYPE(x)
* Not to be used by the user.
*/
#ifdef HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION
#define REFOBJECT_NULL ((refobject_t)(refobject_base_t*)NULL)
#define REFOBJECT_GET_BASE(x) (((refobject_t)(x)).refobject_base)
#define REFOBJECT_IS_NULL(x) (((refobject_t)(x)).refobject_base == NULL)
#define REFOBJECT_TO_TYPE(x,y) ((y)(((refobject_t)(x)).refobject_base))
#else
#define REFOBJECT_NULL NULL
#define REFOBJECT_GET_BASE(x) ((refobject_base_t)(x))
#define REFOBJECT_IS_NULL(x) ((x) == NULL)
#define REFOBJECT_TO_TYPE(x,y) ((y)(x))
#endif
#define REFOBJECT_FROM_TYPE(x) ((refobject_t)(refobject_base_t*)(x))
#define REFOBJECT_GET_TYPE(x) (REFOBJECT_GET_BASE((x)) == NULL ? NULL : REFOBJECT_GET_BASE((x))->type)
#define REFOBJECT_GET_TYPENAME(x) (REFOBJECT_GET_TYPE((x)) == NULL ? NULL : REFOBJECT_GET_TYPE((x))->type_name)
#define REFOBJECT_IS_VALID(x,type) (!REFOBJECT_IS_NULL((x)) && REFOBJECT_GET_TYPE((x)) == (refobject_type__ ## type))
/* The following macros are used to define types.
*
* REFOBJECT_FORWARD_TYPE(type)
* Adds a forward decleration for the type. This is useful for non private types.
* REFOBJECT_DEFINE_TYPE(type,extras...)
* This defines a public type. One or more of the EXTRA macros be used.
* REFOBJECT_DEFINE_PRIVATE_TYPE(type,extras...)
* Same as REFOBJECT_DEFINE_TYPE() but defines private type.
*
* EXTRA Marcos:
* REFOBJECT_DEFINE_TYPE_FREE(cb)
* This defines a callback to be called when the object is freed.
* cb must be of type refobject_free_t.
* REFOBJECT_DEFINE_TYPE_NEW(cb)
* This defines a callback to be called when a new object is created.
* cb must be of type refobject_new_t.
* REFOBJECT_DEFINE_TYPE_NEW_NOOP()
* This installs a dummy callback for creation. This allows the type
* to be created using refobject_new(type) as with REFOBJECT_DEFINE_TYPE_NEW().
* This is useful for types that do not need to be initialized more than what
* refobject_new() already does.
*
* Other Macros:
* REFOBJECT_CONTROL_VERSION
* REFOBJECT_DEFINE_TYPE__RAW()
* Not to be used by the user.
*/
#define REFOBJECT_CONTROL_VERSION 1
#define REFOBJECT_FORWARD_TYPE(type) extern const refobject_type_t * refobject_type__ ## type;
#define REFOBJECT_DEFINE_TYPE__RAW(type, ...) \
static const refobject_type_t refobject_typedef__ ## type = \
{ \
.control_length = sizeof(refobject_type_t), \
.control_version = REFOBJECT_CONTROL_VERSION, \
.type_length = sizeof(type), \
.type_name = # type \
, ## __VA_ARGS__ \
}
#define REFOBJECT_DEFINE_TYPE(type, ...) REFOBJECT_DEFINE_TYPE__RAW(type, ## __VA_ARGS__); const refobject_type_t * refobject_type__ ## type = &refobject_typedef__ ## type
#define REFOBJECT_DEFINE_PRIVATE_TYPE(type, ...) REFOBJECT_DEFINE_TYPE__RAW(type, ## __VA_ARGS__); static const refobject_type_t * refobject_type__ ## type = &refobject_typedef__ ## type
#define REFOBJECT_DEFINE_TYPE_FREE(cb) .type_freecb = (cb)
#define REFOBJECT_DEFINE_TYPE_NEW(cb) .type_newcb = (cb)
#define REFOBJECT_DEFINE_TYPE_NEW_NOOP() .type_newcb = refobject_new__return_zero
typedef struct refobject_type_tag refobject_type_t;
int refobject_new__return_zero(refobject_t self, const refobject_type_t *type, va_list ap);
/* Type used for callback called then the object is actually freed
* That is once all references to it are gone.
*
......@@ -56,18 +123,52 @@
*/
typedef void (*refobject_free_t)(refobject_t self, void **userdata);
/* Type used for callback called then the object is created
* using the generic refobject_new().
*
* Additional parameters passed to refobject_new() are passed
* in the list ap. All limitations of <stdarg.h> apply.
*
* This function must return zero in case of success and
* non-zero in case of error. In case of error refobject_unref()
* is called internally to clear the object.
*/
typedef int (*refobject_new_t)(refobject_t self, const refobject_type_t *type, va_list ap);
/* Meta type used to defined types.
* DO NOT use any of the members in here directly!
*/
struct refobject_type_tag {
/* Size of this control structure */
size_t control_length;
/* ABI version of this structure */
int control_version;
/* Total length of the objects to be created */
size_t type_length;
/* Name of type */
const char * type_name;
/* Callback to be called on final free() */
refobject_free_t type_freecb;
/* Callback to be callback by refobject_new() */
refobject_new_t type_newcb;
};
/* 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 +179,11 @@ 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);
#define refobject_new(type, ...) REFOBJECT_TO_TYPE(refobject_new__simple((refobject_type__ ## type), NULL, NULL, REFOBJECT_NULL, ## __VA_ARGS__), type*)
#define refobject_new_ext(type, userdata, name, associated, ...) REFOBJECT_TO_TYPE(refobject_new__simple((refobject_type__ ## type), (userdata), (name), (associated), ## __VA_ARGS__), type*)
refobject_t refobject_new__simple(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,37 +236,42 @@ static void __report_free(refobject_t self, void **userdata)
refobject_unref(report->root);
}
static reportxml_t * reportxml_new_with_root(reportxml_node_t *root)
static int __report_new(refobject_t self, const refobject_type_t *type, va_list ap)
{
reportxml_t *ret;
reportxml_t *ret = REFOBJECT_TO_TYPE(self, reportxml_t*);
reportxml_node_t *root = reportxml_node_new(REPORTXML_NODE_TYPE_REPORT, NULL, NULL, NULL);
if (!root)
return NULL;
return -1;
ret = REFOBJECT_TO_TYPE(refobject_new(sizeof(reportxml_t), __report_free, NULL, NULL, NULL), reportxml_t *);
ret->root = root;
return ret;
return 0;
}
reportxml_t * reportxml_new(void)
REFOBJECT_DEFINE_TYPE(reportxml_t,
REFOBJECT_DEFINE_TYPE_FREE(__report_free),
REFOBJECT_DEFINE_TYPE_NEW(__report_new)
);
static reportxml_t * reportxml_new_with_root(reportxml_node_t *root)
{
reportxml_node_t *root = reportxml_node_new(REPORTXML_NODE_TYPE_REPORT, NULL, NULL, NULL);
reportxml_t *ret;
if (!root)
return NULL;
ret = reportxml_new_with_root(root);
if (!ret) {
refobject_unref(root);
return NULL;
}
ret = refobject_new__new(reportxml_t, NULL, NULL, NULL);
ret->root = root;
return ret;
}
reportxml_t * reportxml_new(void)
{
return refobject_new(reportxml_t);
}
reportxml_node_t * reportxml_get_root_node(reportxml_t *report)
{
if (!report)
......@@ -368,6 +373,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 +386,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,22 +984,27 @@ static int __compare_definitions(void *arg, void *a, void *b)
return ret;
}
reportxml_database_t * reportxml_database_new(void)
static int __database_new(refobject_t self, const refobject_type_t *type, va_list ap)
{
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_TO_TYPE(self, reportxml_database_t*);
if (!ret)
return NULL;
thread_mutex_create(&(ret->lock));
ret->definitions = avl_tree_new(__compare_definitions, NULL);
if (!ret->definitions) {
refobject_unref(ret);
return NULL;
}
if (!ret->definitions)
return -1;
thread_mutex_create(&(ret->lock));
return 0;
}
return ret;
REFOBJECT_DEFINE_TYPE(reportxml_database_t,
REFOBJECT_DEFINE_TYPE_FREE(__database_free),
REFOBJECT_DEFINE_TYPE_NEW(__database_new)
);
reportxml_database_t * reportxml_database_new(void)
{
return refobject_new(reportxml_database_t);
}
int reportxml_database_add_report(reportxml_database_t *db, reportxml_t *report)
......@@ -1293,7 +1307,7 @@ reportxml_t * reportxml_database_build_report(reportxml_database_t *db
/* Empty definition? Not exactly an exciting report... */
ICECAST_LOG_WARN("Empty definition for \"%H\". Returning empty report. This is likely an error.", id);
refobject_unref(definition);
return reportxml_new();
return refobject_new(reportxml_t);
}
if (type == REPORTXML_NODE_TYPE__ERROR) {
......@@ -1321,7 +1335,7 @@ reportxml_t * reportxml_database_build_report(reportxml_database_t *db
break;
}
ret = reportxml_new();
ret = refobject_new(reportxml_t);
if (!ret) {
refobject_unref(definition);
ICECAST_LOG_ERROR("Can not allocate new report. BAD.");
......