Tcl package Thread source code

Changes On Branch bug-a57b6c3fd4
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch bug-a57b6c3fd4 Excluding Merge-Ins

This is equivalent to a diff from 593a90d9bc to f4a8039bf0

2015-09-30
11:32
Fix [a57b6c3fd4]: -eventmark + thread::send -async == deadlock check-in: 76b05d44a0 user: jan.nijtmans tags: trunk
2015-09-26
02:44
Added a SHED definition check-in: 70528a315b user: seandeelywoods tags: trunk-fork
2015-06-03
21:47
Bump the version number in the code to match configure(.in) check-in: ca155c040e user: andreask tags: trunk
2015-05-25
13:11
Merge trunk check-in: a1bb70903a user: jan.nijtmans tags: novem-support
13:11
merge-mark check-in: 078ff8e546 user: jan.nijtmans tags: novem
2015-05-08
14:21
TEA update Closed-Leaf check-in: f4a8039bf0 user: dgp tags: bug-a57b6c3fd4
2015-05-01
17:17
[a57b6c3fd4] Prevent -eventmark related deadlock. check-in: 12e5e4c993 user: dgp tags: bug-a57b6c3fd4
2015-03-27
20:33
Use the new TCL_MINIMUM_VERSION macro in one additional place missed in the previous check-in. check-in: 593a90d9bc user: mistachkin tags: trunk
2015-03-26
17:00
Revise the compile-time version/feature checking for improved clarity and correctness. check-in: 94b0e5de65 user: mistachkin tags: trunk

Changes to configure.

1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
    # are compatible with.
    TEA_VERSION="3.9"

    echo "$as_me:$LINENO: checking for correct TEA configuration" >&5
