summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorandreas_kupries <akupries@shaw.ca>2005-01-27 00:22:53 (GMT)
committerandreas_kupries <akupries@shaw.ca>2005-01-27 00:22:53 (GMT)
commit98dadc4e726ce2e9342141de853d74f6d614cc7b (patch)
treec0e294ceaa42e69c4fe42ce673e1336cf236d856 /generic
parent3c6ddb9aced9de4312cc2a982bf5715af646eddb (diff)
downloadtcl-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.decls7
-rw-r--r--generic/tcl.h23
-rw-r--r--generic/tclDecls.h13
-rw-r--r--generic/tclIO.c79
-rw-r--r--generic/tclInt.h6
-rw-r--r--generic/tclStubInit.c3
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. */