mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-05 20:50:06 +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_util/r_str_util.h"
|
||||||
#include <r_userconf.h>
|
#include <r_userconf.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
// TODO: fix this to make it crosscompile-friendly: R_SYS_OSTYPE ?
|
// TODO: fix this to make it crosscompile-friendly: R_SYS_OSTYPE ?
|
||||||
/* operating system */
|
/* operating system */
|
||||||
@ -654,4 +655,17 @@ static inline void r_run_call10(void *fcn, void *arg1, void *arg2, void *arg3, v
|
|||||||
# endif
|
# endif
|
||||||
#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
|
#endif // R2_TYPES_H
|
||||||
|
@ -126,10 +126,47 @@ bool test_initial_underscore(void) {
|
|||||||
mu_end;
|
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() {
|
int all_tests() {
|
||||||
mu_run_test (test_ignore_prefixes);
|
mu_run_test (test_ignore_prefixes);
|
||||||
mu_run_test (test_remove_r2_prefixes);
|
mu_run_test (test_remove_r2_prefixes);
|
||||||
mu_run_test (test_dll_names);
|
mu_run_test (test_dll_names);
|
||||||
|
mu_run_test (test_references);
|
||||||
mu_run_test (test_autonames);
|
mu_run_test (test_autonames);
|
||||||
mu_run_test (test_initial_underscore);
|
mu_run_test (test_initial_underscore);
|
||||||
return tests_passed != tests_run;
|
return tests_passed != tests_run;
|
||||||
|
Loading…
Reference in New Issue
Block a user