echo $ECHO_N "checking for correct TEA configuration... $ECHO_C" >&6
    if test x"${PACKAGE_NAME}" = x ; then
	{ { echo "$as_me:$LINENO: error:
The PACKAGE_NAME variable must be defined by your TEA configure.in" >&5
echo "$as_me: error:
The PACKAGE_NAME variable must be defined by your TEA configure.in" >&2;}
   { (exit 1); exit 1; }; }
    fi
    if test x"3.9" = x ; then
	{ { echo "$as_me:$LINENO: error:
TEA version not specified." >&5
echo "$as_me: error:
TEA version not specified." >&2;}







|

|







1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
    # are compatible with.
    TEA_VERSION="3.9"

    echo "$as_me:$LINENO: checking for correct TEA configuration" >&5
echo $ECHO_N "checking for correct TEA configuration... $ECHO_C" >&6
    if test x"${PACKAGE_NAME}" = x ; then
	{ { echo "$as_me:$LINENO: error:
The PACKAGE_NAME variable must be defined by your TEA configure.ac" >&5
echo "$as_me: error:
The PACKAGE_NAME variable must be defined by your TEA configure.ac" >&2;}
   { (exit 1); exit 1; }; }
    fi
    if test x"3.9" = x ; then
	{ { echo "$as_me:$LINENO: error:
TEA version not specified." >&5
echo "$as_me: error:
TEA version not specified." >&2;}
8259
8260
8261
8262
8263
8264
8265
8266


8267
8268
8269
8270
8271
8272
8273
else
  AR="$ac_cv_prog_AR"
fi

    STLIB_LD='${AR} cr'
    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
    if test "x$SHLIB_VERSION" = x; then
  SHLIB_VERSION="1.0"


fi

    case $system in
	# TEA specific:
	windows)
	    # This is a 2-stage check to make sure we have the 64-bit SDK
	    # We have to know where the SDK is installed.







|
>
>







8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
else
  AR="$ac_cv_prog_AR"
fi

    STLIB_LD='${AR} cr'
    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
    if test "x$SHLIB_VERSION" = x; then
  SHLIB_VERSION=""
else
  SHLIB_VERSION=".$SHLIB_VERSION"
fi

    case $system in
	# TEA specific:
	windows)
	    # This is a 2-stage check to make sure we have the 64-bit SDK
	    # We have to know where the SDK is installed.
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
		SHLIB_SUFFIX=".so"
		if test $doRpath = yes; then

		    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi

		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
		LDFLAGS="-Wl,-export-dynamic"
		;;
	    esac
	    case "$arch" in
	    vax)
		CFLAGS_OPTIMIZE="-O1"
		;;







|







9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323
9324
		SHLIB_SUFFIX=".so"
		if test $doRpath = yes; then

		    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi

		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
		LDFLAGS="-Wl,-export-dynamic"
		;;
	    esac
	    case "$arch" in
	    vax)
		CFLAGS_OPTIMIZE="-O1"
		;;
11474
11475
11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489
11490
11491
11492
11493
11494
11495
11496
11497
11498
11499
11500
11501
11502
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512
11513
11514
11515
11516
	    if test x"${TK_BIN_DIR}" != x ; then
		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
	    fi
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
	    if test "$GCC" = "yes"; then
		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc"
	    fi
	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
	else
	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
	    if test "$GCC" = "yes"; then
		PKG_LIB_FILE=lib${PKG_LIB_FILE}
	    fi
	fi
	# Some packages build their own stubs libraries
	eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
	if test "$GCC" = "yes"; then
	    PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
	fi
	# These aren't needed on Windows (either MSVC or gcc)
	RANLIB=:
	RANLIB_STUB=:
    else
	RANLIB_STUB="${RANLIB}"
	if test "${SHARED_BUILD}" = "1" ; then
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
	    if test x"${TK_BIN_DIR}" != x ; then
		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
	    fi
	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
	    RANLIB=:
	else
	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
	fi
	# Some packages build their own stubs libraries
	eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
    fi

    # These are escaped so that only CFLAGS is picked up at configure time.
    # The other values will be substituted at make time.
    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
    if test "${SHARED_BUILD}" = "1" ; then
	CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"







|

|





|













|


|


|







11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489
11490
11491
11492
11493
11494
11495
11496
11497
11498
11499
11500
11501
11502
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512
11513
11514
11515
11516
11517
11518
	    if test x"${TK_BIN_DIR}" != x ; then
		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
	    fi
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
	    if test "$GCC" = "yes"; then
		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc"
	    fi
	    eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
	else
	    eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
	    if test "$GCC" = "yes"; then
		PKG_LIB_FILE=lib${PKG_LIB_FILE}
	    fi
	fi
	# Some packages build their own stubs libraries
	eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
	if test "$GCC" = "yes"; then
	    PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
	fi
	# These aren't needed on Windows (either MSVC or gcc)
	RANLIB=:
	RANLIB_STUB=:
    else
	RANLIB_STUB="${RANLIB}"
	if test "${SHARED_BUILD}" = "1" ; then
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
	    if test x"${TK_BIN_DIR}" != x ; then
		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
	    fi
	    eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
	    RANLIB=:
	else
	    eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
	fi
	# Some packages build their own stubs libraries
	eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
    fi

    # These are escaped so that only CFLAGS is picked up at configure time.
    # The other values will be substituted at make time.
    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
    if test "${SHARED_BUILD}" = "1" ; then
	CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"

Changes to generic/threadCmd.c.

263
264
265
266
267
268
269

270
271
272
273
274
275
276

/*
 * Definition of flags for ThreadSend.
 */

#define THREAD_SEND_WAIT 1<<1
#define THREAD_SEND_HEAD 1<<2


#ifdef BUILD_thread
# undef  TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*







>







263
264
265
266
267
268
269
270
271
272
273
274
275
276
277

/*
 * Definition of flags for ThreadSend.
 */

#define THREAD_SEND_WAIT 1<<1
#define THREAD_SEND_HEAD 1<<2
#define THREAD_SEND_CLBK 1<<3

#ifdef BUILD_thread
# undef  TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*
2743
2744
2745
2746
2747
2748
2749
2750
2751

2752
2753
2754
2755

2756
2757
2758
2759
2760
2761
2762
        Tcl_ThreadQueueEvent(thrId, (Tcl_Event*)eventPtr, TCL_QUEUE_TAIL);
    }
    Tcl_ThreadAlert(thrId);

    if ((flags & THREAD_SEND_WAIT) == 0) {
        /*
         * Might potentially spend some time here, until the
         * worker thread clean's up it's queue a little bit.
         */

        while (tsdPtr->maxEventsCount &&
               tsdPtr->eventsPending > tsdPtr->maxEventsCount) {
            Tcl_ConditionWait(&tsdPtr->doOneEvent, &threadMutex, NULL);
        }

        Tcl_MutexUnlock(&threadMutex);
        return TCL_OK;
    }

    /*
     * Block on the result indefinitely.
     */







|

>
|
|
|
|
>







2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
        Tcl_ThreadQueueEvent(thrId, (Tcl_Event*)eventPtr, TCL_QUEUE_TAIL);
    }
    Tcl_ThreadAlert(thrId);

    if ((flags & THREAD_SEND_WAIT) == 0) {
        /*
         * Might potentially spend some time here, until the
         * worker thread cleans up its queue a little bit.
         */
	if ((flags & THREAD_SEND_CLBK) == 0) {
            while (tsdPtr->maxEventsCount &&
                   tsdPtr->eventsPending > tsdPtr->maxEventsCount) {
                Tcl_ConditionWait(&tsdPtr->doOneEvent, &threadMutex, NULL);
            }
	}
        Tcl_MutexUnlock(&threadMutex);
        return TCL_OK;
    }

    /*
     * Block on the result indefinitely.
     */
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
    interp = (sendPtr && sendPtr->interp) ? sendPtr->interp : tsdPtr->interp;

    if (interp != NULL) {
        Tcl_Preserve((ClientData)interp);

        if (clbkPtr && clbkPtr->threadId == thrId) {
            Tcl_Release((ClientData)interp);
            /* Watch: this thread evaluates it's own callback. */
            interp = clbkPtr->interp;
            Tcl_Preserve((ClientData)interp);
        }

        Tcl_ResetResult(interp);

        if (sendPtr) {







|







3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
    interp = (sendPtr && sendPtr->interp) ? sendPtr->interp : tsdPtr->interp;

    if (interp != NULL) {
        Tcl_Preserve((ClientData)interp);

        if (clbkPtr && clbkPtr->threadId == thrId) {
            Tcl_Release((ClientData)interp);
            /* Watch: this thread evaluates its own callback. */
            interp = clbkPtr->interp;
            Tcl_Preserve((ClientData)interp);
        }

        Tcl_ResetResult(interp);

        if (sendPtr) {
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
         */

        if (code != TCL_OK) {
            ThreadErrorProc(interp);
        }

        ThreadSetResult(interp, code, &clbkPtr->result);
        ThreadSend(interp, clbkPtr->threadId, tmpPtr, NULL, 0);

    } else if (code != TCL_OK) {
        /*
         * Only pass errors onto the registered error handler
         * when we don't have a result target for this event.
         */
        ThreadErrorProc(interp);







|







3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
         */

        if (code != TCL_OK) {
            ThreadErrorProc(interp);
        }

        ThreadSetResult(interp, code, &clbkPtr->result);
        ThreadSend(interp, clbkPtr->threadId, tmpPtr, NULL, THREAD_SEND_CLBK);

    } else if (code != TCL_OK) {
        /*
         * Only pass errors onto the registered error handler
         * when we don't have a result target for this event.
         */
        ThreadErrorProc(interp);