Andrew,

The attached patch adds the --enable-reentrant option to configure
(disabled by default) as suggested by David Monniaux a few days ago
[1]. When selected, the appropriate thread local storage class
specifier is identified, added to config.h and used in tls.c. The
patch is based on the work of Dmitry Nadezhin [2] and the ax_tls macro
form the autoconf archive [3] simplified to match the configure.ac
style, The code remains C89 if the option is not selected.

I have tested this extensively but only on Linux with gcc, so
additional testing and feedback is welcome.

Best Regards,

Chris Matrakidis


[1] http://lists.gnu.org/archive/html/help-glpk/2016-12/msg00023.html
[2] https://github.com/nadezhin/thermocompensation
[3] http://www.gnu.org/software/autoconf-archive/ax_tls.html
diff --git a/config.h.in b/config.h.in
index 2849bf9..bf8dac2 100644
--- a/config.h.in
+++ b/config.h.in
@@ -24,4 +24,7 @@
 #undef MYSQL_DLNAME
 /* MySQL shared library name if this feature is enabled */
 
+#undef TLS
+/* thread local storage class specifier for reentrancy (if any) */
+
 /* eof */
diff --git a/configure.ac b/configure.ac
index 0f57268..1688720 100644
--- a/configure.ac
+++ b/configure.ac
@@ -46,6 +46,16 @@ AC_HELP_STRING([--enable-mysql],
       esac],
    [enable_mysql=no])
 
+AC_ARG_ENABLE(reentrant,
+AC_HELP_STRING([--enable-reentrant],
+   [enable reentrancy support [[default=no]]]),
+   [case $enableval in
+      yes | no) ;;
+      *) AC_MSG_ERROR(
+         [invalid value `$enableval' for --enable-reentrant]);;
+      esac],
+   [enable_reentrant=no])
+
 dnl Disable unnecessary libtool tests
 define([AC_LIBTOOL_LANG_CXX_CONFIG], [:])
 define([AC_LIBTOOL_LANG_F77_CONFIG], [:])
@@ -141,6 +151,30 @@ else
    AC_MSG_RESULT([no])
 fi
 
+AC_MSG_CHECKING([whether to enable reentrancy support])
+if test "$enable_reentrant" = "yes"; then
+   AC_MSG_RESULT([yes])
+   AC_MSG_CHECKING([for thread local storage (TLS) class specifier])
+   keywords="_Thread_local __thread __declspec(thread)"
+   tls=none
+   for tls_keyword in $keywords; do
+      AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+         #include <stdlib.h>
+         static void foo(void)
+         {  static ] $tls_keyword [ int bar;
+            exit(1);
+         }])], [tls=$tls_keyword; break], [])
+   done
+   AC_MSG_RESULT($tls)
+   if test "$tls" != "none"; then
+      AC_DEFINE_UNQUOTED([TLS], $tls, [N/A])
+   else
+      AC_MSG_ERROR([Reentrancy needs complier support for TLS])
+   fi
+else
+   AC_MSG_RESULT([no])
+fi
+
 AC_MSG_CHECKING(
    [if libtool needs -no-undefined flag to build shared libraries])
 case "${host}" in
diff --git a/src/env/tls.c b/src/env/tls.c
index 3ffa114..2a74837 100644
--- a/src/env/tls.c
+++ b/src/env/tls.c
@@ -23,9 +23,17 @@
 
 #include "env.h"
 
-static void *tls = NULL;
-/* NOTE: in a re-entrant version of the package this variable should be
- * placed in the Thread Local Storage (TLS) */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef TLS
+#define TLS
+#endif
+
+static TLS void *tls = NULL;
+/* NOTE: TLS is defined in config.h by specifying the --enable-reentrant
+ * option to configure */
 
 /***********************************************************************
 *  NAME
_______________________________________________
Help-glpk mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/help-glpk

Reply via email to