On 19/08/2010 17:55, Carlos O'Donell wrote: > On Thu, Aug 19, 2010 at 11:00 AM, Mehdi Dogguy <me...@dogguy.org> > wrote: >> On 19/08/2010 16:29, Yavor Doganov wrote: >>> В 16:15 +0200 на 19.08.2010 (чт), Mehdi Dogguy написа: >>>> On 19/08/2010 15:45, Yavor Doganov wrote: >>>>> Thanks, informing upstream. Can you narrow it down a bit >>>>> more? >>>> >>>> I narrowed it down to r28600:r28625. >>> >> >> It's even r28610:r28615. > > I'm the person to ask about hppa and NPTL (I wrote the code). > > There *was* a vfork bug that was just fixed in glibc that could cause > problems. > > Does this code use vfork? >
I was testing the produced gdnc binary, which uses NSTask, which uses vfork. But, afaics, the libc installed in the chroot is 2.11.2-2 and has the fix about vfork. FWIW, the diff (between r28611:r28613) is attached. Cheers, -- Mehdi Dogguy مهدي الدڤي http://dogguy.org/
Index: configure =================================================================== --- configure (revision 28611) +++ configure (revision 28613) @@ -310,7 +310,7 @@ #endif" ac_subdirs_all="$ac_subdirs_all Source/pathconfig Source/mframe SSL" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP WHOAMI EGREP OBJC_WITH_GC GS_WORDS_BIGENDIAN GS_SINT8 GS_UINT8 ac_cv_sizeof_short ac_cv_sizeof_int ac_cv_sizeof_long ac_cv_sizeof_long_long ac_cv_sizeof_float ac_cv_sizeof_double ac_cv_sizeof_voidp GS_SADDR GS_UADDR GS_SINT16 GS_UINT16 GS_SINT32 GS_UINT32 GS_SINT64 GS_UINT64 GS_HAVE_I64 GS_SINT128 GS_UINT128 GS_HAVE_I128 GS_FLT32 GS_FLT64 _GSC_S_SHT _GSC_S_INT _GSC_S_LNG _GSC_S_LNG_LNG DYNAMIC_LINKER NX_CONST_STRING_OBJCFLAGS NX_CONST_STRING_CLASS HAVE_OBJC_SYNC_ENTER HAVE_PTHREAD_H HAVE_PTS_STREAM_MODULES INCLUDE_STDINT DEFINE_INT8_T DEFINE_UINT8_T DEFINE_INT16_T DEFINE_UINT16_T DEFINE_INT32_T DEFINE_UINT32_T DEFINE_INT64_T DEFINE_UINT64_T DEFINE_INTPTR_T DEFINE_UINTPTR_T USE_ZLIB HAVE_INET_PTON HAVE_INET_NTOP GS_PASS_ARGUMENTS GS_FAKE_MAIN WITH_FFI XML2_CONFIG XML_CONFIG XML_CFLAGS XML_LIBS HAVE_LIBXSLT HAVE_LIBXML TLS_CONFIG TLS_CFLAGS TLS_LIBS HAVE_GNUTLS HAVE_MDNS USE_GMP INCLUDE_FLAGS LDIR_FLAGS subdirs VERSION MAJOR_VERSION MINOR_VERSION SUBMINOR_VERSION GCC_VERSION LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP WHOAMI EGREP OBJC_WITH_GC GS_WORDS_BIGENDIAN GS_SINT8 GS_UINT8 ac_cv_sizeof_short ac_cv_sizeof_int ac_cv_sizeof_long ac_cv_sizeof_long_long ac_cv_sizeof_float ac_cv_sizeof_double ac_cv_sizeof_voidp GS_SADDR GS_UADDR GS_SINT16 GS_UINT16 GS_SINT32 GS_UINT32 GS_SINT64 GS_UINT64 GS_HAVE_I64 GS_SINT128 GS_UINT128 GS_HAVE_I128 GS_FLT32 GS_FLT64 _GSC_S_SHT _GSC_S_INT _GSC_S_LNG _GSC_S_LNG_LNG DYNAMIC_LINKER NX_CONST_STRING_OBJCFLAGS NX_CONST_STRING_CLASS HAVE_OBJC_SYNC_ENTER HAVE_PTHREAD_H GS_SIZEOF_MUTEX_T GS_SIZEOF_COND_T HAVE_PTS_STREAM_MODULES INCLUDE_STDINT DEFINE_INT8_T DEFINE_UINT8_T DEFINE_INT16_T DEFINE_UINT16_T DEFINE_INT32_T DEFINE_UINT32_T DEFINE_INT64_T DEFINE_UINT64_T DEFINE_INTPTR_T DEFINE_UINTPTR_T USE_ZLIB HAVE_INET_PTON HAVE_INET_NTOP GS_PASS_ARGUMENTS GS_FAKE_MAIN WITH_FFI XML2_CONFIG XML_CONFIG XML_CFLAGS XML_LIBS HAVE_LIBXSLT HAVE_LIBXML TLS_CONFIG TLS_CFLAGS TLS_LIBS HAVE_GNUTLS HAVE_MDNS USE_GMP INCLUDE_FLAGS LDIR_FLAGS subdirs VERSION MAJOR_VERSION MINOR_VERSION SUBMINOR_VERSION GCC_VERSION LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -12006,12 +12006,848 @@ LIBS="$saved_LIBS" CPPFLAGS="$saved_CPPFLAGS" fi +else + { { echo "$as_me:$LINENO: error: Unable to find pthreads (needed for essential thread support)." >&5 +echo "$as_me: error: Unable to find pthreads (needed for essential thread support)." >&2;} + { (exit 1); exit 1; }; } fi if test x"$objc_threaded" = x"-pthread"; then LIBS="$LIBS -lpthread" fi +echo "$as_me:$LINENO: checking for pthread_mutex_t" >&5 +echo $ECHO_N "checking for pthread_mutex_t... $ECHO_C" >&6 +if test "${ac_cv_type_pthread_mutex_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((pthread_mutex_t *) 0) + return 0; +if (sizeof (pthread_mutex_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_pthread_mutex_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 +ac_cv_type_pthread_mutex_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_pthread_mutex_t" >&5 +echo "${ECHO_T}$ac_cv_type_pthread_mutex_t" >&6 + +echo "$as_me:$LINENO: checking size of pthread_mutex_t" >&5 +echo $ECHO_N "checking size of pthread_mutex_t... $ECHO_C" >&6 +if test "${ac_cv_sizeof_pthread_mutex_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_pthread_mutex_t" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (pthread_mutex_t))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (pthread_mutex_t))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (pthread_mutex_t))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (pthread_mutex_t))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo= ac_hi= +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (pthread_mutex_t))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_pthread_mutex_t=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (pthread_mutex_t), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (pthread_mutex_t), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +long longval () { return (long) (sizeof (pthread_mutex_t)); } +unsigned long ulongval () { return (long) (sizeof (pthread_mutex_t)); } +#include <stdio.h> +#include <stdlib.h> +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (pthread_mutex_t))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (pthread_mutex_t)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (pthread_mutex_t)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_pthread_mutex_t=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (pthread_mutex_t), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (pthread_mutex_t), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_pthread_mutex_t=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_pthread_mutex_t" >&5 +echo "${ECHO_T}$ac_cv_sizeof_pthread_mutex_t" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_PTHREAD_MUTEX_T $ac_cv_sizeof_pthread_mutex_t +_ACEOF + + +GS_SIZEOF_MUTEX_T=$ac_cv_sizeof_pthread_mutex_t + +echo "$as_me:$LINENO: checking for pthread_cond_t" >&5 +echo $ECHO_N "checking for pthread_cond_t... $ECHO_C" >&6 +if test "${ac_cv_type_pthread_cond_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((pthread_cond_t *) 0) + return 0; +if (sizeof (pthread_cond_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_pthread_cond_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_pthread_cond_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_pthread_cond_t" >&5 +echo "${ECHO_T}$ac_cv_type_pthread_cond_t" >&6 + +echo "$as_me:$LINENO: checking size of pthread_cond_t" >&5 +echo $ECHO_N "checking size of pthread_cond_t... $ECHO_C" >&6 +if test "${ac_cv_sizeof_pthread_cond_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_pthread_cond_t" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (pthread_cond_t))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (pthread_cond_t))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (pthread_cond_t))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (pthread_cond_t))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo= ac_hi= +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (pthread_cond_t))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_pthread_cond_t=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (pthread_cond_t), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (pthread_cond_t), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +long longval () { return (long) (sizeof (pthread_cond_t)); } +unsigned long ulongval () { return (long) (sizeof (pthread_cond_t)); } +#include <stdio.h> +#include <stdlib.h> +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (pthread_cond_t))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (pthread_cond_t)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (pthread_cond_t)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_pthread_cond_t=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (pthread_cond_t), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (pthread_cond_t), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_pthread_cond_t=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_pthread_cond_t" >&5 +echo "${ECHO_T}$ac_cv_sizeof_pthread_cond_t" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_PTHREAD_COND_T $ac_cv_sizeof_pthread_cond_t +_ACEOF + + +GS_SIZEOF_COND_T=$ac_cv_sizeof_pthread_cond_t + + #-------------------------------------------------------------------- # This function needed by StdioStream.m #-------------------------------------------------------------------- @@ -20280,6 +21116,8 @@ s,@NX_CONST_STRING_CLASS@,$NX_CONST_STRING_CLASS,;t t s,@HAVE_OBJC_SYNC_ENTER@,$HAVE_OBJC_SYNC_ENTER,;t t s,@HAVE_PTHREAD_H@,$HAVE_PTHREAD_H,;t t +s,@GS_SIZEOF_MUTEX_T@,$GS_SIZEOF_MUTEX_T,;t t +s,@GS_SIZEOF_COND_T@,$GS_SIZEOF_COND_T,;t t s,@HAVE_PTS_STREAM_MODULES@,$HAVE_PTS_STREAM_MODULES,;t t s,@INCLUDE_STDINT@,$INCLUDE_STDINT,;t t s,@DEFINE_INT8_T@,$DEFINE_INT8_T,;t t Index: Source/NSRunLoop.m =================================================================== --- Source/NSRunLoop.m (revision 28611) +++ Source/NSRunLoop.m (revision 28613) @@ -940,7 +940,7 @@ GSIArrayRemoveItemAtIndex(timers, i); } } - for (i = 0; recheck == NO && i < GSIArrayCount(timers); i++) + for (i = 0; i < GSIArrayCount(timers); i++) { NSDate *d; @@ -1025,6 +1025,27 @@ * the context. */ recheck = YES; + /* It's possible that the system time was changed + * while we have been running, and that the timer + * which just fired caused another timer to be + * scheduled using a time in the past relative to + * 'now'. If we checked it again, we would fire it + * again and could in this way end up repeatedly + * firing a timer as fast as we possibly can until + * the system time in in sync with 'now'. + * To prevent this, we re-cache 'now' with the + * current system time if that time is in the past. + * We can't do that unconditionally though, because + * doing so would defeat the whole point of caching + * 'now' ... to prevent a repeated slow timed event + * from continually firing. + */ + ti = GSTimeNow(); + if (ti < now) + { + now = ti; + } + break; } else { Index: Source/NSLock.m =================================================================== --- Source/NSLock.m (revision 28611) +++ Source/NSLock.m (revision 28613) @@ -27,10 +27,14 @@ // them. Other platforms have more sensible libcs, which just default to being // standards-compliant. #define _XOPEN_SOURCE 500 -#include "Foundation/NSLock.h" +#include <pthread.h> +#import "GNUstepBase/GSConfig.h" +#define gs_cond_t pthread_cond_t +#define gs_mutex_t pthread_mutex_t +#import "Foundation/NSLock.h" #include <math.h> #include <errno.h> -#include "Foundation/NSException.h" +#import "Foundation/NSException.h" /** * Methods shared between NSLock, NSRecursiveLock, and NSCondition Index: configure.ac =================================================================== --- configure.ac (revision 28611) +++ configure.ac (revision 28613) @@ -854,11 +854,19 @@ LIBS="$saved_LIBS" CPPFLAGS="$saved_CPPFLAGS" fi +else + AC_MSG_ERROR([Unable to find pthreads (needed for essential thread support).]) fi AC_SUBST(HAVE_PTHREAD_H) if test x"$objc_threaded" = x"-pthread"; then LIBS="$LIBS -lpthread" fi +AC_CHECK_SIZEOF(pthread_mutex_t) +GS_SIZEOF_MUTEX_T=$ac_cv_sizeof_pthread_mutex_t +AC_SUBST(GS_SIZEOF_MUTEX_T) +AC_CHECK_SIZEOF(pthread_cond_t) +GS_SIZEOF_COND_T=$ac_cv_sizeof_pthread_cond_t +AC_SUBST(GS_SIZEOF_COND_T) #-------------------------------------------------------------------- # This function needed by StdioStream.m Index: Headers/Foundation/NSLock.h =================================================================== --- Headers/Foundation/NSLock.h (revision 28611) +++ Headers/Foundation/NSLock.h (revision 28613) @@ -32,11 +32,10 @@ #ifndef __NSLock_h_GNUSTEP_BASE_INCLUDE #define __NSLock_h_GNUSTEP_BASE_INCLUDE #import <GNUstepBase/GSVersionMacros.h> +#import <GNUstepBase/GSConfig.h> #import <Foundation/NSObject.h> -#include <pthread.h> - #if defined(__cplusplus) extern "C" { #endif @@ -59,21 +58,22 @@ @end /** - * Simplest lock for protecting critical sections of code. - * - * An <code>NSLock</code> is used in multi-threaded applications to protect + * <p>Simplest lock for protecting critical sections of code. + * </p> + * <p>An <code>NSLock</code> is used in multi-threaded applications to protect * critical pieces of code. While one thread holds a lock within a piece of * code, another thread cannot execute that code until the first thread has * given up its hold on the lock. The limitation of <code>NSLock</code> is * that you can only lock an <code>NSLock</code> once and it must be unlocked * before it can be acquired again.<br /> Other lock classes, notably * [NSRecursiveLock], have different restrictions. + * </p> */ @interface NSLock : NSObject <NSLocking> { @private - pthread_mutex_t _mutex; - NSString *_name; + gs_mutex_t _mutex; + NSString *_name; } /** @@ -114,34 +114,40 @@ @interface NSCondition : NSObject <NSLocking> { @private - pthread_cond_t _condition; - pthread_mutex_t _mutex; - NSString *_name; + gs_cond_t _condition; + gs_mutex_t _mutex; + NSString *_name; } /** - * Blocks atomically unlocks the receiver. This method should only be called - * when the receiver is locked. The caller will then block until the receiver - * is sent either a -signal or -broadcast message from another thread. At this + * Blocks and atomically unlocks the receiver. + * This method should only be called when the receiver is locked. + * The caller will then block until the receiver is sent either a -signal + * or -broadcast message from another thread. At which * point, the calling thread will reacquire the lock. */ - (void) wait; + /** * Blocks the calling thread and acquires the lock, in the same way as -wait. * Returns YES if the condition is signaled, or NO if the timeout is reached. */ - (BOOL) waitUntilDate: (NSDate*)limit; + /** - * Wakes a single thread that is waiting on this condition. + * Wakes wany one of the threads that are waiting on this condition. */ - (void) signal; + /** * Wakes all threads that are waiting on this condition. */ - (void) broadcast; + /** * Sets the name used for debugging messages. */ - (void) setName: (NSString*)newName; + /** * Returns the name used for debugging messages. */ @@ -247,7 +253,7 @@ @interface NSRecursiveLock : NSObject <NSLocking> { @private - pthread_mutex_t _mutex; + gs_mutex_t _mutex; NSString *_name; } Index: Headers/Additions/GNUstepBase/GSConfig.h.in =================================================================== --- Headers/Additions/GNUstepBase/GSConfig.h.in (revision 28611) +++ Headers/Additions/GNUstepBase/GSConfig.h.in (revision 28613) @@ -203,5 +203,18 @@ #define GSNativeChar char #endif +/* + * Types used to avoid exposing pthread header in NSLock.h + * NB. These types should *never* be used except to provide enough space + * in a class layout for the type of data actually used by the pthread + * implementation of the current platform. + */ +typedef struct { + uint8_t dum...@gs_sizeof_cond_t@]; +} gs_cond_t; +typedef struct { + uint8_t dum...@gs_sizeof_mutex_t@]; +} gs_mutex_t; + #endif /* included_GSConfig_h */ Index: Headers/Additions/GNUstepBase/config.h.in =================================================================== --- Headers/Additions/GNUstepBase/config.h.in (revision 28611) +++ Headers/Additions/GNUstepBase/config.h.in (revision 28613) @@ -504,6 +504,9 @@ /* The size of a `long long', as computed by sizeof. */ #undef SIZEOF_LONG_LONG +/* The size of a `pthread_mutex_t', as computed by sizeof. */ +#undef SIZEOF_PTHREAD_MUTEX_T + /* The size of a `short', as computed by sizeof. */ #undef SIZEOF_SHORT Index: ChangeLog =================================================================== --- ChangeLog (revision 28611) +++ ChangeLog (revision 28613) @@ -1,6 +1,25 @@ +2009-09-06 Richard Frith-Macdonald <r...@gnu.org> + + * Source/NSRunLoop.m: Fix for rare problem if someone changes the + system time backwards. + * configure.ac: Check for pthread.h and type sizes. Insist on having + pthread.h in order to build, now that it is a requirement. + * configure: Regenerate + * Headers/Additions/GNUstepBase/GSConfig.h.in: Declare abstract types. + * Source/NSLock.m: including pthread.h + * Headers/Foundation/NSLock.h: Avoid including pthread.h + Basically, insist on finding pthread.h at configure time, and get size + of essential types so we can avoid exposing them directly in our + public headers. This should discourage developers from using things + they shouldn't, but it does not solve the issue that copies of the base + library built with different pthread implementations on the same + platform may have binary incompatible NSLock classes (with respect to + subclassing as the pthread specific ivars differ in size). However + this is *really* unlikely to be an issue in practice. + 2009-09-05 David Chisnall <csda...@swan.ac.uk> - * Source/NSEnumberation.m: Added enumeration mutation callback. + * Source/NSEnumeration.m: Added enumeration mutation callback. 2009-09-03 Richard Frith-Macdonald <r...@gnu.org>