<p>Harald Welte has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/13312">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">context: Add support for [per-thread] global talloc contexts<br><br>Rather than having applications maintain their own talloc cotexts,<br>let's offer some root talloc contexts in libosmocore.  Let's also<br>make them per thread right from the beginning.  This will help<br>some multi-threaded applications to use talloc in a thread-safe<br>way.<br><br>Change-Id: Iae39cd57274bf6753ecaf186f229e582b42662e3<br>---<br>M include/Makefile.am<br>A include/osmocom/core/context.h<br>M src/Makefile.am<br>A src/context.c<br>M src/select.c<br>5 files changed, 58 insertions(+), 2 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/12/13312/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/Makefile.am b/include/Makefile.am</span><br><span>index 17f7d1c..7389e63 100644</span><br><span>--- a/include/Makefile.am</span><br><span>+++ b/include/Makefile.am</span><br><span>@@ -13,6 +13,7 @@</span><br><span>                        osmocom/core/bitvec.h \</span><br><span>                        osmocom/core/bitcomp.h \</span><br><span>                        osmocom/core/byteswap.h \</span><br><span style="color: hsl(120, 100%, 40%);">+                       osmocom/core/context.h \</span><br><span>                        osmocom/core/conv.h \</span><br><span>                        osmocom/core/counter.h \</span><br><span>                        osmocom/core/crc16.h \</span><br><span>diff --git a/include/osmocom/core/context.h b/include/osmocom/core/context.h</span><br><span>new file mode 100644</span><br><span>index 0000000..28a8dae</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/core/context.h</span><br><span>@@ -0,0 +1,20 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! per-thread talloc contexts.  This works around the problem that talloc is not</span><br><span style="color: hsl(120, 100%, 40%);">+ * thread-safe. However, one can simply have a different set of talloc contexts for each</span><br><span style="color: hsl(120, 100%, 40%);">+ * thread, and ensure that allocations made on one thread are always only free'd on that</span><br><span style="color: hsl(120, 100%, 40%);">+ * very same thread.</span><br><span style="color: hsl(120, 100%, 40%);">+ * WARNING: Users must make sure they free() on the same thread as they allocate!! */</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_talloc_contexts {</span><br><span style="color: hsl(120, 100%, 40%);">+    /*! global per-thread talloc context. */</span><br><span style="color: hsl(120, 100%, 40%);">+      void *global;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! volatile select-dispatch context.  This context is completely free'd and</span><br><span style="color: hsl(120, 100%, 40%);">+       * re-created every time the main select loop in osmo_select_main() returns from</span><br><span style="color: hsl(120, 100%, 40%);">+       * select(2) and calls per-fd callback functions.  This allows users of this</span><br><span style="color: hsl(120, 100%, 40%);">+   * facility to allocate temporary objects like string buffers, message buffers</span><br><span style="color: hsl(120, 100%, 40%);">+         * and the like which are automatically free'd when going into the next select()</span><br><span style="color: hsl(120, 100%, 40%);">+   * system call */</span><br><span style="color: hsl(120, 100%, 40%);">+     void *select;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern __thread struct osmo_talloc_contexts *osmo_ctx;</span><br><span>diff --git a/src/Makefile.am b/src/Makefile.am</span><br><span>index 27ab702..54e9280 100644</span><br><span>--- a/src/Makefile.am</span><br><span>+++ b/src/Makefile.am</span><br><span>@@ -13,7 +13,7 @@</span><br><span> lib_LTLIBRARIES = libosmocore.la</span><br><span> </span><br><span> libosmocore_la_LIBADD = $(BACKTRACE_LIB) $(TALLOC_LIBS) $(LIBRARY_RT)</span><br><span style="color: hsl(0, 100%, 40%);">-libosmocore_la_SOURCES = timer.c timer_gettimeofday.c timer_clockgettime.c \</span><br><span style="color: hsl(120, 100%, 40%);">+libosmocore_la_SOURCES = context.c timer.c timer_gettimeofday.c timer_clockgettime.c \</span><br><span>                         select.c signal.c msgb.c bits.c \</span><br><span>                    bitvec.c bitcomp.c counter.c fsm.c \</span><br><span>                         write_queue.c utils.c socket.c \</span><br><span>diff --git a/src/context.c b/src/context.c</span><br><span>new file mode 100644</span><br><span>index 0000000..7163178</span><br><span>--- /dev/null</span><br><span>+++ b/src/context.c</span><br><span>@@ -0,0 +1,22 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/talloc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/context.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+__thread struct osmo_talloc_contexts *osmo_ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_ctx_init(const char *id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      osmo_ctx = talloc_named(NULL, sizeof(*osmo_ctx), "global-%s", id);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!osmo_ctx)</span><br><span style="color: hsl(120, 100%, 40%);">+                return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+       memset(osmo_ctx, 0, sizeof(*osmo_ctx));</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_ctx->global = osmo_ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* initialize osmo_ctx on main tread */</span><br><span style="color: hsl(120, 100%, 40%);">+static __attribute__((constructor)) void on_dso_load_ctx(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_ctx_init("main");</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/select.c b/src/select.c</span><br><span>index 4e7be35..f5ad174 100644</span><br><span>--- a/src/select.c</span><br><span>+++ b/src/select.c</span><br><span>@@ -36,6 +36,9 @@</span><br><span> #include <osmocom/core/linuxlist.h></span><br><span> #include <osmocom/core/timer.h></span><br><span> #include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/talloc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/context.h></span><br><span> </span><br><span> #include "../config.h"</span><br><span> </span><br><span>@@ -259,8 +262,18 @@</span><br><span>     /* fire timers */</span><br><span>    osmo_timers_update();</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     /* create new volatile 'select' scope context */</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(!osmo_ctx->select);</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_ctx->select = talloc_named_const(osmo_ctx->global, 0, "select");</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(osmo_ctx->select);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  /* call registered callback functions */</span><br><span style="color: hsl(0, 100%, 40%);">-        return osmo_fd_disp_fds(&readset, &writeset, &exceptset);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_fd_disp_fds(&readset, &writeset, &exceptset);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* free the volatile 'select' scope context and any of its siblings */</span><br><span style="color: hsl(120, 100%, 40%);">+        talloc_free(osmo_ctx->select);</span><br><span style="color: hsl(120, 100%, 40%);">+     osmo_ctx->select = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+   return rc;</span><br><span> }</span><br><span> </span><br><span> /*! find an osmo_fd based on the integer fd</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13312">change 13312</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/13312"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Iae39cd57274bf6753ecaf186f229e582b42662e3 </div>
<div style="display:none"> Gerrit-Change-Number: 13312 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>