diff options
author | andreas_kupries <akupries@shaw.ca> | 2005-01-27 00:22:53 (GMT) |
---|---|---|
committer | andreas_kupries <akupries@shaw.ca> | 2005-01-27 00:22:53 (GMT) |
commit | 98dadc4e726ce2e9342141de853d74f6d614cc7b (patch) | |
tree | c0e294ceaa42e69c4fe42ce673e1336cf236d856 /unix/tclUnixChan.c | |
parent | 3c6ddb9aced9de4312cc2a982bf5715af646eddb (diff) | |
download | tcl-98dadc4e726ce2e9342141de853d74f6d614cc7b.zip tcl-98dadc4e726ce2e9342141de853d74f6d614cc7b.tar.gz tcl-98dadc4e726ce2e9342141de853d74f6d614cc7b.tar.bz2 |
TIP#218 IMPLEMENTATION
* generic/tclDecls.h: Regenerated from tcl.decls.
* generic/tclStubInit.c:
* doc/CrtChannel.3: Documentation of extended API,
* generic/tcl.decls: extended testsuite, and
* generic/tcl.h: implementation. Removal of old
* generic/tclIO.c: driver-specific TclpCut/Splice
* generic/tclInt.h: functions. Replaced with generic
* tests/io.test: thread-action calls through the
* unix/tclUnixChan.c: new hooks. Update of all builtin
* unix/tclUnixPipe.c: channel drivers to version 4.
* unix/tclUnixSock.c: Windows drivers extended to
* win/tclWinChan.c: manage thread state in a thread
* win/tclWinConsole.c: action handler.
* win/tclWinPipe.c:
* win/tclWinSerial.c:
* win/tclWinSock.c:
Diffstat (limited to 'unix/tclUnixChan.c')
-rw-r--r-- | unix/tclUnixChan.c | 98 |
1 files changed, 62 insertions, 36 deletions
diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index 5b9fa0a..6d3bd12 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.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: tclUnixChan.c,v 1.53 2004/11/17 02:51:32 hobbs Exp $ + * RCS: @(#) $Id: tclUnixChan.c,v 1.54 2005/01/27 00:23:31 andreas_kupries Exp $ */ #include "tclInt.h" /* Internal definitions for Tcl. */ @@ -232,6 +232,10 @@ static int FileOutputProc _ANSI_ARGS_(( int toWrite, int *errorCode)); static int FileSeekProc _ANSI_ARGS_((ClientData instanceData, long offset, int mode, int *errorCode)); +#ifdef DEPRECATED +static void FileThreadActionProc _ANSI_ARGS_ (( + ClientData instanceData, int action)); +#endif static Tcl_WideInt FileWideSeekProc _ANSI_ARGS_((ClientData instanceData, Tcl_WideInt offset, int mode, int *errorCode)); static void FileWatchProc _ANSI_ARGS_((ClientData instanceData, @@ -291,7 +295,7 @@ static Tcl_Channel MakeTcpClientChannelMode _ANSI_ARGS_( 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. */ @@ -305,6 +309,11 @@ static Tcl_ChannelType fileChannelType = { NULL, /* flush proc. */ NULL, /* handler proc. */ FileWideSeekProc, /* wide seek proc. */ +#ifdef DEPRECATED + FileThreadActionProc, /* thread actions */ +#else + NULL, +#endif }; #ifdef SUPPORTS_TTY @@ -315,7 +324,7 @@ static Tcl_ChannelType fileChannelType = { static Tcl_ChannelType ttyChannelType = { "tty", /* Type name. */ - TCL_CHANNEL_VERSION_2, /* v2 channel */ + TCL_CHANNEL_VERSION_4, /* v4 channel */ TtyCloseProc, /* Close proc. */ FileInputProc, /* Input proc. */ #if BAD_TIP35_FLUSH @@ -332,6 +341,8 @@ static Tcl_ChannelType ttyChannelType = { FileBlockModeProc, /* Set blocking or non-blocking mode.*/ NULL, /* flush proc. */ NULL, /* handler proc. */ + NULL, /* wide seek proc. */ + NULL, /* thread action proc. */ }; #endif /* SUPPORTS_TTY */ @@ -342,7 +353,7 @@ static Tcl_ChannelType ttyChannelType = { static Tcl_ChannelType tcpChannelType = { "tcp", /* Type name. */ - TCL_CHANNEL_VERSION_2, /* v2 channel */ + TCL_CHANNEL_VERSION_4, /* v4 channel */ TcpCloseProc, /* Close proc. */ TcpInputProc, /* Input proc. */ TcpOutputProc, /* Output proc. */ @@ -355,6 +366,8 @@ static Tcl_ChannelType tcpChannelType = { TcpBlockModeProc, /* Set blocking or non-blocking mode.*/ NULL, /* flush proc. */ NULL, /* handler proc. */ + NULL, /* wide seek proc. */ + NULL, /* thread action proc. */ }; @@ -1821,6 +1834,15 @@ TclpOpenFileChannel(interp, pathPtr, mode, permissions) fsPtr = (FileState *) ckalloc((unsigned) sizeof(FileState)); } +#ifdef DEPRECATED + if (channelTypePtr == &fileChannelType) { + /* 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. + */ + fsPtr->nextPtr = NULL; + } +#endif /* DEPRECATED */ fsPtr->validMask = channelPermissions | TCL_EXCEPTION; fsPtr->fd = fd; @@ -3239,13 +3261,13 @@ TclUnixWaitForFile(fd, mask, timeout) return result; } +#ifdef DEPRECATED /* *---------------------------------------------------------------------- * - * TclpCutFileChannel -- + * FileThreadActionProc -- * - * Remove any thread local refs to this channel. See - * Tcl_CutChannel for more info. + * Insert or remove any thread local refs to this channel. * * Results: * None. @@ -3256,35 +3278,39 @@ TclUnixWaitForFile(fd, mask, timeout) *---------------------------------------------------------------------- */ -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; { -} - -/* - *---------------------------------------------------------------------- - * - * TclpSpliceFileChannel -- - * - * Insert thread local ref for this channel. - * Tcl_SpliceChannel for more info. - * - * Results: - * None. - * - * Side effects: - * None. This is a no-op under unix. - * - *---------------------------------------------------------------------- - */ + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + FileState *fsPtr = (FileState *) instanceData; -void -TclpSpliceFileChannel(chan) - Tcl_Channel chan; /* The channel being removed. Must - * not be referenced in any - * interpreter. */ -{ + if (action == TCL_CHANNEL_THREAD_INSERT) { + fsPtr->nextPtr = tsdPtr->firstFilePtr; + tsdPtr->firstFilePtr = fsPtr; + } else { + FileState **nextPtrPtr; + int removed = 0; + + 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) { + Tcl_Panic("file info ptr not on thread channel list"); + } + } } +#endif |