summaryrefslogtreecommitdiffstats
path: root/generic/tclIOUtil.c
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/tclIOUtil.c
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/tclIOUtil.c')
-rw-r--r--generic/tclIOUtil.c69
1 files changed, 17 insertions, 52 deletions
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--;
}
/*