| ︙ | | | ︙ | |
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
*
* Copyright (c) 1998 by Sun Microsystems, Inc.
* Copyright (c) 2006-2008 by Joe Mistachkin. All rights reserved.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclThreadTest.c,v 1.30 2009/01/09 11:21:46 dkf Exp $
*/
#include "tclInt.h"
extern int Tcltest_Init(Tcl_Interp *interp);
#ifdef TCL_THREADS
|
|
|
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
*
* Copyright (c) 1998 by Sun Microsystems, Inc.
* Copyright (c) 2006-2008 by Joe Mistachkin. All rights reserved.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclThreadTest.c,v 1.31 2009/02/10 23:09:05 nijtmans Exp $
*/
#include "tclInt.h"
extern int Tcltest_Init(Tcl_Interp *interp);
#ifdef TCL_THREADS
|
| ︙ | | | ︙ | |
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
EXTERN int Tcl_ThreadObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
EXTERN int TclCreateThread(Tcl_Interp *interp, const char *script,
int joinable);
EXTERN int TclThreadList(Tcl_Interp *interp);
EXTERN int TclThreadSend(Tcl_Interp *interp, Tcl_ThreadId id,
char *script, int wait);
EXTERN int TclThreadCancel(Tcl_Interp *interp, Tcl_ThreadId id,
char *result, int flags);
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
Tcl_ThreadCreateType NewTestThread(ClientData clientData);
static void ListRemove(ThreadSpecificData *tsdPtr);
static void ListUpdateInner(ThreadSpecificData *tsdPtr);
|
|
|
|
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
EXTERN int Tcl_ThreadObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
EXTERN int TclCreateThread(Tcl_Interp *interp, const char *script,
int joinable);
EXTERN int TclThreadList(Tcl_Interp *interp);
EXTERN int TclThreadSend(Tcl_Interp *interp, Tcl_ThreadId id,
const char *script, int wait);
EXTERN int TclThreadCancel(Tcl_Interp *interp, Tcl_ThreadId id,
const char *result, int flags);
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
Tcl_ThreadCreateType NewTestThread(ClientData clientData);
static void ListRemove(ThreadSpecificData *tsdPtr);
static void ListUpdateInner(ThreadSpecificData *tsdPtr);
|
| ︙ | | | ︙ | |
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
|
Tcl_CreateThreadExitHandler(ThreadExitProc, NULL);
Tcl_MutexUnlock(&threadMutex);
}
switch ((enum options)option) {
case THREAD_CANCEL: {
long id;
char *result;
int flags, arg;
if ((objc < 3) || (objc > 5)) {
Tcl_WrongNumArgs(interp, 2, objv, "?-unwind? id ?result?");
return TCL_ERROR;
}
flags = 0;
|
|
|
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
|
Tcl_CreateThreadExitHandler(ThreadExitProc, NULL);
Tcl_MutexUnlock(&threadMutex);
}
switch ((enum options)option) {
case THREAD_CANCEL: {
long id;
const char *result;
int flags, arg;
if ((objc < 3) || (objc > 5)) {
Tcl_WrongNumArgs(interp, 2, objv, "?-unwind? id ?result?");
return TCL_ERROR;
}
flags = 0;
|
| ︙ | | | ︙ | |
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
|
if (objc > 2) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
return TCL_ERROR;
}
return TclThreadList(interp);
case THREAD_SEND: {
long id;
char *script;
int wait, arg;
if ((objc != 4) && (objc != 5)) {
Tcl_WrongNumArgs(interp, 2, objv, "?-async? id script");
return TCL_ERROR;
}
if (objc == 5) {
|
|
|
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
|
if (objc > 2) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
return TCL_ERROR;
}
return TclThreadList(interp);
case THREAD_SEND: {
long id;
const char *script;
int wait, arg;
if ((objc != 4) && (objc != 5)) {
Tcl_WrongNumArgs(interp, 2, objv, "?-async? id script");
return TCL_ERROR;
}
if (objc == 5) {
|
| ︙ | | | ︙ | |
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
|
return TCL_OK;
}
case THREAD_ERRORPROC: {
/*
* Arrange for this proc to handle thread death errors.
*/
char *proc;
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "proc");
return TCL_ERROR;
}
Tcl_MutexLock(&threadMutex);
errorThreadId = Tcl_GetCurrentThread();
|
|
|
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
|
return TCL_OK;
}
case THREAD_ERRORPROC: {
/*
* Arrange for this proc to handle thread death errors.
*/
const char *proc;
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "proc");
return TCL_ERROR;
}
Tcl_MutexLock(&threadMutex);
errorThreadId = Tcl_GetCurrentThread();
|
| ︙ | | | ︙ | |
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
|
*------------------------------------------------------------------------
*/
int
TclThreadSend(
Tcl_Interp *interp, /* The current interpreter. */
Tcl_ThreadId id, /* Thread Id of other interpreter. */
char *script, /* The script to evaluate. */
int wait) /* If 1, we block for the result. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
ThreadEvent *threadEventPtr;
ThreadEventResult *resultPtr;
int found, code;
Tcl_ThreadId threadId = (Tcl_ThreadId) id;
|
|
|
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
|
*------------------------------------------------------------------------
*/
int
TclThreadSend(
Tcl_Interp *interp, /* The current interpreter. */
Tcl_ThreadId id, /* Thread Id of other interpreter. */
const char *script, /* The script to evaluate. */
int wait) /* If 1, we block for the result. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
ThreadEvent *threadEventPtr;
ThreadEventResult *resultPtr;
int found, code;
Tcl_ThreadId threadId = (Tcl_ThreadId) id;
|
| ︙ | | | ︙ | |
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
|
ckfree(resultPtr->errorCode);
}
if (resultPtr->errorInfo) {
Tcl_AddErrorInfo(interp, resultPtr->errorInfo);
ckfree(resultPtr->errorInfo);
}
}
Tcl_SetResult(interp, resultPtr->result, TCL_VOLATILE);
ckfree(resultPtr->result);
Tcl_ConditionFinalize(&resultPtr->done);
code = resultPtr->code;
ckfree((char *) resultPtr);
return code;
}
|
|
<
|
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
|
ckfree(resultPtr->errorCode);
}
if (resultPtr->errorInfo) {
Tcl_AddErrorInfo(interp, resultPtr->errorInfo);
ckfree(resultPtr->errorInfo);
}
}
Tcl_SetResult(interp, resultPtr->result, TCL_DYNAMIC);
Tcl_ConditionFinalize(&resultPtr->done);
code = resultPtr->code;
ckfree((char *) resultPtr);
return code;
}
|
| ︙ | | | ︙ | |
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
|
*------------------------------------------------------------------------
*/
int
TclThreadCancel(
Tcl_Interp *interp, /* The current interpreter. */
Tcl_ThreadId id, /* Thread Id of other interpreter. */
char *result, /* The result or NULL for default. */
int flags) /* Flags for Tcl_CancelEval. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
int found;
Tcl_ThreadId threadId = (Tcl_ThreadId) id;
/*
|
|
|
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
|
*------------------------------------------------------------------------
*/
int
TclThreadCancel(
Tcl_Interp *interp, /* The current interpreter. */
Tcl_ThreadId id, /* Thread Id of other interpreter. */
const char *result, /* The result or NULL for default. */
int flags) /* Flags for Tcl_CancelEval. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
int found;
Tcl_ThreadId threadId = (Tcl_ThreadId) id;
/*
|
| ︙ | | | ︙ | |