towards thread-safe logging
authorFlorian Dold <florian.dold@gmail.com>
Thu, 9 May 2019 12:51:50 +0000 (14:51 +0200)
committerFlorian Dold <florian.dold@gmail.com>
Thu, 9 May 2019 12:54:00 +0000 (14:54 +0200)
(Thread-safe logging isn't really relevant for GNUnet itself, but it is
necessary for the GNU Taler exchange)

configure.ac
src/include/platform.h
src/util/common_logging.c

index e00b8ae1b85f0518cd78567739ab0678a7fd23ac..b1e1c1acaf93ba57071068d1ae248b00a9b0c47c 100644 (file)
@@ -1795,6 +1795,20 @@ else
 fi
 AC_DEFINE_UNQUOTED([ENABLE_WINDOWS_WORKAROUNDS], $workarounds, [enable workarounds used on Windows (only useful for test cases)])
 
+
+# Check if the __thread storage class for thread-local storage is available.
+AC_MSG_CHECKING(whether __thread is supported)
+AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([#include <stdlib.h>
+                   #undef __thread
+                   static __thread int a = 1;],
+                  [exit(a-1);])],
+ [have_thread_local_gcc=1],[have_thread_local_gcc=0])
+AC_DEFINE_UNQUOTED([HAVE_THREAD_LOCAL_GCC],$have_thread_local_gcc,[Define this if __thread is supported])
+AS_IF([test "x$have_thread_local_gcc" = "x1"],
+      [AC_MSG_RESULT(yes)],
+      [AC_MSG_RESULT(no)])
+
 # gcov compilation
 AC_MSG_CHECKING(whether to compile with support for code coverage analysis)
 AC_ARG_ENABLE([coverage],
index 01b0bcf9ef7f8420bf46443ece1fa698b80ee148..23e640ec1a308282d6a527bef6636f70ce0b7a91 100644 (file)
@@ -289,6 +289,10 @@ atoll (const char *nptr);
 #define PATH_MAX 4096
 #endif
 
-
+#if HAVE_THREAD_LOCAL_GCC
+#define GNUNET_THREAD_LOCAL __thread
+#else
+#define GNUNET_THREAD_LOCAL
+#endif
 
 #endif
index de30cab3a185bad70895c05e16d78f1319d9c303..34002e0fc4707d5f0efb98f869dd027428e5b1e6 100644 (file)
@@ -100,27 +100,27 @@ struct CustomLogger
  * Note that this message maybe truncated to the first BULK_TRACK_SIZE
  * characters, in which case it is NOT 0-terminated!
  */
-static char last_bulk[BULK_TRACK_SIZE] __attribute__ ((nonstring));
+static GNUNET_THREAD_LOCAL char last_bulk[BULK_TRACK_SIZE] __attribute__ ((nonstring));
 
 /**
  * Type of the last bulk message.
  */
-static enum GNUNET_ErrorType last_bulk_kind;
+static GNUNET_THREAD_LOCAL enum GNUNET_ErrorType last_bulk_kind;
 
 /**
  * Time of the last bulk error message (0 for none)
  */
-static struct GNUNET_TIME_Absolute last_bulk_time;
+static GNUNET_THREAD_LOCAL struct GNUNET_TIME_Absolute last_bulk_time;
 
 /**
  * Number of times that bulk message has been repeated since.
  */
-static unsigned int last_bulk_repeat;
+static GNUNET_THREAD_LOCAL unsigned int last_bulk_repeat;
 
 /**
  * Component when the last bulk was logged.  Will be 0-terminated.
  */
-static char last_bulk_comp[COMP_TRACK_SIZE + 1];
+static GNUNET_THREAD_LOCAL char last_bulk_comp[COMP_TRACK_SIZE + 1];
 
 /**
  * Running component.
@@ -150,7 +150,7 @@ static struct CustomLogger *loggers;
 /**
  * Number of log calls to ignore.
  */
-static int skip_log = 0;
+static GNUNET_THREAD_LOCAL int skip_log = 0;
 
 /**
  * File descriptor to use for "stderr", or NULL for none.