From 7b4a05d535f0ecc070e9b506ad0a667e24b67f71 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 --- src/Makefile.am | 2 +- src/context.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/select.c | 41 ++++++++++++++++++++++++++++++++++++----- 3 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 src/context.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index e65e0c97..714b5eac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,7 +13,7 @@ endif lib_LTLIBRARIES = libosmocore.la libosmocore_la_LIBADD = $(BACKTRACE_LIB) $(TALLOC_LIBS) $(LIBRARY_RT) -libosmocore_la_SOURCES = timer.c timer_gettimeofday.c timer_clockgettime.c \ +libosmocore_la_SOURCES = context.c timer.c timer_gettimeofday.c timer_clockgettime.c \ select.c signal.c msgb.c bits.c \ bitvec.c bitcomp.c counter.c fsm.c \ write_queue.c utils.c socket.c \ diff --git a/src/context.c b/src/context.c new file mode 100644 index 00000000..bad012bd --- /dev/null +++ b/src/context.c @@ -0,0 +1,52 @@ +/*! \file context.c + * talloc context handling. + * + * (C) 2019 by Harald Welte + * All Rights Reserverd. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include +#include +#include +#include + +__thread struct osmo_talloc_contexts *osmo_ctx; + +int osmo_ctx_init(const char *id) +{ + osmo_ctx = talloc_named(NULL, sizeof(*osmo_ctx), "global-%s", id); + if (!osmo_ctx) + return -ENOMEM; + memset(osmo_ctx, 0, sizeof(*osmo_ctx)); + osmo_ctx->global = osmo_ctx; + osmo_ctx->select = talloc_named_const(osmo_ctx->global, 0, "select"); + if (!osmo_ctx->select) { + talloc_free(osmo_ctx); + return -ENOMEM; + } + return 0; +} + +/* initialize osmo_ctx on main tread */ +static __attribute__((constructor)) void on_dso_load_ctx(void) +{ + OSMO_ASSERT(osmo_ctx_init("main") == 0); +} + +/*! @} */ diff --git a/src/select.c b/src/select.c index 7ce135f5..34a133c0 100644 --- a/src/select.c +++ b/src/select.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include "../config.h" @@ -233,11 +235,7 @@ restart: return work; } -/*! select main loop integration - * \param[in] polling should we pollonly (1) or block on select (0) - * \returns 0 if no fd handled; 1 if fd handled; negative in case of error - */ -int osmo_select_main(int polling) +static int _osmo_select_main(int polling) { fd_set readset, writeset, exceptset; int rc; @@ -259,10 +257,43 @@ int osmo_select_main(int polling) /* fire timers */ osmo_timers_update(); + OSMO_ASSERT(osmo_ctx->select); + /* call registered callback functions */ return osmo_fd_disp_fds(&readset, &writeset, &exceptset); } +/*! select main loop integration + * \param[in] polling should we pollonly (1) or block on select (0) + * \returns 0 if no fd handled; 1 if fd handled; negative in case of error + */ +int osmo_select_main(int polling) +{ + int rc = _osmo_select_main(polling); +#ifndef EMBEDDED + if (talloc_total_size(osmo_ctx->select) != 0) { + LOGP(DLGLOBAL, LOGL_FATAL, "You cannot use the 'select' volatile " + "context if you don't use osmo_select_main_ctx()!\n"); + OSMO_ASSERT(0); + } +#endif + return rc; +} + +#ifndef EMBEDDED +/*! select main loop integration with temporary select-dispatch talloc context + * \param[in] polling should we pollonly (1) or block on select (0) + * \returns 0 if no fd handled; 1 if fd handled; negative in case of error + */ +int osmo_select_main_ctx(int polling) +{ + int rc = _osmo_select_main(polling); + /* free all the children of the volatile 'select' scope context */ + talloc_free_children(osmo_ctx->select); + return rc; +} +#endif + /*! find an osmo_fd based on the integer fd * \param[in] fd file descriptor to use as search key * \returns \ref osmo_fd for \ref fd; NULL in case it doesn't exist */ -- cgit v1.2.3