From a01e2597158342b2959e3b541e09cc55f3f3e1ff Mon Sep 17 00:00:00 2001 From: Carola Nitz Date: Fri, 23 Feb 2018 13:16:41 +0100 Subject: [PATCH 12/24] Work around lack of __thread storage qualifier on old macOS --- configure.ac | 4 +- include/vlc_fixups.h | 7 +++- po/POTFILES.in | 1 + src/Makefile.am | 1 + {compat => src/extras}/tdestroy.c | 67 ++++++++++++++++++------------- 5 files changed, 48 insertions(+), 32 deletions(-) rename {compat => src/extras}/tdestroy.c (59%) diff --git a/configure.ac b/configure.ac index a6ff64595e..b9c2a95c20 100644 --- a/configure.ac +++ b/configure.ac @@ -591,8 +591,8 @@ dnl Check for system libs needed need_libc=false dnl Check for usual libc functions -AC_CHECK_FUNCS([accept4 daemon fcntl flock fstatvfs fork getenv getpwuid_r isatty lstat memalign mkostemp mmap newlocale open_memstream openat pipe2 pread posix_fadvise posix_madvise posix_memalign setlocale stricmp strnicmp strptime uselocale]) -AC_REPLACE_FUNCS([aligned_alloc atof atoll dirfd fdopendir ffsll flockfile fsync getdelim getpid lfind lldiv memrchr nrand48 poll recvmsg rewind sendmsg setenv strcasecmp strcasestr strdup strlcpy strndup strnlen strnstr strsep strtof strtok_r strtoll swab tdestroy tfind timegm timespec_get strverscmp pathconf]) +AC_CHECK_FUNCS([accept4 daemon fcntl flock fstatvfs fork getenv getpwuid_r isatty lstat memalign mkostemp mmap open_memstream openat pipe2 pread posix_fadvise posix_madvise posix_memalign setlocale stricmp strnicmp strptime tdestroy uselocale]) +AC_REPLACE_FUNCS([aligned_alloc atof atoll dirfd fdopendir ffsll flockfile fsync getdelim getpid lfind lldiv memrchr nrand48 poll recvmsg rewind sendmsg setenv strcasecmp strcasestr strdup strlcpy strndup strnlen strnstr strsep strtof strtok_r strtoll swab tfind timegm timespec_get strverscmp pathconf]) AC_REPLACE_FUNCS([gettimeofday]) AC_CHECK_FUNC(fdatasync,, [AC_DEFINE(fdatasync, fsync, [Alias fdatasync() to fsync() if missing.]) diff --git a/include/vlc_fixups.h b/include/vlc_fixups.h index 239cad4d77..e1a1d13e1e 100644 --- a/include/vlc_fixups.h +++ b/include/vlc_fixups.h @@ -495,9 +495,12 @@ void *tdelete( const void *key, void **rootp, int(*cmp)(const void *, const void void twalk( const void *root, void(*action)(const void *nodep, VISIT which, int depth) ); void *lfind( const void *key, const void *base, size_t *nmemb, size_t size, int(*cmp)(const void *, const void *) ); -#endif /* HAVE_SEARCH_H */ -#ifndef HAVE_TDESTROY void tdestroy( void *root, void (*free_node)(void *nodep) ); +#else // HAVE_SEARCH_H +# ifndef HAVE_TDESTROY +void vlc_tdestroy( void *, void (*)(void *) ); +# define tdestroy vlc_tdestroy +# endif #endif /* Random numbers */ diff --git a/po/POTFILES.in b/po/POTFILES.in index 2b4319f140..cb7f3948e9 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -68,6 +68,7 @@ src/config/help.c src/config/intf.c src/darwin/error.c src/extras/libc.c +src/extras/tdestroy.c src/input/access.c src/input/clock.c src/input/clock.h diff --git a/src/Makefile.am b/src/Makefile.am index 502990c70c..044169156c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -200,6 +200,7 @@ libvlccore_la_SOURCES = \ config/getopt.c \ config/vlc_getopt.h \ extras/libc.c \ + extras/tdestroy.c \ modules/modules.h \ modules/modules.c \ modules/bank.c \ diff --git a/compat/tdestroy.c b/src/extras/tdestroy.c similarity index 59% rename from compat/tdestroy.c rename to src/extras/tdestroy.c index 6bb3480957..5c54881553 100644 --- a/compat/tdestroy.c +++ b/src/extras/tdestroy.c @@ -3,7 +3,7 @@ * @brief replacement for GNU tdestroy() */ /***************************************************************************** - * Copyright (C) 2009, 2018 Rémi Denis-Courmont + * Copyright (C) 2009 Rémi Denis-Courmont * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by @@ -24,77 +24,88 @@ # include "config.h" #endif -#include +#if defined(HAVE_SEARCH_H) && !defined(HAVE_TDESTROY) && defined(HAVE_TFIND) + #include -#ifdef HAVE_SEARCH_H -# include -#endif +#include -#ifdef HAVE_TFIND -static __thread struct +#include +#include + +static struct { const void **tab; size_t count; -} list = { NULL, 0 }; + vlc_mutex_t lock; +} list = { NULL, 0, VLC_STATIC_MUTEX }; -static void list_nodes(const void *node, const VISIT which, const int depth) +static void list_nodes (const void *node, const VISIT which, const int depth) { (void) depth; if (which != postorder && which != leaf) return; - const void **tab = realloc(list.tab, sizeof (*tab) * (list.count + 1)); - if (tab == NULL) - abort(); + const void **tab = realloc (list.tab, sizeof (*tab) * (list.count + 1)); + if (unlikely(tab == NULL)) + abort (); tab[list.count] = *(const void **)node; list.tab = tab; list.count++; } -static __thread const void *smallest; +static struct +{ + const void *node; + vlc_mutex_t lock; +} smallest = { NULL, VLC_STATIC_MUTEX }; -static int cmp_smallest(const void *a, const void *b) +static int cmp_smallest (const void *a, const void *b) { if (a == b) return 0; - if (a == smallest) + if (a == smallest.node) return -1; - if (b == smallest) + if (likely(b == smallest.node)) return +1; - abort(); + abort (); } -void tdestroy(void *root, void (*freenode)(void *)) +void vlc_tdestroy (void *root, void (*freenode) (void *)) { const void **tab; size_t count; - assert(freenode != NULL); + assert (freenode != NULL); /* Enumerate nodes in order */ - assert(list.count == 0); - twalk(root, list_nodes); + vlc_mutex_lock (&list.lock); + assert (list.count == 0); + twalk (root, list_nodes); tab = list.tab; count = list.count; list.tab = NULL; list.count = 0; + vlc_mutex_unlock (&list.lock); /* Destroy the tree */ + vlc_mutex_lock (&smallest.lock); for (size_t i = 0; i < count; i++) { - void *node = (void *)(tab[i]); + void *node = tab[i]; - smallest = node; - node = tdelete(node, &root, cmp_smallest); - assert(node != NULL); + smallest.node = node; + node = tdelete (node, &root, cmp_smallest); + assert (node != NULL); } + vlc_mutex_unlock (&smallest.lock); assert (root == NULL); /* Destroy the nodes */ for (size_t i = 0; i < count; i++) - freenode((void *)(tab[i])); - free(tab); + freenode ((void *)(tab[i])); + free (tab); } -#endif /* HAVE_TFIND */ + +#endif -- 2.19.1