summaryrefslogtreecommitdiffstats
path: root/win/tclWinChan.c
diff options
context:
space:
mode:
Diffstat (limited to 'win/tclWinChan.c')
-rw-r--r--win/tclWinChan.c118
1 files changed, 42 insertions, 76 deletions
diff --git a/win/tclWinChan.c b/win/tclWinChan.c
index fb7a83d..d6ea38c 100644
--- a/win/tclWinChan.c
+++ b/win/tclWinChan.c
@@ -9,7 +9,7 @@
* 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.38 2005/01/19 22:07:41 mdejong Exp $
+ * RCS: @(#) $Id: tclWinChan.c,v 1.39 2005/01/27 00:23:32 andreas_kupries Exp $
*/
#include "tclWinInt.h"
@@ -97,7 +97,9 @@ static Tcl_WideInt FileWideSeekProc _ANSI_ARGS_((ClientData instanceData,
static void FileSetupProc _ANSI_ARGS_((ClientData clientData,
int flags));
static void FileWatchProc _ANSI_ARGS_((ClientData instanceData,
- int mask));
+ int mask));
+static void FileThreadActionProc _ANSI_ARGS_ ((
+ ClientData instanceData, int action));
/*
* This structure describes the channel type structure for file based IO.
@@ -105,7 +107,7 @@ static void FileWatchProc _ANSI_ARGS_((ClientData instanceData,
static Tcl_ChannelType fileChannelType = {
"file", /* Type name. */
- TCL_CHANNEL_VERSION_3, /* v3 channel */
+ TCL_CHANNEL_VERSION_4, /* v4 channel */
FileCloseProc, /* Close proc. */
FileInputProc, /* Input proc. */
FileOutputProc, /* Output proc. */
@@ -119,6 +121,7 @@ static Tcl_ChannelType fileChannelType = {
NULL, /* flush proc. */
NULL, /* handler proc. */
FileWideSeekProc, /* Wide seek proc. */
+ FileThreadActionProc, /* Thread action proc. */
};
#if defined(HAVE_NO_SEH) && defined(TCL_MEM_DEBUG)
@@ -430,11 +433,11 @@ FileCloseProc(instanceData, interp)
if (infoPtr == fileInfoPtr) {
/*
* This channel exists on the thread local list. It should
- * have been removed by an earlier call to TclpCutFileChannel,
+ * have been removed by an earlier Threadaction call,
* but do that now since just deallocating fileInfoPtr would
* leave an deallocated pointer on the thread local list.
*/
- TclpCutFileChannel(fileInfoPtr->channel);
+ FileThreadActionProc(fileInfoPtr,TCL_CHANNEL_THREAD_REMOVE);
break;
}
}
@@ -1307,8 +1310,11 @@ TclWinOpenFileChannel(handle, channelName, permissions, appendMode)
}
infoPtr = (FileInfo *) ckalloc((unsigned) sizeof(FileInfo));
- infoPtr->nextPtr = tsdPtr->firstFilePtr;
- tsdPtr->firstFilePtr = infoPtr;
+ /* TIP #218. Removed the code inserting the new structure
+ * into the global list. This is now handled in the thread
+ * action callbacks, and only there.
+ */
+ infoPtr->nextPtr = NULL;
infoPtr->validMask = permissions;
infoPtr->watchMask = 0;
infoPtr->flags = appendMode;
@@ -1373,10 +1379,9 @@ TclWinFlushDirtyChannels ()
/*
*----------------------------------------------------------------------
*
- * TclpCutFileChannel --
+ * FileThreadActionProc --
*
- * Remove any thread local refs to this channel. See
- * See Tcl_CutChannel for more info.
+ * Insert or remove any thread local refs to this channel.
*
* Results:
* None.
@@ -1387,77 +1392,38 @@ TclWinFlushDirtyChannels ()
*----------------------------------------------------------------------
*/
-void
-TclpCutFileChannel(chan)
- Tcl_Channel chan; /* The channel being removed. Must
- * not be referenced in any
- * interpreter. */
+static void
+FileThreadActionProc (instanceData, action)
+ ClientData instanceData;
+ int action;
{
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;
+ FileInfo *infoPtr = (FileInfo *) instanceData;
- for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL;
- nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
- if ((*nextPtrPtr) == infoPtr) {
- (*nextPtrPtr) = infoPtr->nextPtr;
- removed = 1;
- break;
+ if (action == TCL_CHANNEL_THREAD_INSERT) {
+ infoPtr->nextPtr = tsdPtr->firstFilePtr;
+ tsdPtr->firstFilePtr = infoPtr;
+ } else {
+ FileInfo **nextPtrPtr;
+ int removed = 0;
+
+ 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) {
- Tcl_Panic("file info ptr not on thread channel list");
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclpSpliceFileChannel --
- *
- * Insert thread local ref for this channel.
- * See 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;
+ /*
+ * 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 (chanPtr->typePtr != &fileChannelType) {
- return;
+ if (!removed) {
+ Tcl_Panic("file info ptr not on thread channel list");
+ }
}
-
- infoPtr = (FileInfo *) chanPtr->instanceData;
-
- infoPtr->nextPtr = tsdPtr->firstFilePtr;
- tsdPtr->firstFilePtr = infoPtr;
}