Add autoconf checks for pthreads; fix #340
This commit is contained in:
1 parent
917334d18a
commit
d056668f4f
7 files changed
+155
-21
No files matched your search
@@ -0,0 +1,8 @@
|
|||||||
|
dnl Shamelessly stolen from Heimdal
|
||||||
|
dnl
|
||||||
|
dnl Look for function in any of the specified libraries
|
||||||
|
dnl
|
||||||
|
|
||||||
|
dnl AC_FIND_FUNC_NO_LIBS(func, libraries, includes, arguments, extra libs, extra args)
|
||||||
|
AC_DEFUN([AC_FIND_FUNC_NO_LIBS], [
|
||||||
|
AC_FIND_FUNC_NO_LIBS2([$1], ["" $2], [$3], [$4], [$5], [$6])])
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
dnl Shamelessly stolen from Heimdal
|
||||||
|
dnl
|
||||||
|
dnl Look for function in any of the specified libraries
|
||||||
|
dnl
|
||||||
|
|
||||||
|
dnl AC_FIND_FUNC_NO_LIBS2(func, libraries, includes, arguments, extra libs, extra args)
|
||||||
|
AC_DEFUN([AC_FIND_FUNC_NO_LIBS2], [
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([for $1])
|
||||||
|
AC_CACHE_VAL(ac_cv_funclib_$1,
|
||||||
|
[
|
||||||
|
if eval "test \"\$ac_cv_func_$1\" != yes" ; then
|
||||||
|
ac_save_LIBS="$LIBS"
|
||||||
|
for ac_lib in $2; do
|
||||||
|
case "$ac_lib" in
|
||||||
|
"") ;;
|
||||||
|
yes) ac_lib="" ;;
|
||||||
|
no) continue ;;
|
||||||
|
-l*) ;;
|
||||||
|
*) ac_lib="-l$ac_lib" ;;
|
||||||
|
esac
|
||||||
|
LIBS="$6 $ac_lib $5 $ac_save_LIBS"
|
||||||
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[$3]],[[$1($4)]])],[eval "if test -n \"$ac_lib\";then ac_cv_funclib_$1=$ac_lib; else ac_cv_funclib_$1=yes; fi";break])
|
||||||
|
done
|
||||||
|
eval "ac_cv_funclib_$1=\${ac_cv_funclib_$1-no}"
|
||||||
|
LIBS="$ac_save_LIBS"
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
eval "ac_res=\$ac_cv_funclib_$1"
|
||||||
|
|
||||||
|
if false; then
|
||||||
|
AC_CHECK_FUNCS($1)
|
||||||
|
dnl AC_CHECK_LIBS($2, foo)
|
||||||
|
fi
|
||||||
|
# $1
|
||||||
|
eval "ac_tr_func=HAVE_[]upcase($1)"
|
||||||
|
eval "ac_tr_lib=HAVE_LIB[]upcase($ac_res | sed -e 's/-l//')"
|
||||||
|
eval "LIB_$1=$ac_res"
|
||||||
|
|
||||||
|
case "$ac_res" in
|
||||||
|
yes)
|
||||||
|
eval "ac_cv_func_$1=yes"
|
||||||
|
eval "LIB_$1="
|
||||||
|
AC_DEFINE_UNQUOTED($ac_tr_func)
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
;;
|
||||||
|
no)
|
||||||
|
eval "ac_cv_func_$1=no"
|
||||||
|
eval "LIB_$1="
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
eval "ac_cv_func_$1=yes"
|
||||||
|
eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
|
||||||
|
AC_DEFINE_UNQUOTED($ac_tr_func)
|
||||||
|
AC_DEFINE_UNQUOTED($ac_tr_lib)
|
||||||
|
AC_MSG_RESULT([yes, in $ac_res])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_SUBST(LIB_$1)
|
||||||
|
])
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
dnl Shamelessly stolen from Heimdal
|
||||||
|
dnl
|
||||||
|
dnl AC_FIND_FUNC(func, libraries, includes, arguments)
|
||||||
|
AC_DEFUN([AC_FIND_FUNC], [
|
||||||
|
AC_FIND_FUNC_NO_LIBS([$1], [$2], [$3], [$4])
|
||||||
|
if test -n "$LIB_$1"; then
|
||||||
|
LIBS="$LIB_$1 $LIBS"
|
||||||
|
fi
|
||||||
|
])
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
dnl Shamelessly stolen from Heimdal
|
||||||
|
AC_DEFUN([upcase],[`echo $1 | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`])dnl
|
||||||
@@ -78,6 +78,24 @@ EOF
|
|||||||
])
|
])
|
||||||
|
|
||||||
AM_CONDITIONAL([ENABLE_DOCS], [test "x$enable_docs" != xno])
|
AM_CONDITIONAL([ENABLE_DOCS], [test "x$enable_docs" != xno])
|
||||||
|
|
||||||
|
AC_FIND_FUNC([pthread_key_create], [pthread], [#include <pthread.h>], [NULL, NULL])
|
||||||
|
AC_FIND_FUNC([pthread_once], [pthread], [#include <pthread.h>], [NULL, NULL])
|
||||||
|
AC_FIND_FUNC([atexit], [pthread], [#include <stdlib.h>], [NULL])
|
||||||
|
|
||||||
|
dnl Thread local storage
|
||||||
|
have___thread=no
|
||||||
|
AC_MSG_CHECKING(for thread-local storage)
|
||||||
|
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||||
|
static __thread int x ;
|
||||||
|
int main () { x = 123; return x; }
|
||||||
|
])], have___thread=yes)
|
||||||
|
if test $have___thread = yes; then
|
||||||
|
AC_DEFINE([HAVE___THREAD],1,[Define to 1 if the system supports __thread])
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT($have___thread)
|
||||||
|
|
||||||
|
|
||||||
AC_SUBST([BUNDLER], ["$bundle_cmd"])
|
AC_SUBST([BUNDLER], ["$bundle_cmd"])
|
||||||
|
|
||||||
AC_CONFIG_MACRO_DIR([config/m4])
|
AC_CONFIG_MACRO_DIR([config/m4])
|
||||||
|
|||||||
+52
-20
@@ -7,13 +7,27 @@ struct nomem_handler {
|
|||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef USE_PTHREAD_KEY
|
#if !defined(HAVE_PTHREAD_KEY_CREATE) || \
|
||||||
#ifdef _MSC_VER
|
!defined(HAVE_PTHREAD_ONCE) || \
|
||||||
static __declspec(thread) struct nomem_handler nomem_handler;
|
!defined(HAVE_ATEXIT)
|
||||||
#else
|
|
||||||
static __thread struct nomem_handler nomem_handler;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
/* Try thread-local storage? */
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
/* Visual C++: yes */
|
||||||
|
static __declspec(thread) struct nomem_handler nomem_handler;
|
||||||
|
#define USE_TLS
|
||||||
|
#else
|
||||||
|
#ifdef HAVE___THREAD
|
||||||
|
/* GCC and friends: yes */
|
||||||
|
static __thread struct nomem_handler nomem_handler;
|
||||||
|
#define USE_TLS
|
||||||
|
#endif /* HAVE___THREAD */
|
||||||
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
|
#endif /* !HAVE_PTHREAD_KEY_CREATE */
|
||||||
|
|
||||||
|
#ifdef USE_TLS
|
||||||
void jv_nomem_handler(jv_nomem_handler_f handler, void *data) {
|
void jv_nomem_handler(jv_nomem_handler_f handler, void *data) {
|
||||||
nomem_handler.handler = handler;
|
nomem_handler.handler = handler;
|
||||||
}
|
}
|
||||||
@@ -25,44 +39,60 @@ static void memory_exhausted() {
|
|||||||
fprintf(stderr, "error: cannot allocate memory\n");
|
fprintf(stderr, "error: cannot allocate memory\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
#else
|
#else /* USE_TLS */
|
||||||
|
|
||||||
#ifdef HAVE_PTHREAD_KEY_CREATE
|
#ifdef HAVE_PTHREAD_KEY_CREATE
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
pthread_key_t nomem_handler_key;
|
pthread_key_t nomem_handler_key;
|
||||||
pthread_once_t mem_once = PTHREAD_ONCE_INIT;
|
pthread_once_t mem_once = PTHREAD_ONCE_INIT;
|
||||||
|
|
||||||
|
static void tsd_fini(void) {
|
||||||
|
struct nomem_handler *nomem_handler;
|
||||||
|
nomem_handler = pthread_getspecific(nomem_handler_key);
|
||||||
|
if (nomem_handler) {
|
||||||
|
(void) pthread_setspecific(nomem_handler_key, NULL);
|
||||||
|
free(nomem_handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void tsd_init(void) {
|
static void tsd_init(void) {
|
||||||
if (pthread_key_create(&nomem_handler_key, NULL) != 0) {
|
if (pthread_key_create(&nomem_handler_key, NULL) != 0) {
|
||||||
fprintf(stderr, "error: cannot create thread specific key");
|
fprintf(stderr, "error: cannot create thread specific key");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
if (atexit(tsd_fini) != 0) {
|
||||||
|
fprintf(stderr, "error: cannot set an exit handler");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
struct nomem_handler *nomem_handler = calloc(1, sizeof(struct nomem_handler));
|
||||||
|
if (pthread_setspecific(nomem_handler_key, nomem_handler) != 0) {
|
||||||
|
fprintf(stderr, "error: cannot set thread specific data");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void jv_nomem_handler(jv_nomem_handler_f handler, void *data) {
|
void jv_nomem_handler(jv_nomem_handler_f handler, void *data) {
|
||||||
pthread_once(&mem_once, tsd_init); // cannot fail
|
pthread_once(&mem_once, tsd_init); // cannot fail
|
||||||
struct nomem_handler *nomem_handler = calloc(1, sizeof (nomem_handler));
|
struct nomem_handler *nomem_handler;
|
||||||
|
|
||||||
|
nomem_handler = pthread_getspecific(nomem_handler_key);
|
||||||
if (nomem_handler == NULL) {
|
if (nomem_handler == NULL) {
|
||||||
handler(data);
|
handler(data);
|
||||||
fprintf(stderr, "error: cannot allocate memory\n");
|
fprintf(stderr, "error: cannot allocate memory\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
nomem_handler.handler = handler;
|
nomem_handler->handler = handler;
|
||||||
nomem_handler.data = data;
|
nomem_handler->data = data;
|
||||||
if (pthread_setspecific(nomem_handler_key, nomem_handler) != 0) {
|
|
||||||
handler(data);
|
|
||||||
fprintf(stderr, "error: cannot set thread specific data");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void memory_exhausted() {
|
static void memory_exhausted() {
|
||||||
jv_nomem_handler_f handler;
|
struct nomem_handler *nomem_handler;
|
||||||
|
|
||||||
pthread_once(&mem_once, tsd_init);
|
pthread_once(&mem_once, tsd_init);
|
||||||
handler = pthread_getspecific(nomem_handler_key);
|
nomem_handler = pthread_getspecific(nomem_handler_key);
|
||||||
if (handler)
|
if (nomem_handler)
|
||||||
handler(); // Maybe handler() will longjmp() to safety
|
nomem_handler->handler(nomem_handler->data); // Maybe handler() will longjmp() to safety
|
||||||
// Or not
|
// Or not
|
||||||
fprintf(stderr, "error: cannot allocate memory\n");
|
fprintf(stderr, "error: cannot allocate memory\n");
|
||||||
abort();
|
abort();
|
||||||
@@ -70,6 +100,8 @@ static void memory_exhausted() {
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
/* No thread-local storage of any kind that we know how to handle */
|
||||||
|
|
||||||
static struct nomem_handler nomem_handler;
|
static struct nomem_handler nomem_handler;
|
||||||
void jv_nomem_handler(jv_nomem_handler_f handler, void *data) {
|
void jv_nomem_handler(jv_nomem_handler_f handler, void *data) {
|
||||||
nomem_handler.handler = handler;
|
nomem_handler.handler = handler;
|
||||||
@@ -82,7 +114,7 @@ static void memory_exhausted() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_PTHREAD_KEY_CREATE */
|
#endif /* HAVE_PTHREAD_KEY_CREATE */
|
||||||
#endif /* !USE_PTHREAD_KEY */
|
#endif /* USE_TLS */
|
||||||
|
|
||||||
|
|
||||||
void* jv_mem_alloc(size_t sz) {
|
void* jv_mem_alloc(size_t sz) {
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
|
|
||||||
if [ "clean" == "$1" ]; then
|
if [ "clean" == "$1" ]; then
|
||||||
make distclean || echo "continuing..."
|
make distclean || echo "continuing..."
|
||||||
rm -rf tmp autom4te.cache config
|
find config/m4 -type f \( -name libtool\* -o -name lt\* \) | xargs rm -f
|
||||||
|
find config -name m4 -prune -o -type f -print | xargs rm -f
|
||||||
|
rm -rf tmp autom4te.cache
|
||||||
rm -f INSTALL Makefile.in aclocal.m4 configure config.h.in ChangeLog
|
rm -f INSTALL Makefile.in aclocal.m4 configure config.h.in ChangeLog
|
||||||
rm -f jv_utf8_tables.gen.h lexer.c lexer.h parser.c parser.h
|
rm -f jv_utf8_tables.gen.h lexer.c lexer.h parser.c parser.h
|
||||||
elif [ "superclean" == "$1" ]; then
|
elif [ "superclean" == "$1" ]; then
|
||||||
|
|||||||
Reference in new issue
Block a user