mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-12 23:46:36 +00:00
Add generic reference counting implementation ##util (#16604)
* Unit test for the r-ref api
This commit is contained in:
parent
f549eb2a28
commit
0baf99d81d
@ -5,6 +5,7 @@
|
||||
#include "r_util/r_str_util.h"
|
||||
#include <r_userconf.h>
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
// TODO: fix this to make it crosscompile-friendly: R_SYS_OSTYPE ?
|
||||
/* operating system */
|
||||
@ -654,4 +655,17 @@ static inline void r_run_call10(void *fcn, void *arg1, void *arg2, void *arg3, v
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// reference counter
|
||||
typedef int RRef;
|
||||
|
||||
#define R_REF_NAME refcount
|
||||
#define r_ref(x) x->R_REF_NAME++;
|
||||
#define r_ref_init(x) x->R_REF_NAME = 1
|
||||
#define r_unref(x,f) { assert (x->R_REF_NAME> 0); if (!--(x->R_REF_NAME)) { f(x); } }
|
||||
|
||||
#define R_REF_TYPE RRef refcount;
|
||||
#define R_REF_FUNCTIONS(s, n) \
|
||||
static inline void n##_ref(s *x) { x->R_REF_NAME++; } \
|
||||
static inline void n##_unref(s *x) { r_unref (x, n##_free); }
|
||||
|
||||
#endif // R2_TYPES_H
|
||||
|
@ -126,10 +126,47 @@ bool test_initial_underscore(void) {
|
||||
mu_end;
|
||||
}
|
||||
|
||||
/* references */
|
||||
typedef struct {
|
||||
const char *name;
|
||||
R_REF_TYPE;
|
||||
} TypeTest;
|
||||
|
||||
static TypeTest *r_type_test_new(const char *name) {
|
||||
TypeTest *tt = R_NEW0 (TypeTest);
|
||||
if (tt) {
|
||||
r_ref_init (tt);
|
||||
tt->name = name;
|
||||
}
|
||||
return tt;
|
||||
}
|
||||
|
||||
static void r_type_test_free(TypeTest *tt) {
|
||||
tt->name = "";
|
||||
}
|
||||
|
||||
R_REF_FUNCTIONS(TypeTest, r_type_test);
|
||||
|
||||
bool test_references(void) {
|
||||
TypeTest *tt = r_type_test_new ("foo");
|
||||
mu_assert_eq (tt->refcount, 1, "reference count issue");
|
||||
r_type_test_ref (tt);
|
||||
mu_assert_eq (tt->refcount, 2, "reference count issue");
|
||||
r_type_test_unref (tt);
|
||||
mu_assert_streq (tt->name, "foo", "typetest name should be foo");
|
||||
mu_assert_eq (tt->refcount, 1, "reference count issue");
|
||||
r_type_test_unref (tt); // tt becomes invalid
|
||||
mu_assert_eq (tt->refcount, 0, "reference count issue");
|
||||
mu_assert_streq (tt->name, "", "typetest name should be foo");
|
||||
free (tt);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
int all_tests() {
|
||||
mu_run_test (test_ignore_prefixes);
|
||||
mu_run_test (test_remove_r2_prefixes);
|
||||
mu_run_test (test_dll_names);
|
||||
mu_run_test (test_references);
|
||||
mu_run_test (test_autonames);
|
||||
mu_run_test (test_initial_underscore);
|
||||
return tests_passed != tests_run;
|
||||
|
Loading…
Reference in New Issue
Block a user