1
0
mirror of https://gitlab.xiph.org/xiph/icecast-common.git synced 2024-09-22 04:15:55 -04:00

Feature: Outlined new refobject API

This commit is contained in:
Philipp Schafft 2018-10-31 16:17:57 +00:00
parent 9b26fdf57d
commit 904ddf1c39
3 changed files with 148 additions and 0 deletions

View File

@ -24,6 +24,111 @@
extern "C" {
#endif
#include <stdarg.h>
#include "types.h"
#include "thread.h"
/* Type used for callback called then the object is actually freed
* That is once all references to it are gone.
*
* This function must not try to deallocate or alter self.
*/
typedef void (*igloo_ro_free_t)(igloo_ro_t self);
/* Type used for callback called then the object is created
* using the generic igloo_ro_new().
*
* Additional parameters passed to igloo_ro_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 igloo_ro_unref()
* is called internally to clear the object.
*/
typedef int (*igloo_ro_new_t)(igloo_ro_t self, const igloo_ro_type_t *type, va_list ap);
/* Meta type used to defined types.
* DO NOT use any of the members in here directly!
*/
/* ---[ PRIVATE ]--- */
/*
* Those types are defined here as they must be known to the compiler.
* Nobody should ever try to access them directly.
*/
struct igloo_ro_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() */
igloo_ro_free_t type_freecb;
/* Callback to be callback by igloo_ro_new() */
igloo_ro_new_t type_newcb;
};
struct igloo_ro_base_tag {
/* Type of the object */
const igloo_ro_type_t * type;
/* Reference counter */
size_t refc;
/* Mutex for igloo_ro_*(). */
igloo_mutex_t lock;
/* Name of the object. */
char * name;
/* Associated objects */
igloo_ro_t associated;
};
/* ---[ END PRIVATE ]--- */
#ifdef igloo_HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION
#define igloo_RO__GETBASE(x) (((igloo_ro_t)(x)).subtype__igloo_ro_base_t)
#define igloo_RO_NULL ((igloo_ro_t)(igloo_ro_base_t*)NULL)
#define igloo_RO_IS_NULL(x) (igloo_RO__GETBASE((x)) == NULL)
#define igloo_RO_TO_TYPE(x,type) (igloo_RO_IS_VALID((x),type) ? NULL : ((igloo_ro_t)(x)).subtype__ ## type)
#else
#define igloo_RO__GETBASE(x) ((igloo_ro_base_t*)(x))
#define igloo_RO_NULL NULL
#define igloo_RO_IS_NULL(x) ((x) == NULL)
#define igloo_RO_TO_TYPE(x,type) ((type*)(x))
#endif
#define igloo_RO_GET_TYPE(x) (igloo_RO__GETBASE((x)) == NULL ? NULL : igloo_RO__GETBASE((x))->type)
#define igloo_RO_GET_TYPENAME(x) (igloo_RO_GET_TYPE((x)) == NULL ? NULL : igloo_RO_GET_TYPE((x))->type_name)
#define igloo_RO_IS_VALID(x,type) (!igloo_RO_IS_NULL((x)) && igloo_RO_GET_TYPE((x)) == (igloo_ro__type__ ## type))
/* Create a new refobject
* The type argument gives the type for the new object,
* the name for the object is given by name, and
* the associated refobject is given by associated.
*/
igloo_ro_t igloo_ro_new__raw(const igloo_ro_type_t *type, const char *name, igloo_ro_t associated);
#define igloo_ro_new_raw(type, name, associated) igloo_RO_TO_TYPE(igloo_ro_new__raw((igloo_ro__type__ ## type), (name), (associated)), type)
igloo_ro_t igloo_ro_new__simple(const igloo_ro_type_t *type, const char *name, igloo_ro_t associated, ...);
#define igloo_ro_new(type, ...) igloo_RO_TO_TYPE(igloo_ro_new__simple((igloo_ro__type__ ## type), NULL, igloo_RO_NULL, ## __VA_ARGS__), type)
#define igloo_ro_new_ext(type, name, associated, ...) igloo_RO_TO_TYPE(igloo_ro_new__simple((igloo_ro__type__ ## type), (name), (associated), ## __VA_ARGS__), type)
/* This increases the reference counter of the object */
int igloo_ro_ref(igloo_ro_t self);
/* This decreases the reference counter of the object.
* If the object's reference counter reaches zero the object is freed.
*/
int igloo_ro_unref(igloo_ro_t self);
/* This gets the object's name */
const char * igloo_ro_get_name(igloo_ro_t self);
/* This gets the object's associated object. */
igloo_ro_t igloo_ro_get_associated(igloo_ro_t self);
int igloo_ro_set_associated(igloo_ro_t self, igloo_ro_t associated);
#ifdef __cplusplus
}
#endif

View File

@ -28,6 +28,9 @@ extern "C" {
* This header must be included before "types.h" and "ro.h" if used.
*/
#define igloo_RO_TYPE(type) type * subtype__ ## type;
#define igloo_RO_FORWARD_TYPE(type) extern const igloo_ro_type_t *igloo_ro__type__ ## type
#ifdef __cplusplus
}
#endif

View File

@ -24,6 +24,46 @@
extern "C" {
#endif
/* For NULL */
#include <stddef.h>
/* For size_t and ssize_t */
#include <sys/types.h>
/* Included in case is not yet included */
#include "typedef.h"
/*
* This header includes forward declarations for several basic types.
*/
typedef struct igloo_ro_type_tag igloo_ro_type_t;
typedef struct igloo_ro_base_tag igloo_ro_base_t;
igloo_RO_FORWARD_TYPE(igloo_ro_base_t);
#ifdef igloo_HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION
typedef union __attribute__ ((__transparent_union__)) {
/* Those are libigloo's own types */
igloo_RO_TYPE(igloo_ro_base_t)
/* Now we add the current compilation unit's private types if any */
#ifdef igloo_RO_PRIVATETYPES
igloo_RO_PRIVATETYPES
#endif
/* Next are the application's types if any */
#ifdef igloo_RO_APPTYPES
igloo_RO_APPTYPES
#endif
/* And finnally all the types that are used by dependencies if any */
#ifdef igloo_RO_LIBTYPES
igloo_RO_LIBTYPES
#endif
} igloo_ro_t;
#else
typedef void * igloo_ro_t;
#endif
#ifdef __cplusplus
}
#endif