1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
/*
* tclThreadTest.c --
*
* This file implements the testthread command. Eventually this
* should be tclThreadCmd.c
* Some of this code is based on work done by Richard Hipp on behalf of
* Conservation Through Innovation, Limited, with their permission.
*
* Copyright (c) 1998 by Sun Microsystems, Inc.
*
* 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.1.2.5 1998/12/12 01:37:03 lfb Exp $
*/
#include "tclInt.h"
#ifdef TCL_THREADS
/*
* Each thread has an single instance of the following structure. There
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
/*
* tclThreadTest.c --
*
* This file implements the testthread command. Eventually this
* should be tclThreadCmd.c
* Some of this code is based on work done by Richard Hipp on behalf of
* Conservation Through Innovation, Limited, with their permission.
*
* Copyright (c) 1998 by Sun Microsystems, Inc.
*
* 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.1.2.5.2.1 1999/03/09 02:37:18 stanton Exp $
*/
#include "tclInt.h"
#ifdef TCL_THREADS
/*
* Each thread has an single instance of the following structure. There
|
| ︙ | | | ︙ | |
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
|
return TCL_ERROR;
}
/*
* Wait for the thread to start because it is using something on our stack!
*/
TclpConditionWait(&ctrl.condWait, &threadMutex, NULL);
Tcl_MutexUnlock(&threadMutex);
TclFinalizeCondition(&ctrl.condWait);
Tcl_SetObjResult(interp, Tcl_NewIntObj((int)id));
return TCL_OK;
}
/*
|
|
|
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
|
return TCL_ERROR;
}
/*
* Wait for the thread to start because it is using something on our stack!
*/
Tcl_ConditionWait(&ctrl.condWait, &threadMutex, NULL);
Tcl_MutexUnlock(&threadMutex);
TclFinalizeCondition(&ctrl.condWait);
Tcl_SetObjResult(interp, Tcl_NewIntObj((int)id));
return TCL_OK;
}
/*
|
| ︙ | | | ︙ | |
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
|
ListUpdateInner(tsdPtr);
Tcl_CreateThreadExitHandler(ThreadExitProc, NULL);
/*
* Notify the parent we are alive.
*/
TclpConditionNotify(&ctrlPtr->condWait);
Tcl_MutexUnlock(&threadMutex);
/*
* Run the script.
*/
Tcl_Preserve((ClientData) tsdPtr->interp);
|
|
|
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
|
ListUpdateInner(tsdPtr);
Tcl_CreateThreadExitHandler(ThreadExitProc, NULL);
/*
* Notify the parent we are alive.
*/
Tcl_ConditionNotify(&ctrlPtr->condWait);
Tcl_MutexUnlock(&threadMutex);
/*
* Run the script.
*/
Tcl_Preserve((ClientData) tsdPtr->interp);
|
| ︙ | | | ︙ | |
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
|
/*
* Block on the results and then get them.
*/
Tcl_ResetResult(interp);
Tcl_MutexLock(&threadMutex);
if (resultPtr->result == NULL) {
TclpConditionWait(&resultPtr->done, &threadMutex, NULL);
}
Tcl_MutexUnlock(&threadMutex);
if (resultPtr->code != TCL_OK) {
if (resultPtr->errorCode) {
Tcl_SetErrorCode(interp, resultPtr->errorCode, NULL);
ckfree(resultPtr->errorCode);
}
|
|
|
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
|
/*
* Block on the results and then get them.
*/
Tcl_ResetResult(interp);
Tcl_MutexLock(&threadMutex);
if (resultPtr->result == NULL) {
Tcl_ConditionWait(&resultPtr->done, &threadMutex, NULL);
}
Tcl_MutexUnlock(&threadMutex);
if (resultPtr->code != TCL_OK) {
if (resultPtr->errorCode) {
Tcl_SetErrorCode(interp, resultPtr->errorCode, NULL);
ckfree(resultPtr->errorCode);
}
|
| ︙ | | | ︙ | |
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
|
resultPtr->errorCode = ckalloc(strlen(errorCode) + 1);
strcpy(resultPtr->errorCode, errorCode);
}
if (errorInfo != NULL) {
resultPtr->errorInfo = ckalloc(strlen(errorInfo) + 1);
strcpy(resultPtr->errorInfo, errorInfo);
}
TclpConditionNotify(&resultPtr->done);
Tcl_MutexUnlock(&threadMutex);
}
if (interp != NULL) {
Tcl_Release((ClientData) interp);
}
return 1;
}
|
|
|
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
|
resultPtr->errorCode = ckalloc(strlen(errorCode) + 1);
strcpy(resultPtr->errorCode, errorCode);
}
if (errorInfo != NULL) {
resultPtr->errorInfo = ckalloc(strlen(errorInfo) + 1);
strcpy(resultPtr->errorInfo, errorInfo);
}
Tcl_ConditionNotify(&resultPtr->done);
Tcl_MutexUnlock(&threadMutex);
}
if (interp != NULL) {
Tcl_Release((ClientData) interp);
}
return 1;
}
|
| ︙ | | | ︙ | |
874
875
876
877
878
879
880
881
882
883
884
885
886
887
|
ckfree((char *)resultPtr);
} else if (resultPtr->dstThreadId == self) {
/*
* Dang. The target is going away. Unblock the caller.
*/
resultPtr->result = "target thread died";
resultPtr->code = TCL_ERROR;
TclpConditionNotify(&resultPtr->done);
}
}
Tcl_MutexUnlock(&threadMutex);
}
#endif /* TCL_THREADS */
|
|
|
874
875
876
877
878
879
880
881
882
883
884
885
886
887
|
ckfree((char *)resultPtr);
} else if (resultPtr->dstThreadId == self) {
/*
* Dang. The target is going away. Unblock the caller.
*/
resultPtr->result = "target thread died";
resultPtr->code = TCL_ERROR;
Tcl_ConditionNotify(&resultPtr->done);
}
}
Tcl_MutexUnlock(&threadMutex);
}
#endif /* TCL_THREADS */
|