diff options
author | andreas_kupries <andreas_kupries@noemail.net> | 2005-01-27 22:53:22 (GMT) |
---|---|---|
committer | andreas_kupries <andreas_kupries@noemail.net> | 2005-01-27 22:53:22 (GMT) |
commit | 7a7836163c871fad53891570f92211653aaad626 (patch) | |
tree | 222920345572469c253fc4368f14969609001923 /generic/tclIO.c | |
parent | 19f83aa0a97c3c7d3ce802e5b75a14c72a1ebe93 (diff) | |
download | tcl-7a7836163c871fad53891570f92211653aaad626.zip tcl-7a7836163c871fad53891570f92211653aaad626.tar.gz tcl-7a7836163c871fad53891570f92211653aaad626.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:
* mac/tclMacChan.c:
FossilOrigin-Name: 1621430b8bd8ba1f234e7b963155cd20e9a5decc
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r-- | generic/tclIO.c | 72 |
1 files changed, 57 insertions, 15 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index 054cc89..90451c1 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.61.2.8 2004/09/10 20:06:41 dkf Exp $ + * RCS: @(#) $Id: tclIO.c,v 1.61.2.9 2005/01/27 22:53:32 andreas_kupries Exp $ */ #include "tclInt.h" @@ -1208,18 +1208,19 @@ Tcl_CreateChannel(typePtr, chanName, instanceData, mask) * in the list on exit. * * JH: Could call Tcl_SpliceChannel, but need to avoid NULL check. + * + * TIP #218. + * AK: Just initialize the field to NULL before invoking Tcl_SpliceChannel + * We need Tcl_SpliceChannel, for the threadAction calls. + * There is no real reason to duplicate all of this. + * NOTE: All drivers using thread actions now have to perform their TSD + * manipulation only in their thread action proc. Doing it when + * creating their instance structures will collide with the thread + * action activity and lead to damaged lists. */ - statePtr->nextCSPtr = tsdPtr->firstCSPtr; - tsdPtr->firstCSPtr = statePtr; - - /* - * TIP #10. Mark the current thread as the one managing the new - * channel. Note: 'Tcl_GetCurrentThread' returns sensible - * values even for a non-threaded core. - */ - - statePtr->managingThread = Tcl_GetCurrentThread (); + statePtr->nextCSPtr = (ChannelState *) NULL; + Tcl_SpliceChannel ((Tcl_Channel) chanPtr); /* * Install this channel in the first empty standard channel slot, if @@ -2378,7 +2379,7 @@ CloseChannel(interp, chanPtr, errorCode) * Resets the field 'nextCSPtr' of the specified channel state to NULL. * * NOTE: - * The channel to splice out of the list must not be referenced + * The channel to cut out of the list must not be referenced * in any interpreter. This is something this procedure cannot * check (despite the refcount) because the caller usually wants * fiddle with the channel (like transfering it to a different @@ -2400,6 +2401,7 @@ Tcl_CutChannel(chan) * channel out of the list on close. */ ChannelState *statePtr = ((Channel *) chan)->state; /* state of the channel stack. */ + Tcl_DriverThreadActionProc *threadActionProc; /* * Remove this channel from of the list of all channels @@ -2422,7 +2424,12 @@ Tcl_CutChannel(chan) statePtr->nextCSPtr = (ChannelState *) NULL; - TclpCutFileChannel(chan); + /* TIP #218, Channel Thread Actions */ + threadActionProc = Tcl_ChannelThreadActionProc (Tcl_GetChannelType (chan)); + if (threadActionProc != NULL) { + (*threadActionProc) (Tcl_GetChannelInstanceData(chan), + TCL_CHANNEL_THREAD_REMOVE); + } } /* @@ -2441,7 +2448,7 @@ Tcl_CutChannel(chan) * Nothing. * * NOTE: - * The channel to add to the list must not be referenced in any + * The channel to splice into the list must not be referenced in any * interpreter. This is something this procedure cannot check * (despite the refcount) because the caller usually wants figgle * with the channel (like transfering it to a different thread) @@ -2459,6 +2466,7 @@ Tcl_SpliceChannel(chan) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); ChannelState *statePtr = ((Channel *) chan)->state; + Tcl_DriverThreadActionProc *threadActionProc; if (statePtr->nextCSPtr != (ChannelState *) NULL) { panic("Tcl_SpliceChannel: trying to add channel used in different list"); @@ -2475,7 +2483,12 @@ Tcl_SpliceChannel(chan) statePtr->managingThread = Tcl_GetCurrentThread (); - TclpSpliceFileChannel(chan); + /* TIP #218, Channel Thread Actions */ + threadActionProc = Tcl_ChannelThreadActionProc (Tcl_GetChannelType (chan)); + if (threadActionProc != NULL) { + (*threadActionProc) (Tcl_GetChannelInstanceData(chan), + TCL_CHANNEL_THREAD_INSERT); + } } /* @@ -8902,6 +8915,8 @@ Tcl_ChannelVersion(chanTypePtr) return TCL_CHANNEL_VERSION_2; } else if (chanTypePtr->version == TCL_CHANNEL_VERSION_3) { return TCL_CHANNEL_VERSION_3; + } else if (chanTypePtr->version == TCL_CHANNEL_VERSION_4) { + return TCL_CHANNEL_VERSION_4; } else { /* * In <v2 channel versions, the version field is occupied @@ -9254,6 +9269,33 @@ Tcl_ChannelWideSeekProc(chanTypePtr) return NULL; } } + +/* + *---------------------------------------------------------------------- + * + * Tcl_ChannelThreadActionProc -- + * + * Return the Tcl_DriverThreadActionProc of the channel type. + * + * Results: + * A pointer to the proc. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_DriverThreadActionProc * +Tcl_ChannelThreadActionProc(chanTypePtr) + Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */ +{ + if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_4)) { + return chanTypePtr->threadActionProc; + } else { + return NULL; + } +} #if 0 /* For future debugging work, a simple function to print the flags of |