mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Merge branch 'ph3-update-refobject'
This commit is contained in:
commit
ed78741e3d
14
src/buffer.c
14
src/buffer.c
@ -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);
|
||||
|
24
src/module.c
24
src/module.c
@ -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);
|
||||
|
109
src/refobject.h
109
src/refobject.h
@ -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,6 +236,24 @@ static void __report_free(refobject_t self, void **userdata)
|
||||
refobject_unref(report->root);
|
||||
}
|
||||
|
||||
static int __report_new(refobject_t self, const refobject_type_t *type, va_list ap)
|
||||
{
|
||||
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 -1;
|
||||
|
||||
ret->root = root;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_t *ret;
|
||||
@ -243,7 +261,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;
|
||||
@ -251,20 +269,7 @@ static reportxml_t * reportxml_new_with_root(reportxml_node_t *root)
|
||||
|
||||
reportxml_t * reportxml_new(void)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return refobject_new(reportxml_t);
|
||||
}
|
||||
|
||||
reportxml_node_t * reportxml_get_root_node(reportxml_t *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 *);
|
||||
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
ret->definitions = avl_tree_new(__compare_definitions, NULL);
|
||||
if (!ret->definitions) {
|
||||
refobject_unref(ret);
|
||||
return NULL;
|
||||
}
|
||||
reportxml_database_t *ret = REFOBJECT_TO_TYPE(self, reportxml_database_t*);
|
||||
|
||||
thread_mutex_create(&(ret->lock));
|
||||
|
||||
return ret;
|
||||
ret->definitions = avl_tree_new(__compare_definitions, NULL);
|
||||
if (!ret->definitions)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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.");
|
||||
|
@ -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,12 +61,16 @@ 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 */
|
||||
/* Depreciated: This creates a new, empty report XML document
|
||||
* Do NOT use this. Use refobject_new(reportxml_t)
|
||||
*/
|
||||
reportxml_t * reportxml_new(void);
|
||||
/* This gets the root node of a report XML document */
|
||||
reportxml_node_t * reportxml_get_root_node(reportxml_t *report);
|
||||
@ -125,7 +130,9 @@ xmlNodePtr reportxml_node_get_xml_child(reportxml_node_t *node, siz
|
||||
/* The database object is thread safe. */
|
||||
|
||||
|
||||
/* Create a new database object */
|
||||
/* Depreciated: Create a new database object
|
||||
* Do NOT use this. Use refobject_new(reportxml_database_t)
|
||||
*/
|
||||
reportxml_database_t * reportxml_database_new(void);
|
||||
/* Add an report to the database */
|
||||
int reportxml_database_add_report(reportxml_database_t *db, reportxml_t *report);
|
||||
|
@ -25,7 +25,7 @@ static void test_create_ref_unref(void)
|
||||
ctest_test("buffer created", a != NULL);
|
||||
ctest_test("un-referenced", refobject_unref(a) == 0);
|
||||
|
||||
a = buffer_new_simple();
|
||||
a = refobject_new(buffer_t);
|
||||
ctest_test("buffer created", a != NULL);
|
||||
ctest_test("un-referenced", refobject_unref(a) == 0);
|
||||
|
||||
@ -80,10 +80,10 @@ static void test_userdata(void)
|
||||
|
||||
static void test_associated(void)
|
||||
{
|
||||
refobject_t a;
|
||||
refobject_base_t *a;
|
||||
buffer_t *b;
|
||||
|
||||
a = refobject_new(sizeof(refobject_base_t), NULL, NULL, NULL, REFOBJECT_NULL);
|
||||
a = refobject_new(refobject_base_t);
|
||||
ctest_test("refobject created", !REFOBJECT_IS_NULL(a));
|
||||
|
||||
|
||||
@ -102,7 +102,7 @@ static void test_empty(void)
|
||||
const char *string;
|
||||
int ret;
|
||||
|
||||
a = buffer_new_simple();
|
||||
a = refobject_new(buffer_t);
|
||||
ctest_test("buffer created", a != NULL);
|
||||
|
||||
ret = buffer_get_data(a, &data, &length);
|
||||
@ -147,7 +147,7 @@ static void test_string(void)
|
||||
const char *string = NULL;
|
||||
int ret;
|
||||
|
||||
a = buffer_new_simple();
|
||||
a = refobject_new(buffer_t);
|
||||
ctest_test("buffer created", a != NULL);
|
||||
ctest_test("pushed string", buffer_push_string(a, hw) == 0);
|
||||
ret = buffer_get_string(a, &string);
|
||||
@ -182,7 +182,7 @@ static void test_binary(void)
|
||||
size_t length;
|
||||
const void *data;
|
||||
|
||||
a = buffer_new_simple();
|
||||
a = refobject_new(buffer_t);
|
||||
ctest_test("buffer created", a != NULL);
|
||||
|
||||
ctest_test("pushed data pattern a", buffer_push_data(a, pattern_a, sizeof(pattern_a)) == 0);
|
||||
@ -238,7 +238,7 @@ static void test_shift(void)
|
||||
buffer_t *a;
|
||||
const char *pattern = "AABBBCC";
|
||||
|
||||
a = buffer_new_simple();
|
||||
a = refobject_new(buffer_t);
|
||||
ctest_test("buffer created", a != NULL);
|
||||
|
||||
ctest_test("pushed string", buffer_push_string(a, pattern) == 0);
|
||||
@ -264,7 +264,7 @@ static void test_length(void)
|
||||
const char *match_b = "AABB";
|
||||
const char *match_c = "";
|
||||
|
||||
a = buffer_new_simple();
|
||||
a = refobject_new(buffer_t);
|
||||
ctest_test("buffer created", a != NULL);
|
||||
|
||||
ctest_test("pushed string", buffer_push_string(a, pattern) == 0);
|
||||
@ -290,7 +290,7 @@ static void test_printf(void)
|
||||
const char *match_b = ":Hello World!:<-127 >";
|
||||
const char *match_c = ":Hello World!:<-127 >? +127?";
|
||||
|
||||
a = buffer_new_simple();
|
||||
a = refobject_new(buffer_t);
|
||||
ctest_test("buffer created", a != NULL);
|
||||
|
||||
ctest_test("Set length to match pattern a", buffer_push_printf(a, ":%s:", str) == 0);
|
||||
@ -310,9 +310,9 @@ static void test_push_buffer(void)
|
||||
const char *pattern = "AABBBCC";
|
||||
const char *match_a = "AABBBCCAABBBCC";
|
||||
|
||||
a = buffer_new_simple();
|
||||
a = refobject_new(buffer_t);
|
||||
ctest_test("buffer a created", a != NULL);
|
||||
b = buffer_new_simple();
|
||||
b = refobject_new(buffer_t);
|
||||
ctest_test("buffer b created", b != NULL);
|
||||
|
||||
ctest_test("pushed string", buffer_push_string(a, pattern) == 0);
|
||||
|
@ -29,9 +29,9 @@ static void test_ptr(void)
|
||||
|
||||
static void test_create_ref_unref(void)
|
||||
{
|
||||
refobject_t a;
|
||||
refobject_base_t *a;
|
||||
|
||||
a = refobject_new(sizeof(refobject_base_t), NULL, NULL, NULL, REFOBJECT_NULL);
|
||||
a = refobject_new(refobject_base_t);
|
||||
ctest_test("refobject created", !REFOBJECT_IS_NULL(a));
|
||||
|
||||
ctest_test("referenced", refobject_ref(a) == 0);
|
||||
@ -39,27 +39,91 @@ static void test_create_ref_unref(void)
|
||||
ctest_test("un-referenced (2 of 2)", refobject_unref(a) == 0);
|
||||
}
|
||||
|
||||
static void test_typename(void)
|
||||
{
|
||||
refobject_base_t *a;
|
||||
const char *typename;
|
||||
|
||||
a = refobject_new(refobject_base_t);
|
||||
ctest_test("refobject created", !REFOBJECT_IS_NULL(a));
|
||||
|
||||
typename = REFOBJECT_GET_TYPENAME(a);
|
||||
ctest_test("got typename", typename != NULL);
|
||||
ctest_test("typename matches", strcmp(typename, "refobject_base_t") == 0);
|
||||
|
||||
ctest_test("un-referenced", refobject_unref(a) == 0);
|
||||
}
|
||||
|
||||
static void test_valid(void)
|
||||
{
|
||||
refobject_base_t *a;
|
||||
|
||||
typedef struct {
|
||||
refobject_base_t __base;
|
||||
} ctest_test_type_t;
|
||||
|
||||
REFOBJECT_DEFINE_PRIVATE_TYPE(ctest_test_type_t);
|
||||
|
||||
ctest_test("NULL is not valid", !REFOBJECT_IS_VALID(REFOBJECT_NULL, refobject_base_t));
|
||||
|
||||
a = refobject_new(refobject_base_t);
|
||||
ctest_test("refobject created", !REFOBJECT_IS_NULL(a));
|
||||
|
||||
ctest_test("is valid", REFOBJECT_IS_VALID(a, refobject_base_t));
|
||||
ctest_test("is valid as diffrent type", !REFOBJECT_IS_VALID(a, ctest_test_type_t));
|
||||
|
||||
ctest_test("un-referenced", refobject_unref(a) == 0);
|
||||
}
|
||||
|
||||
static void test_sizes(void)
|
||||
{
|
||||
refobject_t a;
|
||||
|
||||
a = refobject_new(sizeof(refobject_base_t) + 1024, NULL, NULL, NULL, REFOBJECT_NULL);
|
||||
typedef struct {
|
||||
refobject_base_t __base;
|
||||
char padding[1024];
|
||||
} ctest_test_type_a_t;
|
||||
REFOBJECT_DEFINE_PRIVATE_TYPE(ctest_test_type_a_t,
|
||||
REFOBJECT_DEFINE_TYPE_NEW_NOOP()
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
refobject_base_t __base;
|
||||
char padding[131072];
|
||||
} ctest_test_type_b_t;
|
||||
REFOBJECT_DEFINE_PRIVATE_TYPE(ctest_test_type_b_t,
|
||||
REFOBJECT_DEFINE_TYPE_NEW_NOOP()
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
char padding[sizeof(refobject_base_t) - 1];
|
||||
} ctest_test_type_c_t;
|
||||
REFOBJECT_DEFINE_PRIVATE_TYPE(ctest_test_type_c_t,
|
||||
REFOBJECT_DEFINE_TYPE_NEW_NOOP()
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
char padding[0];
|
||||
} ctest_test_type_d_t;
|
||||
REFOBJECT_DEFINE_PRIVATE_TYPE(ctest_test_type_d_t,
|
||||
REFOBJECT_DEFINE_TYPE_NEW_NOOP()
|
||||
);
|
||||
|
||||
a = REFOBJECT_FROM_TYPE(refobject_new(ctest_test_type_a_t));
|
||||
ctest_test("refobject created with size=sizeof(refobject_base_t) + 1024", !REFOBJECT_IS_NULL(a));
|
||||
ctest_test("un-referenced", refobject_unref(a) == 0);
|
||||
|
||||
a = refobject_new(sizeof(refobject_base_t) + 131072, NULL, NULL, NULL, REFOBJECT_NULL);
|
||||
a = REFOBJECT_FROM_TYPE(refobject_new(ctest_test_type_b_t));
|
||||
ctest_test("refobject created with size=sizeof(refobject_base_t) + 131072", !REFOBJECT_IS_NULL(a));
|
||||
ctest_test("un-referenced", refobject_unref(a) == 0);
|
||||
|
||||
if (sizeof(refobject_base_t) >= 1) {
|
||||
a = refobject_new(sizeof(refobject_base_t) - 1, NULL, NULL, NULL, REFOBJECT_NULL);
|
||||
ctest_test("refobject created with size=sizeof(refobject_base_t) - 1", REFOBJECT_IS_NULL(a));
|
||||
if (!REFOBJECT_IS_NULL(a)) {
|
||||
ctest_test("un-referenced", refobject_unref(a) == 0);
|
||||
}
|
||||
a = REFOBJECT_FROM_TYPE(refobject_new(ctest_test_type_c_t));
|
||||
ctest_test("refobject created with size=sizeof(refobject_base_t) - 1", REFOBJECT_IS_NULL(a));
|
||||
if (!REFOBJECT_IS_NULL(a)) {
|
||||
ctest_test("un-referenced", refobject_unref(a) == 0);
|
||||
}
|
||||
|
||||
a = refobject_new(0, NULL, NULL, NULL, REFOBJECT_NULL);
|
||||
a = REFOBJECT_FROM_TYPE(refobject_new(ctest_test_type_d_t));
|
||||
ctest_test("refobject created with size=0", REFOBJECT_IS_NULL(a));
|
||||
if (!REFOBJECT_IS_NULL(a)) {
|
||||
ctest_test("un-referenced", refobject_unref(a) == 0);
|
||||
@ -68,11 +132,11 @@ static void test_sizes(void)
|
||||
|
||||
static void test_name(void)
|
||||
{
|
||||
refobject_t a;
|
||||
refobject_base_t *a;
|
||||
const char *name = "test object name";
|
||||
const char *ret;
|
||||
|
||||
a = refobject_new(sizeof(refobject_base_t), NULL, NULL, name, REFOBJECT_NULL);
|
||||
a = refobject_new_ext(refobject_base_t, NULL, name, REFOBJECT_NULL);
|
||||
ctest_test("refobject created", !REFOBJECT_IS_NULL(a));
|
||||
|
||||
ret = refobject_get_name(a);
|
||||
@ -84,12 +148,12 @@ static void test_name(void)
|
||||
|
||||
static void test_userdata(void)
|
||||
{
|
||||
refobject_t a;
|
||||
refobject_base_t *a;
|
||||
int tmp = 0;
|
||||
void *userdata = &tmp;
|
||||
void *ret;
|
||||
|
||||
a = refobject_new(sizeof(refobject_base_t), NULL, NULL, NULL, REFOBJECT_NULL);
|
||||
a = refobject_new(refobject_base_t);
|
||||
ctest_test("refobject created", !REFOBJECT_IS_NULL(a));
|
||||
|
||||
ret = refobject_get_userdata(a);
|
||||
@ -103,7 +167,7 @@ static void test_userdata(void)
|
||||
|
||||
ctest_test("un-referenced", refobject_unref(a) == 0);
|
||||
|
||||
a = refobject_new(sizeof(refobject_base_t), NULL, userdata, NULL, REFOBJECT_NULL);
|
||||
a = refobject_new_ext(refobject_base_t, userdata, NULL, REFOBJECT_NULL);
|
||||
ctest_test("refobject created", !REFOBJECT_IS_NULL(a));
|
||||
ret = refobject_get_userdata(a);
|
||||
ctest_test("get userdata", ret == userdata);
|
||||
@ -115,12 +179,12 @@ static void test_userdata(void)
|
||||
|
||||
static void test_associated(void)
|
||||
{
|
||||
refobject_t a, b;
|
||||
refobject_base_t *a, *b;
|
||||
|
||||
a = refobject_new(sizeof(refobject_base_t), NULL, NULL, NULL, REFOBJECT_NULL);
|
||||
a = refobject_new(refobject_base_t);
|
||||
ctest_test("refobject created", !REFOBJECT_IS_NULL(a));
|
||||
|
||||
b = refobject_new(sizeof(refobject_base_t), NULL, NULL, NULL, a);
|
||||
b = refobject_new_ext(refobject_base_t, NULL, NULL, a);
|
||||
ctest_test("refobject created with associated", !REFOBJECT_IS_NULL(b));
|
||||
|
||||
ctest_test("un-referenced (1 of 2)", refobject_unref(b) == 0);
|
||||
@ -135,22 +199,30 @@ static void test_freecb__freecb(refobject_t self, void **userdata)
|
||||
|
||||
static void test_freecb(void)
|
||||
{
|
||||
refobject_t a;
|
||||
typedef struct {
|
||||
refobject_base_t __base;
|
||||
} ctest_test_type_t;
|
||||
ctest_test_type_t *a;
|
||||
|
||||
REFOBJECT_DEFINE_PRIVATE_TYPE(ctest_test_type_t,
|
||||
REFOBJECT_DEFINE_TYPE_FREE(test_freecb__freecb),
|
||||
REFOBJECT_DEFINE_TYPE_NEW_NOOP()
|
||||
);
|
||||
|
||||
test_freecb__called = 0;
|
||||
a = refobject_new(sizeof(refobject_base_t), test_freecb__freecb, NULL, NULL, REFOBJECT_NULL);
|
||||
ctest_test("refobject created", !REFOBJECT_IS_NULL(a));
|
||||
ctest_test("un-referenced", refobject_unref(a) == 0);
|
||||
a = refobject_new(ctest_test_type_t);
|
||||
ctest_test("refobject created", a != NULL);
|
||||
ctest_test("un-referenced", refobject_unref(REFOBJECT_FROM_TYPE(a)) == 0);
|
||||
ctest_test("freecb called", test_freecb__called == 1);
|
||||
|
||||
test_freecb__called = 0;
|
||||
a = refobject_new(sizeof(refobject_base_t), test_freecb__freecb, NULL, NULL, REFOBJECT_NULL);
|
||||
ctest_test("refobject created", !REFOBJECT_IS_NULL(a));
|
||||
ctest_test("referenced", refobject_ref(a) == 0);
|
||||
a = refobject_new(ctest_test_type_t);
|
||||
ctest_test("refobject created", a != NULL);
|
||||
ctest_test("referenced", refobject_ref(REFOBJECT_FROM_TYPE(a)) == 0);
|
||||
ctest_test("freecb uncalled", test_freecb__called == 0);
|
||||
ctest_test("un-referenced (1 of 2)", refobject_unref(a) == 0);
|
||||
ctest_test("un-referenced (1 of 2)", refobject_unref(REFOBJECT_FROM_TYPE(a)) == 0);
|
||||
ctest_test("freecb uncalled", test_freecb__called == 0);
|
||||
ctest_test("un-referenced (2 of 2)", refobject_unref(a) == 0);
|
||||
ctest_test("un-referenced (2 of 2)", refobject_unref(REFOBJECT_FROM_TYPE(a)) == 0);
|
||||
ctest_test("freecb called", test_freecb__called == 1);
|
||||
}
|
||||
|
||||
@ -167,6 +239,9 @@ int main (void)
|
||||
|
||||
test_create_ref_unref();
|
||||
|
||||
test_typename();
|
||||
test_valid();
|
||||
|
||||
test_sizes();
|
||||
|
||||
test_name();
|
||||
|
Loading…
Reference in New Issue
Block a user