From 2d90611cb06b780b165296aa3abd1f7229d503f9 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 18 Mar 2019 17:17:43 +0100 Subject: context: Add support for [per-thread] global talloc contexts Rather than having applications maintain their own talloc cotexts, let's offer some root talloc contexts in libosmocore. Let's also make them per thread right from the beginning. This will help some multi-threaded applications to use talloc in a thread-safe way. Change-Id: Iae39cd57274bf6753ecaf186f229e582b42662e3 --- tests/Makefile.am | 5 +++ tests/context/context_test.c | 84 +++++++++++++++++++++++++++++++++++++++++++ tests/context/context_test.ok | 4 +++ tests/testsuite.at | 6 ++++ 4 files changed, 99 insertions(+) create mode 100644 tests/context/context_test.c create mode 100644 tests/context/context_test.ok (limited to 'tests') diff --git a/tests/Makefile.am b/tests/Makefile.am index a8a06c53..92edf752 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -32,6 +32,7 @@ check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_test \ tdef/tdef_vty_test_dynamic \ sockaddr_str/sockaddr_str_test \ use_count/use_count_test \ + context/context_test \ $(NULL) if ENABLE_MSGFILE @@ -251,6 +252,9 @@ sockaddr_str_sockaddr_str_test_LDADD = $(LDADD) use_count_use_count_test_SOURCES = use_count/use_count_test.c use_count_use_count_test_LDADD = $(LDADD) +context_context_test_SOURCES = context/context_test.c +context_context_test_LDADD = $(LDADD) + # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac :;{ \ @@ -322,6 +326,7 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \ tdef/tdef_vty_test_dynamic.vty \ sockaddr_str/sockaddr_str_test.ok \ use_count/use_count_test.ok use_count/use_count_test.err \ + context/context_test.ok \ $(NULL) DISTCLEANFILES = atconfig atlocal conv/gsm0503_test_vectors.c diff --git a/tests/context/context_test.c b/tests/context/context_test.c new file mode 100644 index 00000000..e9a55593 --- /dev/null +++ b/tests/context/context_test.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +static struct osmo_fd g_evfd; + +static void *alloc_res_select; +static void *alloc_res_global; + +static int destructor_called; + +static int talloc_destructor(void *ptr) +{ + printf("destructor was called automatically\n"); + /* ensure the destructor is only called for the chunk allocated from the + * volatile select context */ + OSMO_ASSERT(ptr == alloc_res_select); + destructor_called += 1; + return 0; +} + +static int evfd_cb(struct osmo_fd *ofd, unsigned int what) +{ + uint64_t rval; + int rc; + + rc = read(ofd->fd, &rval, sizeof(rval)); + OSMO_ASSERT(rc == sizeof(rval)); + + printf("allocating from select context\n"); + alloc_res_select = talloc_named_const(OTC_SELECT, 23, "alloc_select"); + OSMO_ASSERT(alloc_res_select); + talloc_set_destructor(alloc_res_select, talloc_destructor); + + printf("allocating from global context\n"); + alloc_res_global = talloc_named_const(OTC_GLOBAL, 42, "alloc_global"); + OSMO_ASSERT(alloc_res_global); + talloc_set_destructor(alloc_res_global, talloc_destructor); + return 0; +} + +const struct log_info_cat default_categories[] = { +}; + +static struct log_info info = { + .cat = default_categories, + .num_cat = ARRAY_SIZE(default_categories), +}; + +int main(int argc, char **argv) +{ + int rc; + + osmo_init_logging2(OTC_GLOBAL, &info); + + rc = eventfd(0, 0); + OSMO_ASSERT(rc >= 0); + osmo_fd_setup(&g_evfd, rc, OSMO_FD_READ, evfd_cb, NULL, 0); + osmo_fd_register(&g_evfd); + + /* make sure the select loop will immediately call the callback */ + uint64_t val = 1; + rc = write(g_evfd.fd, &val, sizeof(val)); + OSMO_ASSERT(rc == sizeof(val)); + + /* enter osmo_select_main_ctx() once */ + printf("entering osmo_select_main\n"); + osmo_select_main_ctx(1); + + /* the allocation must have happened, and the destructor must have been called + * automatically exactly once */ + OSMO_ASSERT(destructor_called == 1); + + exit(0); +} diff --git a/tests/context/context_test.ok b/tests/context/context_test.ok new file mode 100644 index 00000000..3984a397 --- /dev/null +++ b/tests/context/context_test.ok @@ -0,0 +1,4 @@ +entering osmo_select_main +allocating from select context +allocating from global context +destructor was called automatically diff --git a/tests/testsuite.at b/tests/testsuite.at index 0fc96467..a043f0c7 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -350,3 +350,9 @@ cat $abs_srcdir/use_count/use_count_test.ok > expout cat $abs_srcdir/use_count/use_count_test.err > experr AT_CHECK([$abs_top_builddir/tests/use_count/use_count_test], [0], [expout], [experr]) AT_CLEANUP + +AT_SETUP([context]) +AT_KEYWORDS([context]) +cat $abs_srcdir/context/context_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/context/context_test], [0], [expout], [ignore]) +AT_CLEANUP -- cgit v1.2.3