summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2012-06-25 14:43:36 (GMT)
committerdgp <dgp@users.sourceforge.net>2012-06-25 14:43:36 (GMT)
commitc56279aca031cd571054139f95be82bb90c7dbfa (patch)
treec871ead30ab5ffe77b435d00aead35267d1695d9 /generic
parent01eab1b3890706a987bfd038c2193a060660d823 (diff)
parent527a4f67fa396747502ba37514a882725f401110 (diff)
downloadtcl-c56279aca031cd571054139f95be82bb90c7dbfa.zip
tcl-c56279aca031cd571054139f95be82bb90c7dbfa.tar.gz
tcl-c56279aca031cd571054139f95be82bb90c7dbfa.tar.bz2
Simplify bug fix so that active claims on the FilesystemRecord list of a threadbug_3024359
prevent any overwriting of that per-thread cache. This keeps active traversals of the list valid. The possible downside is that this may result in some delay in noticing new epochs and result in somewhat greater likelihood we will cache things in a "path" value that are out of date. Since the system has to deal with out of date cached data anyway, this should have no correctness affects, measured against the status quo. In multi-threaded operation the possibility of caching and/or retrieving outdated information can never be eliminated. Checkin also includes merge of 8.5.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclCmdAH.c18
-rw-r--r--generic/tclIOUtil.c69
-rw-r--r--generic/tclPathObj.c3
3 files changed, 29 insertions, 61 deletions
diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c
index e1ec927..8e32389 100644
--- a/generic/tclCmdAH.c
+++ b/generic/tclCmdAH.c
@@ -505,7 +505,7 @@ Tcl_EncodingObjCmd(
break;
}
case ENC_DIRS:
- return EncodingDirsObjCmd(dummy, interp, objc-1, objv+1);
+ return EncodingDirsObjCmd(dummy, interp, objc, objv);
case ENC_NAMES:
if (objc > 2) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
@@ -552,20 +552,24 @@ EncodingDirsObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "?dirList?");
+ Tcl_Obj *dirListObj;
+
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?dirList?");
return TCL_ERROR;
}
- if (objc == 1) {
+ if (objc == 2) {
Tcl_SetObjResult(interp, Tcl_GetEncodingSearchPath());
return TCL_OK;
}
- if (Tcl_SetEncodingSearchPath(objv[1]) == TCL_ERROR) {
+
+ dirListObj = objv[2];
+ if (Tcl_SetEncodingSearchPath(dirListObj) == TCL_ERROR) {
Tcl_AppendResult(interp, "expected directory list but got \"",
- TclGetString(objv[1]), "\"", NULL);
+ TclGetString(dirListObj), "\"", NULL);
return TCL_ERROR;
}
- Tcl_SetObjResult(interp, objv[1]);
+ Tcl_SetObjResult(interp, dirListObj);
return TCL_OK;
}
diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c
index 9d81d18..dccbeb5 100644
--- a/generic/tclIOUtil.c
+++ b/generic/tclIOUtil.c
@@ -586,31 +586,19 @@ static void
FsRecacheFilesystemList(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
- FilesystemRecord *fsRecPtr, *tmpFsRecPtr = NULL, *toFree = NULL, *chain = NULL;
+ FilesystemRecord *fsRecPtr, *tmpFsRecPtr = NULL, *toFree = NULL, *list;
/*
* Trash the current cache.
*/
fsRecPtr = tsdPtr->filesystemList;
- if (tsdPtr->claims <= 0) {
- while (fsRecPtr != NULL) {
- tmpFsRecPtr = fsRecPtr->nextPtr;
- fsRecPtr->fsPtr = NULL;
- fsRecPtr->nextPtr = toFree;
- toFree = fsRecPtr;
- fsRecPtr = tmpFsRecPtr;
- }
- } else {
- chain = fsRecPtr;
- while (fsRecPtr->nextPtr != NULL) {
- fsRecPtr->prevPtr = fsRecPtr->nextPtr;
- fsRecPtr->nextPtr = NULL;
- fsRecPtr = fsRecPtr->prevPtr;
- }
- fsRecPtr->prevPtr = fsRecPtr;
+ while (fsRecPtr != NULL) {
+ tmpFsRecPtr = fsRecPtr->nextPtr;
+ fsRecPtr->nextPtr = toFree;
+ toFree = fsRecPtr;
+ fsRecPtr = tmpFsRecPtr;
}
- tsdPtr->filesystemList = NULL;
/*
* Locate tail of the global filesystem list.
@@ -627,24 +615,26 @@ FsRecacheFilesystemList(void)
* Refill the cache honouring the order.
*/
+ list = NULL;
fsRecPtr = tmpFsRecPtr;
while (fsRecPtr != NULL) {
tmpFsRecPtr = (FilesystemRecord *) ckalloc(sizeof(FilesystemRecord));
*tmpFsRecPtr = *fsRecPtr;
- tmpFsRecPtr->nextPtr = tsdPtr->filesystemList;
- tmpFsRecPtr->prevPtr = chain;
- chain = NULL;
- tsdPtr->filesystemList = tmpFsRecPtr;
+ tmpFsRecPtr->nextPtr = list;
+ tmpFsRecPtr->prevPtr = NULL;
+ list = tmpFsRecPtr;
fsRecPtr = fsRecPtr->prevPtr;
}
+ tsdPtr->filesystemList = list;
+ tsdPtr->filesystemEpoch = theFilesystemEpoch;
+ Tcl_MutexUnlock(&filesystemMutex);
while (toFree) {
FilesystemRecord *next = toFree->nextPtr;
+ toFree->fsPtr = NULL;
ckfree((char *)toFree);
toFree = next;
}
- tsdPtr->filesystemEpoch = theFilesystemEpoch;
- Tcl_MutexUnlock(&filesystemMutex);
/*
* Make sure the above gets released on thread exit.
@@ -660,8 +650,8 @@ static FilesystemRecord *
FsGetFirstFilesystem(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
- if (tsdPtr->filesystemList == NULL
- || (tsdPtr->filesystemEpoch != theFilesystemEpoch)) {
+ if (tsdPtr->filesystemList == NULL || ((tsdPtr->claims == 0)
+ && (tsdPtr->filesystemEpoch != theFilesystemEpoch))) {
FsRecacheFilesystemList();
}
return tsdPtr->filesystemList;
@@ -683,7 +673,6 @@ static void
Claim()
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
-
tsdPtr->claims++;
}
@@ -691,31 +680,7 @@ static void
Disclaim()
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
- FilesystemRecord *fsRecPtr, *toRelease, *lastCurrent;
-
- if (--tsdPtr->claims > 0) {
- return;
- }
- fsRecPtr = tsdPtr->filesystemList;
-
- /*
- * Release all out of date FilesystemRecords.
- * First skip the current list.
- */
- while (fsRecPtr->nextPtr != NULL) {
- fsRecPtr = fsRecPtr->nextPtr;
- }
-
- /* Then release everything that comes after. */
- lastCurrent = fsRecPtr;
- toRelease = lastCurrent->prevPtr;
- lastCurrent->prevPtr = NULL;
- while (toRelease != NULL) {
- fsRecPtr = (toRelease == toRelease->prevPtr) ? NULL
- : toRelease->prevPtr;
- ckfree((char *)toRelease);
- toRelease = fsRecPtr;
- }
+ tsdPtr->claims--;
}
/*
diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c
index 66cc617..4e1172a 100644
--- a/generic/tclPathObj.c
+++ b/generic/tclPathObj.c
@@ -563,8 +563,7 @@ TclPathPart(
if (pathPtr->typePtr == &tclFsPathType) {
FsPath *fsPathPtr = PATHOBJ(pathPtr);
- if (/*TclFSEpochOk(fsPathPtr->filesystemEpoch)
- && */(PATHFLAGS(pathPtr) != 0)) {
+ if (PATHFLAGS(pathPtr) != 0) {
switch (portion) {
case TCL_PATH_DIRNAME: {
/*