Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Xiph.Org
Icecast-Server
Commits
491c4ab2
Commit
491c4ab2
authored
Oct 10, 2018
by
Philipp Schafft
🦁
Browse files
Feature: Implemented simple API refobject_new() and refobject_new_ext()
parent
9f6d3c30
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/refobject.c
View file @
491c4ab2
...
...
@@ -19,7 +19,15 @@
#define TO_BASE(x) REFOBJECT_TO_TYPE((x), refobject_base_t *)
REFOBJECT_DEFINE_TYPE
(
refobject_base_t
);
static
int
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
(
return_zero
)
);
static
inline
int
check_type
(
const
refobject_type_t
*
type
)
{
...
...
@@ -64,6 +72,34 @@ refobject_t refobject_new__real(const refobject_type_t *type, void *userdata
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
))
...
...
src/refobject.h
View file @
491c4ab2
...
...
@@ -17,6 +17,8 @@
#include <config.h>
#endif
#include <stdarg.h>
#include "common/thread/thread.h"
#include "icecasttypes.h"
...
...
@@ -69,6 +71,9 @@ static const refobject_type_t refobject_typedef__ ## type = \
#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)
typedef
struct
refobject_type_tag
refobject_type_t
;
/* Type used for callback called then the object is actually freed
* That is once all references to it are gone.
...
...
@@ -80,11 +85,23 @@ static const refobject_type_t refobject_typedef__ ## type = \
*/
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!
*/
typedef
struct
{
struct
refobject_type_tag
{
/* Size of this control structure */
size_t
control_length
;
/* ABI version of this structure */
...
...
@@ -96,7 +113,9 @@ typedef struct {
const
char
*
type_name
;
/* Callback to be called on final free() */
refobject_free_t
type_freecb
;
}
refobject_type_t
;
/* 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!
...
...
@@ -124,6 +143,9 @@ REFOBJECT_FORWARD_TYPE(refobject_base_t);
*/
#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
);
...
...
src/tests/ctest_buffer.c
View file @
491c4ab2
...
...
@@ -83,7 +83,7 @@ static void test_associated(void)
refobject_base_t
*
a
;
buffer_t
*
b
;
a
=
refobject_new
__new
(
refobject_base_t
,
NULL
,
NULL
,
REFOBJECT_NULL
);
a
=
refobject_new
(
refobject_base_t
);
ctest_test
(
"refobject created"
,
!
REFOBJECT_IS_NULL
(
a
));
...
...
src/tests/ctest_refobject.c
View file @
491c4ab2
...
...
@@ -16,6 +16,12 @@
#include "../refobject.h"
static
int
return_zero
(
refobject_t
self
,
const
refobject_type_t
*
type
,
va_list
ap
)
{
(
void
)
self
,
(
void
)
type
,
(
void
)
ap
;
return
0
;
}
static
void
test_ptr
(
void
)
{
refobject_t
a
;
...
...
@@ -31,7 +37,7 @@ static void test_create_ref_unref(void)
{
refobject_base_t
*
a
;
a
=
refobject_new
__new
(
refobject_base_t
,
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
);
...
...
@@ -44,7 +50,7 @@ static void test_typename(void)
refobject_base_t
*
a
;
const
char
*
typename
;
a
=
refobject_new
__new
(
refobject_base_t
,
NULL
,
NULL
,
REFOBJECT_NULL
);
a
=
refobject_new
(
refobject_base_t
);
ctest_test
(
"refobject created"
,
!
REFOBJECT_IS_NULL
(
a
));
typename
=
REFOBJECT_GET_TYPENAME
(
a
);
...
...
@@ -66,7 +72,7 @@ static void test_valid(void)
ctest_test
(
"NULL is not valid"
,
!
REFOBJECT_IS_VALID
(
REFOBJECT_NULL
,
refobject_base_t
));
a
=
refobject_new
__new
(
refobject_base_t
,
NULL
,
NULL
,
REFOBJECT_NULL
);
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
));
...
...
@@ -83,39 +89,47 @@ static void test_sizes(void)
refobject_base_t
__base
;
char
padding
[
1024
];
}
ctest_test_type_a_t
;
REFOBJECT_DEFINE_PRIVATE_TYPE
(
ctest_test_type_a_t
);
REFOBJECT_DEFINE_PRIVATE_TYPE
(
ctest_test_type_a_t
,
REFOBJECT_DEFINE_TYPE_NEW
(
return_zero
)
);
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_PRIVATE_TYPE
(
ctest_test_type_b_t
,
REFOBJECT_DEFINE_TYPE_NEW
(
return_zero
)
);
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_PRIVATE_TYPE
(
ctest_test_type_c_t
,
REFOBJECT_DEFINE_TYPE_NEW
(
return_zero
)
);
typedef
struct
{
char
padding
[
0
];
}
ctest_test_type_d_t
;
REFOBJECT_DEFINE_PRIVATE_TYPE
(
ctest_test_type_d_t
);
REFOBJECT_DEFINE_PRIVATE_TYPE
(
ctest_test_type_d_t
,
REFOBJECT_DEFINE_TYPE_NEW
(
return_zero
)
);
a
=
REFOBJECT_FROM_TYPE
(
refobject_new
__new
(
ctest_test_type_a_t
,
NULL
,
NULL
,
REFOBJECT_NULL
));
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_FROM_TYPE
(
refobject_new
__new
(
ctest_test_type_b_t
,
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
);
a
=
REFOBJECT_FROM_TYPE
(
refobject_new
__new
(
ctest_test_type_c_t
,
NULL
,
NULL
,
REFOBJECT_NULL
));
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_FROM_TYPE
(
refobject_new
__new
(
ctest_test_type_d_t
,
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
);
...
...
@@ -128,7 +142,7 @@ static void test_name(void)
const
char
*
name
=
"test object name"
;
const
char
*
ret
;
a
=
refobject_new_
_new
(
refobject_base_t
,
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
);
...
...
@@ -145,7 +159,7 @@ static void test_userdata(void)
void
*
userdata
=
&
tmp
;
void
*
ret
;
a
=
refobject_new
__new
(
refobject_base_t
,
NULL
,
NULL
,
REFOBJECT_NULL
);
a
=
refobject_new
(
refobject_base_t
);
ctest_test
(
"refobject created"
,
!
REFOBJECT_IS_NULL
(
a
));
ret
=
refobject_get_userdata
(
a
);
...
...
@@ -159,7 +173,7 @@ static void test_userdata(void)
ctest_test
(
"un-referenced"
,
refobject_unref
(
a
)
==
0
);
a
=
refobject_new_
_new
(
refobject_base_t
,
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
);
...
...
@@ -173,10 +187,10 @@ static void test_associated(void)
{
refobject_base_t
*
a
,
*
b
;
a
=
refobject_new
__new
(
refobject_base_t
,
NULL
,
NULL
,
REFOBJECT_NULL
);
a
=
refobject_new
(
refobject_base_t
);
ctest_test
(
"refobject created"
,
!
REFOBJECT_IS_NULL
(
a
));
b
=
refobject_new_
_new
(
refobject_base_t
,
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
);
...
...
@@ -197,17 +211,18 @@ static void test_freecb(void)
ctest_test_type_t
*
a
;
REFOBJECT_DEFINE_PRIVATE_TYPE
(
ctest_test_type_t
,
REFOBJECT_DEFINE_TYPE_FREE
(
test_freecb__freecb
)
REFOBJECT_DEFINE_TYPE_FREE
(
test_freecb__freecb
),
REFOBJECT_DEFINE_TYPE_NEW
(
return_zero
)
);
test_freecb__called
=
0
;
a
=
refobject_new
__new
(
ctest_test_type_t
,
NULL
,
NULL
,
REFOBJECT_NULL
);
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
__new
(
ctest_test_type_t
,
NULL
,
NULL
,
REFOBJECT_NULL
);
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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment