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 /generic | |
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 'generic')
-rw-r--r-- | generic/tcl.decls | 7 | ||||
-rw-r--r-- | generic/tcl.h | 23 | ||||
-rw-r--r-- | generic/tclDecls.h | 13 | ||||
-rw-r--r-- | generic/tclIO.c | 79 | ||||
-rw-r--r-- | generic/tclInt.h | 6 | ||||
-rw-r--r-- | generic/tclStubInit.c | 3 |
6 files changed, 102 insertions, 29 deletions
diff --git a/generic/tcl.decls b/generic/tcl.decls index 4f20a56..cd95420 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -11,7 +11,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: tcl.decls,v 1.107 2005/01/21 22:25:08 andreas_kupries Exp $ +# RCS: @(#) $Id: tcl.decls,v 1.108 2005/01/27 00:22:58 andreas_kupries Exp $ library tcl @@ -1984,7 +1984,10 @@ declare 553 generic { Tcl_ScaleTimeProc** scaleProc, ClientData* clientData) } - +# TIP#218 (Driver Thread Actions) davygrvy/akupries ChannelType ver 4 +declare 554 generic { + Tcl_DriverThreadActionProc *Tcl_ChannelThreadActionProc(Tcl_ChannelType *chanTypePtr) +} ############################################################################## diff --git a/generic/tcl.h b/generic/tcl.h index d1638bc..a79e092 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tcl.h,v 1.195 2005/01/21 22:25:09 andreas_kupries Exp $ + * RCS: @(#) $Id: tcl.h,v 1.196 2005/01/27 00:22:58 andreas_kupries Exp $ */ #ifndef _TCL @@ -1460,6 +1460,14 @@ typedef void (Tcl_ScaleTimeProc) _ANSI_ARGS_ ((Tcl_Time* timebuf, ClientData cli #define TCL_CHANNEL_VERSION_1 ((Tcl_ChannelTypeVersion) 0x1) #define TCL_CHANNEL_VERSION_2 ((Tcl_ChannelTypeVersion) 0x2) #define TCL_CHANNEL_VERSION_3 ((Tcl_ChannelTypeVersion) 0x3) +#define TCL_CHANNEL_VERSION_4 ((Tcl_ChannelTypeVersion) 0x4) + +/* + * TIP #218: Channel Actions, Ids for Tcl_DriverThreadActionProc + */ + +#define TCL_CHANNEL_THREAD_INSERT (0) +#define TCL_CHANNEL_THREAD_REMOVE (1) /* * Typedefs for the various operations in a channel type: @@ -1495,6 +1503,9 @@ typedef Tcl_WideInt (Tcl_DriverWideSeekProc) _ANSI_ARGS_(( ClientData instanceData, Tcl_WideInt offset, int mode, int *errorCodePtr)); +/* TIP #218, Channel Thread Actions */ +typedef void (Tcl_DriverThreadActionProc) _ANSI_ARGS_ (( + ClientData instanceData, int action)); /* * The following declarations either map ckalloc and ckfree to @@ -1585,6 +1596,16 @@ typedef struct Tcl_ChannelType { * handle 64-bit offsets. May be * NULL, and must be NULL if * seekProc is NULL. */ + + /* + * Only valid in TCL_CHANNEL_VERSION_4 channels or later + * TIP #218, Channel Thread Actions + */ + Tcl_DriverThreadActionProc *threadActionProc; + /* Procedure to call to notify + * the driver of thread specific + * activity for a channel. + * May be NULL. */ } Tcl_ChannelType; /* diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 800f53d..1226d00 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclDecls.h,v 1.109 2005/01/21 22:25:11 andreas_kupries Exp $ + * RCS: @(#) $Id: tclDecls.h,v 1.110 2005/01/27 00:23:16 andreas_kupries Exp $ */ #ifndef _TCLDECLS @@ -3452,6 +3452,12 @@ EXTERN void Tcl_QueryTimeProc _ANSI_ARGS_(( Tcl_ScaleTimeProc** scaleProc, ClientData* clientData)); #endif +#ifndef Tcl_ChannelThreadActionProc_TCL_DECLARED +#define Tcl_ChannelThreadActionProc_TCL_DECLARED +/* 554 */ +EXTERN Tcl_DriverThreadActionProc * Tcl_ChannelThreadActionProc _ANSI_ARGS_(( + Tcl_ChannelType * chanTypePtr)); +#endif typedef struct TclStubHooks { struct TclPlatStubs *tclPlatStubs; @@ -4047,6 +4053,7 @@ typedef struct TclStubs { int (*tcl_GetEnsembleNamespace) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, Tcl_Namespace ** namespacePtrPtr)); /* 551 */ void (*tcl_SetTimeProc) _ANSI_ARGS_((Tcl_GetTimeProc* getProc, Tcl_ScaleTimeProc* scaleProc, ClientData clientData)); /* 552 */ void (*tcl_QueryTimeProc) _ANSI_ARGS_((Tcl_GetTimeProc** getProc, Tcl_ScaleTimeProc** scaleProc, ClientData* clientData)); /* 553 */ + Tcl_DriverThreadActionProc * (*tcl_ChannelThreadActionProc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 554 */ } TclStubs; #ifdef __cplusplus @@ -6303,6 +6310,10 @@ extern TclStubs *tclStubsPtr; #define Tcl_QueryTimeProc \ (tclStubsPtr->tcl_QueryTimeProc) /* 553 */ #endif +#ifndef Tcl_ChannelThreadActionProc +#define Tcl_ChannelThreadActionProc \ + (tclStubsPtr->tcl_ChannelThreadActionProc) /* 554 */ +#endif #endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */ diff --git a/generic/tclIO.c b/generic/tclIO.c index bb6c438..f7cba66 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.81 2004/11/30 19:34:47 dgp Exp $ + * RCS: @(#) $Id: tclIO.c,v 1.82 2005/01/27 00:23:23 andreas_kupries Exp $ */ #include "tclInt.h" @@ -1205,18 +1205,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 @@ -2382,7 +2383,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 @@ -2404,6 +2405,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 @@ -2426,8 +2428,12 @@ Tcl_CutChannel(chan) statePtr->nextCSPtr = (ChannelState *) NULL; - TclpCutFileChannel(chan); - TclpCutSockChannel(chan); + /* TIP #218, Channel Thread Actions */ + threadActionProc = Tcl_ChannelThreadActionProc (Tcl_GetChannelType (chan)); + if (threadActionProc != NULL) { + (*threadActionProc) (Tcl_GetChannelInstanceData(chan), + TCL_CHANNEL_THREAD_REMOVE); + } } /* @@ -2446,7 +2452,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) @@ -2462,8 +2468,9 @@ Tcl_SpliceChannel(chan) * not be referenced in any * interpreter. */ { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - ChannelState *statePtr = ((Channel *) chan)->state; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + ChannelState *statePtr = ((Channel *) chan)->state; + Tcl_DriverThreadActionProc *threadActionProc; if (statePtr->nextCSPtr != (ChannelState *) NULL) { Tcl_Panic("Tcl_SpliceChannel: trying to add channel used in different list"); @@ -2480,8 +2487,12 @@ Tcl_SpliceChannel(chan) statePtr->managingThread = Tcl_GetCurrentThread(); - TclpSpliceFileChannel(chan); - TclpSpliceSockChannel(chan); + /* TIP #218, Channel Thread Actions */ + threadActionProc = Tcl_ChannelThreadActionProc (Tcl_GetChannelType (chan)); + if (threadActionProc != NULL) { + (*threadActionProc) (Tcl_GetChannelInstanceData(chan), + TCL_CHANNEL_THREAD_INSERT); + } } /* @@ -8953,6 +8964,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 @@ -9308,6 +9321,34 @@ Tcl_ChannelWideSeekProc(chanTypePtr) } } +/* + *---------------------------------------------------------------------- + * + * Tcl_ChannelThreadActionProc -- + * + * TIP #218, Channel Thread Actions. + * 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 diff --git a/generic/tclInt.h b/generic/tclInt.h index df48d31..2f760d1 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.213 2005/01/21 22:25:18 andreas_kupries Exp $ + * RCS: @(#) $Id: tclInt.h,v 1.214 2005/01/27 00:23:26 andreas_kupries Exp $ */ #ifndef _TCLINT @@ -1977,10 +1977,6 @@ MODULE_SCOPE Tcl_Obj* TclpObjLink _ANSI_ARGS_((Tcl_Obj *pathPtr, MODULE_SCOPE int TclpObjChdir _ANSI_ARGS_((Tcl_Obj *pathPtr)); MODULE_SCOPE Tcl_Obj * TclPathPart _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_PathPart portion)); -MODULE_SCOPE void TclpCutFileChannel _ANSI_ARGS_((Tcl_Channel chan)); -MODULE_SCOPE void TclpCutSockChannel _ANSI_ARGS_((Tcl_Channel chan)); -MODULE_SCOPE void TclpSpliceFileChannel _ANSI_ARGS_((Tcl_Channel chan)); -MODULE_SCOPE void TclpSpliceSockChannel _ANSI_ARGS_((Tcl_Channel chan)); MODULE_SCOPE void TclpPanic _ANSI_ARGS_(TCL_VARARGS(CONST char *, format)); MODULE_SCOPE char * TclpReadlink _ANSI_ARGS_((CONST char *fileName, diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index fe406e6..29ed7bb 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclStubInit.c,v 1.112 2005/01/21 22:25:19 andreas_kupries Exp $ + * RCS: @(#) $Id: tclStubInit.c,v 1.113 2005/01/27 00:23:27 andreas_kupries Exp $ */ #include "tclInt.h" @@ -970,6 +970,7 @@ TclStubs tclStubs = { Tcl_GetEnsembleNamespace, /* 551 */ Tcl_SetTimeProc, /* 552 */ Tcl_QueryTimeProc, /* 553 */ + Tcl_ChannelThreadActionProc, /* 554 */ }; /* !END!: Do not edit above this line. */ |