refobject.h 3.42 KB
Newer Older
1 2 3 4 5 6 7 8
/* 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>,
 */

9 10 11 12
/* 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.
 */

13 14 15
#ifndef __REFOBJECT_H__
#define __REFOBJECT_H__

16 17 18 19
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

20 21 22 23 24
#include "common/thread/thread.h"

#include "icecasttypes.h"
#include "compat.h"

25 26 27 28 29 30 31 32 33 34 35 36 37 38
/* 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).
 */
39 40 41 42 43 44 45 46 47 48
#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

49 50 51 52 53 54 55 56
/* 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.
 */
57
typedef void (*refobject_free_t)(refobject_t self, void **userdata);
58

59 60 61
/* Only defined here as the size must be publically known.
 * DO NOT use any of the members in here directly!
 */
62 63 64 65
struct refobject_base_tag {
    size_t refc;
    mutex_t lock;
    void *userdata;
66 67
    refobject_free_t freecb;
    char *name;
68
    refobject_t associated;
69 70
};

71 72 73 74 75 76 77 78 79 80
/* 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).
 */
81
refobject_t     refobject_new(size_t len, refobject_free_t freecb, void *userdata, const char *name, refobject_t associated);
82 83

/* This increases the reference counter of the object */
84
int             refobject_ref(refobject_t self);
85 86 87
/* This decreases the reference counter of the object.
 * If the object's reference counter reaches zero the object is freed.
 */
88
int             refobject_unref(refobject_t self);
89 90

/* This gets and sets the userdata */
91 92
void *          refobject_get_userdata(refobject_t self);
int             refobject_set_userdata(refobject_t self, void *userdata);
93 94

/* This gets the object's name */
95
const char *    refobject_get_name(refobject_t self);
96 97

/* This gets the object's associated object. */
98
refobject_t     refobject_get_associated(refobject_t self);
99 100

#endif