diff options
-rw-r--r-- | changes/bug26779 | 4 | ||||
-rw-r--r-- | configure.ac | 20 | ||||
-rw-r--r-- | src/common/compat_threads.c | 5 | ||||
-rw-r--r-- | src/common/compat_threads.h | 19 |
4 files changed, 37 insertions, 11 deletions
diff --git a/changes/bug26779 b/changes/bug26779 new file mode 100644 index 0000000000..fb7f6160ea --- /dev/null +++ b/changes/bug26779 @@ -0,0 +1,4 @@ + o Minor features (bug workaround): + - Compile correctly on systems that provide the C11 stdatomic.h header, + but where C11 atomic functions don't actually compile. + Closes ticket 26779; workaround for Debian issue 903709. diff --git a/configure.ac b/configure.ac index cd591c785f..8e6683bb71 100644 --- a/configure.ac +++ b/configure.ac @@ -1557,6 +1557,26 @@ AC_CHECK_SIZEOF(socklen_t, , [AC_INCLUDES_DEFAULT() AC_CHECK_SIZEOF(cell_t) +# Let's see if stdatomic works. (There are some debian clangs that screw it +# up; see Tor bug #26779 and debian bug 903709.) +AC_CACHE_CHECK([whether C11 stdatomic.h actually works], + tor_cv_stdatomic_works, +[AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#include <stdatomic.h> +struct x { atomic_size_t y; }; +void try_atomic_init(struct x *xx) +{ + atomic_init(&xx->y, 99); + atomic_fetch_add(&xx->y, 1); +} +]])], [tor_cv_stdatomic_works=yes], [tor_cv_stdatomic_works=no])]) + +if test "$tor_cv_stdatomic_works" = "yes"; then + AC_DEFINE(STDATOMIC_WORKS, 1, [Set to 1 if we can compile a simple stdatomic example.]) +elif test "$ac_cv_header_stdatomic_h" = "yes"; then + AC_MSG_WARN([Your compiler provides the stdatomic.h header, but it doesn't seem to work. I'll pretend it isn't there. If you are using Clang on Debian, maybe this is because of https://bugs.debian.org/903709 ]) +fi + # Now make sure that NULL can be represented as zero bytes. AC_CACHE_CHECK([whether memset(0) sets pointers to NULL], tor_cv_null_is_zero, [AC_RUN_IFELSE([AC_LANG_SOURCE( diff --git a/src/common/compat_threads.c b/src/common/compat_threads.c index 3171c4b2f2..9f64c06342 100644 --- a/src/common/compat_threads.c +++ b/src/common/compat_threads.c @@ -352,7 +352,7 @@ alert_sockets_close(alert_sockets_t *socks) socks->read_fd = socks->write_fd = -1; } -#ifndef HAVE_STDATOMIC_H +#ifndef HAVE_WORKING_STDATOMIC /** Initialize a new atomic counter with the value 0 */ void atomic_counter_init(atomic_counter_t *counter) @@ -403,5 +403,4 @@ atomic_counter_exchange(atomic_counter_t *counter, size_t newval) tor_mutex_release(&counter->mutex); return oldval; } -#endif /* !defined(HAVE_STDATOMIC_H) */ - +#endif /* !defined(HAVE_WORKING_STDATOMIC) */ diff --git a/src/common/compat_threads.h b/src/common/compat_threads.h index c93e601ec5..8bf8225689 100644 --- a/src/common/compat_threads.h +++ b/src/common/compat_threads.h @@ -14,7 +14,11 @@ #include <pthread.h> #endif -#ifdef HAVE_STDATOMIC_H +#if defined(HAVE_STDATOMIC_H) && defined(STDATOMIC_WORKS) +#define HAVE_WORKING_STDATOMIC +#endif + +#ifdef HAVE_WORKING_STDATOMIC #include <stdatomic.h> #endif @@ -156,18 +160,18 @@ void tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value); /** * Atomic counter type; holds a size_t value. */ -#ifdef HAVE_STDATOMIC_H +#ifdef HAVE_WORKING_STDATOMIC typedef struct atomic_counter_t { atomic_size_t val; } atomic_counter_t; #define ATOMIC_LINKAGE static -#else /* !(defined(HAVE_STDATOMIC_H)) */ +#else /* !(defined(HAVE_WORKING_STDATOMIC)) */ typedef struct atomic_counter_t { tor_mutex_t mutex; size_t val; } atomic_counter_t; #define ATOMIC_LINKAGE -#endif /* defined(HAVE_STDATOMIC_H) */ +#endif /* defined(HAVE_WORKING_STDATOMIC) */ ATOMIC_LINKAGE void atomic_counter_init(atomic_counter_t *counter); ATOMIC_LINKAGE void atomic_counter_destroy(atomic_counter_t *counter); @@ -178,7 +182,7 @@ ATOMIC_LINKAGE size_t atomic_counter_exchange(atomic_counter_t *counter, size_t newval); #undef ATOMIC_LINKAGE -#ifdef HAVE_STDATOMIC_H +#ifdef HAVE_WORKING_STDATOMIC /** Initialize a new atomic counter with the value 0 */ static inline void atomic_counter_init(atomic_counter_t *counter) @@ -216,8 +220,7 @@ atomic_counter_exchange(atomic_counter_t *counter, size_t newval) return atomic_exchange(&counter->val, newval); } -#else /* !(defined(HAVE_STDATOMIC_H)) */ -#endif /* defined(HAVE_STDATOMIC_H) */ +#else /* !(defined(HAVE_WORKING_STDATOMIC)) */ +#endif /* defined(HAVE_WORKING_STDATOMIC) */ #endif /* !defined(TOR_COMPAT_THREADS_H) */ - |