2018-05-25 09:24:03 -04:00
|
|
|
/* Icecast
|
|
|
|
*
|
|
|
|
* This program is distributed under the GNU General Public License, version 2.
|
|
|
|
* A copy of this license is included with this source.
|
|
|
|
*
|
|
|
|
* Copyright 2018, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
|
|
|
|
*/
|
|
|
|
|
2018-07-27 06:33:57 -04:00
|
|
|
/* This file contains the API for the refobject helper type.
|
|
|
|
* The refobject helper type is a base type that allows building other types with safe reference counting.
|
|
|
|
*/
|
|
|
|
|
2018-05-25 09:24:03 -04:00
|
|
|
#ifndef __REFOBJECT_H__
|
|
|
|
#define __REFOBJECT_H__
|
|
|
|
|
2018-06-06 10:38:24 -04:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2018-05-25 09:24:03 -04:00
|
|
|
#include "common/thread/thread.h"
|
|
|
|
|
|
|
|
#include "icecasttypes.h"
|
|
|
|
#include "compat.h"
|
|
|
|
|
2018-07-27 06:33:57 -04:00
|
|
|
/* The following macros are defined. The definition depends on if the compiler
|
|
|
|
* supports transparent unions. If supported full type checking is enabled.
|
|
|
|
* If the compiler does not support transparent unions, we fall back to using
|
|
|
|
* (void*) pointers.
|
|
|
|
*
|
|
|
|
* REFOBJECT_NULL
|
|
|
|
* Can be used to set an refobject to NULL.
|
|
|
|
* REFOBJECT_IS_NULL(x)
|
|
|
|
* Can be used to check if the refobject x is NULL.
|
|
|
|
* Checking by doing (x == NULL) does not work with transparent unions
|
|
|
|
* as the operation is only defined for it's members.
|
|
|
|
* REFOBJECT_TO_TYPE(type,x)
|
|
|
|
* This casts the refobject (x) to the type (type).
|
|
|
|
*/
|
2018-06-06 10:38:24 -04:00
|
|
|
#ifdef HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION
|
|
|
|
#define REFOBJECT_NULL ((refobject_t)(refobject_base_t*)NULL)
|
|
|
|
#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_IS_NULL(x) ((x) == NULL)
|
|
|
|
#define REFOBJECT_TO_TYPE(x,y) ((y)(x))
|
|
|
|
#endif
|
|
|
|
|
2018-07-27 06:33:57 -04:00
|
|
|
/* Type used for callback called then the object is actually freed
|
|
|
|
* That is once all references to it are gone.
|
|
|
|
*
|
|
|
|
* If the callback does not set *userdata to NULL *userdata will
|
|
|
|
* be freed automatically by calling free(3).
|
|
|
|
*
|
|
|
|
* This function must not try to deallocate or alter self.
|
|
|
|
*/
|
2018-05-25 10:45:08 -04:00
|
|
|
typedef void (*refobject_free_t)(refobject_t self, void **userdata);
|
2018-05-25 09:24:03 -04:00
|
|
|
|
2018-07-27 06:33:57 -04:00
|
|
|
/* Only defined here as the size must be publically known.
|
|
|
|
* DO NOT use any of the members in here directly!
|
|
|
|
*/
|
2018-05-25 09:24:03 -04:00
|
|
|
struct refobject_base_tag {
|
|
|
|
size_t refc;
|
|
|
|
mutex_t lock;
|
|
|
|
void *userdata;
|
2018-05-25 10:45:08 -04:00
|
|
|
refobject_free_t freecb;
|
|
|
|
char *name;
|
2018-06-17 03:06:36 -04:00
|
|
|
refobject_t associated;
|
2018-05-25 09:24:03 -04:00
|
|
|
};
|
|
|
|
|
2018-07-27 06:33:57 -04:00
|
|
|
/* 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),
|
|
|
|
* the userdata us given by userdata,
|
|
|
|
* the name for the object is given by name, and
|
|
|
|
* the associated refobject is given by associated.
|
|
|
|
*
|
|
|
|
* 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).
|
|
|
|
*/
|
2018-06-17 03:06:36 -04:00
|
|
|
refobject_t refobject_new(size_t len, refobject_free_t freecb, void *userdata, const char *name, refobject_t associated);
|
2018-07-27 06:33:57 -04:00
|
|
|
|
|
|
|
/* This increases the reference counter of the object */
|
2018-05-25 09:24:03 -04:00
|
|
|
int refobject_ref(refobject_t self);
|
2018-07-27 06:33:57 -04:00
|
|
|
/* This decreases the reference counter of the object.
|
|
|
|
* If the object's reference counter reaches zero the object is freed.
|
|
|
|
*/
|
2018-05-25 09:24:03 -04:00
|
|
|
int refobject_unref(refobject_t self);
|
2018-07-27 06:33:57 -04:00
|
|
|
|
|
|
|
/* This gets and sets the userdata */
|
2018-05-25 09:24:03 -04:00
|
|
|
void * refobject_get_userdata(refobject_t self);
|
|
|
|
int refobject_set_userdata(refobject_t self, void *userdata);
|
2018-07-27 06:33:57 -04:00
|
|
|
|
|
|
|
/* This gets the object's name */
|
2018-05-25 10:45:08 -04:00
|
|
|
const char * refobject_get_name(refobject_t self);
|
2018-07-27 06:33:57 -04:00
|
|
|
|
|
|
|
/* This gets the object's associated object. */
|
2018-06-17 03:06:36 -04:00
|
|
|
refobject_t refobject_get_associated(refobject_t self);
|
2018-05-25 09:24:03 -04:00
|
|
|
|
|
|
|
#endif
|