diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | generic/tclIO.c | 6 | ||||
-rw-r--r-- | generic/tclInt.h | 4 | ||||
-rw-r--r-- | unix/tclUnixChan.c | 118 | ||||
-rw-r--r-- | win/tclWinChan.c | 103 |
5 files changed, 222 insertions, 26 deletions
@@ -1,5 +1,22 @@ 2003-01-25 Mo DeJong <mdejong@users.sourceforge.net> + * generic/tclIO.c (Tcl_CutChannel, Tcl_SpliceChannel): + Invoke TclpCutFileChannel and TclpSpliceFileChannel. + * generic/tclInt.h: Declare TclpCutFileChannel + and TclpSpliceFileChannel. + * unix/tclUnixChan.c (FileCloseProc, TclpOpenFileChannel, + Tcl_MakeFileChannel, TclpCutFileChannel, + TclpSpliceFileChannel): Implement thread load data + cut and splice for file channels. This avoids + an invalid memory ref when compiled with -DDEPRECATED. + * win/tclWinChan.c (FileCloseProc, TclpCutFileChannel, + TclpSpliceFileChannel): Implement thread load data + cut and splice for file channels. This avoids + an invalid memory ref that was showing up in the + thread extension. + +2003-01-25 Mo DeJong <mdejong@users.sourceforge.net> + * win/tclWin32Dll.c (TclpCheckStackSpace, squelch_warnings): * win/tclWinChan.c (Tcl_MakeFileChannel, squelch_warnings): * win/tclWinFCmd.c (DoRenameFile, DoCopyFile, squelch_warnings): diff --git a/generic/tclIO.c b/generic/tclIO.c index e1298d5..5e2338d 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclIO.c,v 1.58 2003/01/24 11:59:29 vincentdarley Exp $ + * RCS: @(#) $Id: tclIO.c,v 1.59 2003/01/26 05:59:37 mdejong Exp $ */ #include "tclInt.h" @@ -2409,6 +2409,8 @@ Tcl_CutChannel(chan) } statePtr->nextCSPtr = (ChannelState *) NULL; + + TclpCutFileChannel(chan); } /* @@ -2460,6 +2462,8 @@ Tcl_SpliceChannel(chan) */ statePtr->managingThread = Tcl_GetCurrentThread (); + + TclpSpliceFileChannel(chan); } /* diff --git a/generic/tclInt.h b/generic/tclInt.h index ff49a21..62a2cc3 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclInt.h,v 1.115 2003/01/17 14:19:49 vincentdarley Exp $ + * RCS: @(#) $Id: tclInt.h,v 1.116 2003/01/26 05:59:37 mdejong Exp $ */ #ifndef _TCLINT @@ -1777,6 +1777,8 @@ EXTERN int TclpObjStat _ANSI_ARGS_((Tcl_Obj *pathPtr, Tcl_StatBuf *buf)); EXTERN Tcl_Channel TclpOpenFileChannel _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions)); +EXTERN void TclpCutFileChannel _ANSI_ARGS_((Tcl_Channel chan)); +EXTERN void TclpSpliceFileChannel _ANSI_ARGS_((Tcl_Channel chan)); EXTERN void TclpPanic _ANSI_ARGS_(TCL_VARARGS(CONST char *, format)); EXTERN char * TclpReadlink _ANSI_ARGS_((CONST char *fileName, diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index 4838c55..79dad86 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -10,11 +10,12 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclUnixChan.c,v 1.40 2002/11/07 02:13:37 mdejong Exp $ + * RCS: @(#) $Id: tclUnixChan.c,v 1.41 2003/01/26 05:59:37 mdejong Exp $ */ #include "tclInt.h" /* Internal definitions for Tcl. */ #include "tclPort.h" /* Portability features for Tcl. */ +#include "tclIO.h" /* To get Channel type declaration. */ /* * sys/ioctl.h has already been included by tclPort.h. Including termios.h @@ -555,15 +556,6 @@ FileCloseProc(instanceData, interp) errorCode = errno; } } -#ifdef DEPRECATED - for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL; - nextPtrPtr = &((*nextPtrPtr)->nextPtr)) { - if ((*nextPtrPtr) == fsPtr) { - (*nextPtrPtr) = fsPtr->nextPtr; - break; - } - } -#endif /* DEPRECATED */ ckfree((char *) fsPtr); return errorCode; } @@ -1834,8 +1826,10 @@ TclpOpenFileChannel(interp, pathPtr, mode, permissions) } #ifdef DEPRECATED - fsPtr->nextPtr = tsdPtr->firstFilePtr; - tsdPtr->firstFilePtr = fsPtr; + if (channelTypePtr == &fileChannelType) { + fsPtr->nextPtr = tsdPtr->firstFilePtr; + tsdPtr->firstFilePtr = fsPtr; + } #endif /* DEPRECATED */ fsPtr->validMask = channelPermissions | TCL_EXCEPTION; fsPtr->fd = fd; @@ -1933,8 +1927,10 @@ Tcl_MakeFileChannel(handle, mode) } #ifdef DEPRECATED - fsPtr->nextPtr = tsdPtr->firstFilePtr; - tsdPtr->firstFilePtr = fsPtr; + if (channelTypePtr == &fileChannelType) { + fsPtr->nextPtr = tsdPtr->firstFilePtr; + tsdPtr->firstFilePtr = fsPtr; + } #endif /* DEPRECATED */ fsPtr->fd = fd; fsPtr->validMask = mode | TCL_EXCEPTION; @@ -3243,3 +3239,97 @@ TclUnixWaitForFile(fd, mask, timeout) } return result; } + +/* + *---------------------------------------------------------------------- + * + * TclpCutFileChannel -- + * + * Remove any thread local refs to this channel. See + * Tcl_CutChannel for more info. + * + * Results: + * None. + * + * Side effects: + * Changes thread local list of valid channels. + * + *---------------------------------------------------------------------- + */ + +void +TclpCutFileChannel(chan) + Tcl_Channel chan; /* The channel being removed. Must + * not be referenced in any + * interpreter. */ +{ +#ifdef DEPRECATED + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel *chanPtr = (Channel *) chan; + FileState *fsPtr; + FileState **nextPtrPtr; + int removed = 0; + + if (chanPtr->typePtr != &fileChannelType) + return; + + fsPtr = (FileState *) chanPtr->instanceData; + + for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL; + nextPtrPtr = &((*nextPtrPtr)->nextPtr)) { + if ((*nextPtrPtr) == fsPtr) { + (*nextPtrPtr) = fsPtr->nextPtr; + removed = 1; + break; + } + } + + /* + * This could happen if the channel was created in one thread + * and then moved to another without updating the thread + * local data in each thread. + */ + + if (!removed) + panic("file info ptr not on thread channel list"); + +#endif /* DEPRECATED */ +} + +/* + *---------------------------------------------------------------------- + * + * TclpSpliceFileChannel -- + * + * Insert thread local ref for this channel. + * Tcl_SpliceChannel for more info. + * + * Results: + * None. + * + * Side effects: + * Changes thread local list of valid channels. + * + *---------------------------------------------------------------------- + */ + +void +TclpSpliceFileChannel(chan) + Tcl_Channel chan; /* The channel being removed. Must + * not be referenced in any + * interpreter. */ +{ +#ifdef DEPRECATED + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel *chanPtr = (Channel *) chan; + FileState *fsPtr; + + if (chanPtr->typePtr != &fileChannelType) + return; + + fsPtr = (FileState *) chanPtr->instanceData; + + fsPtr->nextPtr = tsdPtr->firstFilePtr; + tsdPtr->firstFilePtr = fsPtr; +#endif /* DEPRECATED */ +} diff --git a/win/tclWinChan.c b/win/tclWinChan.c index c377245..c6640f1 100644 --- a/win/tclWinChan.c +++ b/win/tclWinChan.c @@ -9,10 +9,11 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinChan.c,v 1.29 2003/01/25 14:11:32 mdejong Exp $ + * RCS: @(#) $Id: tclWinChan.c,v 1.30 2003/01/26 05:59:38 mdejong Exp $ */ #include "tclWinInt.h" +#include "tclIO.h" /* * State flags used in the info structures below. @@ -389,9 +390,7 @@ FileCloseProc(instanceData, interp) Tcl_Interp *interp; /* Not used. */ { FileInfo *fileInfoPtr = (FileInfo *) instanceData; - FileInfo **nextPtrPtr; int errorCode = 0; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); /* * Remove the file from the watch list. @@ -414,13 +413,7 @@ FileCloseProc(instanceData, interp) errorCode = errno; } } - for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL; - nextPtrPtr = &((*nextPtrPtr)->nextPtr)) { - if ((*nextPtrPtr) == fileInfoPtr) { - (*nextPtrPtr) = fileInfoPtr->nextPtr; - break; - } - } + ckfree((char *)fileInfoPtr); return errorCode; } @@ -1345,3 +1338,93 @@ TclWinFlushDirtyChannels () } } } + +/* + *---------------------------------------------------------------------- + * + * TclpCutFileChannel -- + * + * Remove any thread local refs to this channel. See + * Tcl_CutChannel for more info. + * + * Results: + * None. + * + * Side effects: + * Changes thread local list of valid channels. + * + *---------------------------------------------------------------------- + */ + +void +TclpCutFileChannel(chan) + Tcl_Channel chan; /* The channel being removed. Must + * not be referenced in any + * interpreter. */ +{ + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel *chanPtr = (Channel *) chan; + FileInfo *infoPtr; + FileInfo **nextPtrPtr; + int removed = 0; + + if (chanPtr->typePtr != &fileChannelType) + return; + + infoPtr = (FileInfo *) chanPtr->instanceData; + + for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL; + nextPtrPtr = &((*nextPtrPtr)->nextPtr)) { + if ((*nextPtrPtr) == infoPtr) { + (*nextPtrPtr) = infoPtr->nextPtr; + removed = 1; + break; + } + } + + /* + * This could happen if the channel was created in one thread + * and then moved to another without updating the thread + * local data in each thread. + */ + + if (!removed) + panic("file info ptr not on thread channel list"); + +} + +/* + *---------------------------------------------------------------------- + * + * TclpSpliceFileChannel -- + * + * Insert thread local ref for this channel. + * Tcl_SpliceChannel for more info. + * + * Results: + * None. + * + * Side effects: + * Changes thread local list of valid channels. + * + *---------------------------------------------------------------------- + */ + +void +TclpSpliceFileChannel(chan) + Tcl_Channel chan; /* The channel being removed. Must + * not be referenced in any + * interpreter. */ +{ + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel *chanPtr = (Channel *) chan; + FileInfo *infoPtr; + + if (chanPtr->typePtr != &fileChannelType) + return; + + infoPtr = (FileInfo *) chanPtr->instanceData; + + infoPtr->nextPtr = tsdPtr->firstFilePtr; + tsdPtr->firstFilePtr = infoPtr; +} |