diff options
| author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2025-09-17 11:06:17 (GMT) |
|---|---|---|
| committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2025-09-17 11:06:17 (GMT) |
| commit | 866aec41d6d17c05d6260437e4a73628a8c0e109 (patch) | |
| tree | 1d1394c1a15d2ff55655a141902c23ae40599cb1 | |
| parent | 43ff0b5efc8e10a866c2d03ef5a8a118f3fdae34 (diff) | |
| parent | fe0a86c6895ab6837f6aa5d3352657b0865ae92f (diff) | |
| download | tcl-866aec41d6d17c05d6260437e4a73628a8c0e109.zip tcl-866aec41d6d17c05d6260437e4a73628a8c0e109.tar.gz tcl-866aec41d6d17c05d6260437e4a73628a8c0e109.tar.bz2 | |
Rebase branch to 9.0
| -rwxr-xr-x | unix/configure | 294 | ||||
| -rw-r--r-- | unix/tcl.m4 | 3 | ||||
| -rw-r--r-- | unix/tclConfig.h.in | 4 | ||||
| -rw-r--r-- | unix/tclUnixThrd.c | 48 | ||||
| -rw-r--r-- | win/tclWinThrd.c | 66 |
5 files changed, 198 insertions, 217 deletions
diff --git a/unix/configure b/unix/configure index 4d96bdc..03ca289 100755 --- a/unix/configure +++ b/unix/configure @@ -1785,60 +1785,6 @@ printf "%s\n" "$ac_res" >&6; } } # ac_fn_c_check_func -# ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR -# ------------------------------------------------------------------ -# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR -# accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR. -ac_fn_check_decl () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - as_decl_name=`echo $2|sed 's/ *(.*//'` - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 -printf %s "checking whether $as_decl_name is declared... " >&6; } -if eval test \${$3+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` - eval ac_save_FLAGS=\$$6 - as_fn_append $6 " $5" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main (void) -{ -#ifndef $as_decl_name -#ifdef __cplusplus - (void) $as_decl_use; -#else - (void) $as_decl_name; -#endif -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - eval "$3=yes" -else case e in #( - e) eval "$3=no" ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - eval $6=\$ac_save_FLAGS - ;; -esac -fi -eval ac_res=\$$3 - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_check_decl - # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache @@ -1942,6 +1888,60 @@ fi } # ac_fn_c_try_run +# ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR +# ------------------------------------------------------------------ +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR. +ac_fn_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +printf %s "checking whether $as_decl_name is declared... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + eval ac_save_FLAGS=\$$6 + as_fn_append $6 " $5" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$3=yes" +else case e in #( + e) eval "$3=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + eval $6=\$ac_save_FLAGS + ;; +esac +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_check_decl + # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including @@ -4366,89 +4366,6 @@ printf "%s\n" "#define TCL_CFGVAL_ENCODING \"utf-8\"" >>confdefs.h # Look for libraries that we will need when compiling the Tcl shell #-------------------------------------------------------------------- -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5 -printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; } -if test ${ac_cv_c_undeclared_builtin_options+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) ac_save_CFLAGS=$CFLAGS - ac_cv_c_undeclared_builtin_options='cannot detect' - for ac_arg in '' -fno-builtin; do - CFLAGS="$ac_save_CFLAGS $ac_arg" - # This test program should *not* compile successfully. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ -(void) strchr; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - -else case e in #( - e) # This test program should compile successfully. - # No library function is consistently available on - # freestanding implementations, so test against a dummy - # declaration. Include always-available headers on the - # off chance that they somehow elicit warnings. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <float.h> -#include <limits.h> -#include <stdarg.h> -#include <stddef.h> -extern void ac_decl (int, char *); - -int -main (void) -{ -(void) ac_decl (0, (char *) 0); - (void) ac_decl; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - if test x"$ac_arg" = x -then : - ac_cv_c_undeclared_builtin_options='none needed' -else case e in #( - e) ac_cv_c_undeclared_builtin_options=$ac_arg ;; -esac -fi - break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - done - CFLAGS=$ac_save_CFLAGS - ;; -esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5 -printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; } - case $ac_cv_c_undeclared_builtin_options in #( - 'cannot detect') : - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} -as_fn_error $? "cannot make $CC report undeclared builtins -See 'config.log' for more details" "$LINENO" 5; } ;; #( - 'none needed') : - ac_c_undeclared_builtin_options='' ;; #( - *) : - ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;; -esac - #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is @@ -4987,26 +4904,6 @@ fi LIBS=$ac_saved_libs - # TIP #509 - ac_fn_check_decl "$LINENO" "PTHREAD_MUTEX_RECURSIVE" "ac_cv_have_decl_PTHREAD_MUTEX_RECURSIVE" "#include <pthread.h> -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_PTHREAD_MUTEX_RECURSIVE" = xyes -then : - ac_have_decl=1 -else case e in #( - e) ac_have_decl=0 ;; -esac -fi -printf "%s\n" "#define HAVE_DECL_PTHREAD_MUTEX_RECURSIVE $ac_have_decl" >>confdefs.h -if test $ac_have_decl = 1 -then : - tcl_ok=yes -else case e in #( - e) tcl_ok=no ;; -esac -fi - - # Add the threads support libraries LIBS="$LIBS$THREADS_LIBS" @@ -9054,6 +8951,89 @@ printf "%s\n" "#define HAVE_MTSAFE_GETHOSTBYADDR 1" >>confdefs.h else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5 +printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; } +if test ${ac_cv_c_undeclared_builtin_options+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_save_CFLAGS=$CFLAGS + ac_cv_c_undeclared_builtin_options='cannot detect' + for ac_arg in '' -fno-builtin; do + CFLAGS="$ac_save_CFLAGS $ac_arg" + # This test program should *not* compile successfully. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +(void) strchr; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else case e in #( + e) # This test program should compile successfully. + # No library function is consistently available on + # freestanding implementations, so test against a dummy + # declaration. Include always-available headers on the + # off chance that they somehow elicit warnings. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <float.h> +#include <limits.h> +#include <stdarg.h> +#include <stddef.h> +extern void ac_decl (int, char *); + +int +main (void) +{ +(void) ac_decl (0, (char *) 0); + (void) ac_decl; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + if test x"$ac_arg" = x +then : + ac_cv_c_undeclared_builtin_options='none needed' +else case e in #( + e) ac_cv_c_undeclared_builtin_options=$ac_arg ;; +esac +fi + break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done + CFLAGS=$ac_save_CFLAGS + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5 +printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; } + case $ac_cv_c_undeclared_builtin_options in #( + 'cannot detect') : + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "cannot make $CC report undeclared builtins +See 'config.log' for more details" "$LINENO" 5; } ;; #( + 'none needed') : + ac_c_undeclared_builtin_options='' ;; #( + *) : + ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;; +esac + # Avoids picking hidden internal symbol from libc ac_fn_check_decl "$LINENO" "gethostbyname_r" "ac_cv_have_decl_gethostbyname_r" "#include <netdb.h> diff --git a/unix/tcl.m4 b/unix/tcl.m4 index ce01ee8..1355017 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -2258,9 +2258,6 @@ AC_DEFUN([SC_TCL_LINK_LIBS], [ LIBS="$LIBS $THREADS_LIBS" AC_CHECK_FUNCS(pthread_attr_setstacksize pthread_atfork) LIBS=$ac_saved_libs - - # TIP #509 - AC_CHECK_DECLS([PTHREAD_MUTEX_RECURSIVE],tcl_ok=yes,tcl_ok=no, [[#include <pthread.h>]]) ]) #-------------------------------------------------------------------- diff --git a/unix/tclConfig.h.in b/unix/tclConfig.h.in index 78ea8c9..b07701f 100644 --- a/unix/tclConfig.h.in +++ b/unix/tclConfig.h.in @@ -39,10 +39,6 @@ you don't. */ #undef HAVE_DECL_GETHOSTBYNAME_R -/* Define to 1 if you have the declaration of 'PTHREAD_MUTEX_RECURSIVE', and - to 0 if you don't. */ -#undef HAVE_DECL_PTHREAD_MUTEX_RECURSIVE - /* Is 'DIR64' in <sys/types.h>? */ #undef HAVE_DIR64 diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index 24bc72d..219d0c6 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -61,40 +61,9 @@ *---------------------------------------------------------------------- */ -#ifndef HAVE_DECL_PTHREAD_MUTEX_RECURSIVE -#define HAVE_DECL_PTHREAD_MUTEX_RECURSIVE 0 -#endif - -#if HAVE_DECL_PTHREAD_MUTEX_RECURSIVE /* - * Pthread has native reentrant (AKA recursive) mutexes. Use them for - * Tcl_Mutex. - */ - -typedef pthread_mutex_t PMutex; - -static void -PMutexInit( - PMutex *pmutexPtr) -{ - pthread_mutexattr_t attr; - - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(pmutexPtr, &attr); -} - -#define PMutexDestroy pthread_mutex_destroy -#define PMutexLock pthread_mutex_lock -#define PMutexUnlock pthread_mutex_unlock -#define PCondWait pthread_cond_wait -#define PCondTimedWait pthread_cond_timedwait - -#else /* !HAVE_PTHREAD_MUTEX_RECURSIVE */ - -/* - * No native support for reentrant mutexes. Emulate them with regular mutexes - * and thread-local counters. + * No correct native support for reentrant mutexes. Emulate them with regular mutexes + * and threadlocal counters. */ typedef struct PMutex { @@ -147,7 +116,13 @@ PCondWait( pthread_cond_t *pcondPtr, PMutex *pmutexPtr) { + int counter = pmutexPtr->counter; + + pmutexPtr->thread = 0; + pmutexPtr->counter = 0; pthread_cond_wait(pcondPtr, &pmutexPtr->mutex); + pmutexPtr->thread = pthread_self(); + pmutexPtr->counter = counter; } static void @@ -156,9 +131,14 @@ PCondTimedWait( PMutex *pmutexPtr, struct timespec *ptime) { + int counter = pmutexPtr->counter; + + pmutexPtr->thread = 0; + pmutexPtr->counter = 0; pthread_cond_timedwait(pcondPtr, &pmutexPtr->mutex, ptime); + pmutexPtr->thread = pthread_self(); + pmutexPtr->counter = counter; } -#endif /* HAVE_PTHREAD_MUTEX_RECURSIVE */ /* * globalLock is used to serialize creation of mutexes, condition variables, diff --git a/win/tclWinThrd.c b/win/tclWinThrd.c index 13ec5f4..7383af0 100644 --- a/win/tclWinThrd.c +++ b/win/tclWinThrd.c @@ -48,6 +48,16 @@ static struct Tcl_Mutex_ { } allocLock; static Tcl_Mutex allocLockPtr = &allocLock; static int allocOnce = 0; +/* + * Although CRITICAL_SECTIONs can be nested, we need to keep track + * of their lock counts for condition variables. + */ + +typedef struct WMutex { + CRITICAL_SECTION crit; + volatile Tcl_ThreadId thread; + volatile int counter; +} WMutex; #endif /* TCL_THREADS */ @@ -553,9 +563,9 @@ static void FinalizeConditionEvent(void *data); void Tcl_MutexLock( - Tcl_Mutex *mutexPtr) /* The lock */ + Tcl_Mutex *mutexPtr) /* Really (WMutex **) */ { - CRITICAL_SECTION *csPtr; + WMutex *wmPtr; if (*mutexPtr == NULL) { TclpGlobalLock(); @@ -565,15 +575,23 @@ Tcl_MutexLock( */ if (*mutexPtr == NULL) { - csPtr = (CRITICAL_SECTION *) Tcl_Alloc(sizeof(CRITICAL_SECTION)); - InitializeCriticalSection(csPtr); - *mutexPtr = (Tcl_Mutex) csPtr; + wmPtr = (WMutex *) Tcl_Alloc(sizeof(WMutex)); + InitializeCriticalSection(&wmPtr->crit); + wmPtr->thread = 0; + wmPtr->counter = 0; + *mutexPtr = (Tcl_Mutex) wmPtr; TclRememberMutex(mutexPtr); } TclpGlobalUnlock(); + } else { + wmPtr = *((WMutex **)mutexPtr); + } + if (wmPtr->thread != Tcl_GetCurrentThread() || wmPtr->counter == 0) { + EnterCriticalSection(&wmPtr->crit); + wmPtr->thread = Tcl_GetCurrentThread(); + wmPtr->counter = 0; } - csPtr = *((CRITICAL_SECTION **)mutexPtr); - EnterCriticalSection(csPtr); + wmPtr->counter++; } /* @@ -594,11 +612,15 @@ Tcl_MutexLock( void Tcl_MutexUnlock( - Tcl_Mutex *mutexPtr) /* The lock */ + Tcl_Mutex *mutexPtr) /* Really (WMutex **) */ { - CRITICAL_SECTION *csPtr = *((CRITICAL_SECTION **)mutexPtr); + WMutex *wmPtr = *((WMutex **)mutexPtr); - LeaveCriticalSection(csPtr); + wmPtr->counter--; + if (wmPtr->counter == 0) { + wmPtr->thread = 0; + LeaveCriticalSection(&wmPtr->crit); + } } /* @@ -620,13 +642,14 @@ Tcl_MutexUnlock( void TclpFinalizeMutex( - Tcl_Mutex *mutexPtr) + Tcl_Mutex *mutexPtr) /* Really (WMutex **) */ { - CRITICAL_SECTION *csPtr = *(CRITICAL_SECTION **)mutexPtr; + WMutex *wmPtr; - if (csPtr != NULL) { - DeleteCriticalSection(csPtr); - Tcl_Free(csPtr); + if (mutexPtr != NULL) { + wmPtr = *((WMutex **)mutexPtr); + DeleteCriticalSection(&wmPtr->crit); + Tcl_Free(wmPtr); *mutexPtr = NULL; } } @@ -660,9 +683,10 @@ Tcl_ConditionWait( const Tcl_Time *timePtr) /* Timeout on waiting period */ { WinCondition *winCondPtr; /* Per-condition queue head */ - CRITICAL_SECTION *csPtr; /* Caller's Mutex, after casting */ + WMutex *wmPtr; /* Caller's Mutex, after casting */ DWORD wtime; /* Windows time value */ int timeout; /* True if we got a timeout */ + int counter; /* Caller's Mutex counter */ int doExit = 0; /* True if we need to do exit setup */ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -717,7 +741,7 @@ Tcl_ConditionWait( } TclpGlobalUnlock(); } - csPtr = *((CRITICAL_SECTION **)mutexPtr); + wmPtr = *((WMutex **)mutexPtr); winCondPtr = *((WinCondition **)condPtr); if (timePtr == NULL) { wtime = INFINITE; @@ -752,7 +776,10 @@ Tcl_ConditionWait( * thread. */ - LeaveCriticalSection(csPtr); + counter = wmPtr->counter; + wmPtr->thread = 0; + wmPtr->counter = 0; + LeaveCriticalSection(&wmPtr->crit); timeout = 0; while (!timeout && (tsdPtr->flags & WIN_THREAD_BLOCKED)) { ResetEvent(tsdPtr->condEvent); @@ -795,7 +822,8 @@ Tcl_ConditionWait( } LeaveCriticalSection(&winCondPtr->condLock); - EnterCriticalSection(csPtr); + Tcl_MutexLock(mutexPtr); + wmPtr->counter = counter; } /* |
