Attachment "patch.txt" to
ticket [875701ffff]
added by
davygrvy
2004-01-14 10:13:19.
*** doc/CrtChannel.3 1 Jul 2002 18:24:39 -0000 1.16
--- doc/CrtChannel.3 14 Jan 2004 02:18:02 -0000
***************
*** 7,17 ****
'\"
'\" RCS: @(#) $Id: CrtChannel.3,v 1.16 2002/07/01 18:24:39 jenglish Exp $
.so man.macros
! .TH Tcl_CreateChannel 3 8.3 Tcl "Tcl Library Procedures"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
! Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_ChannelWideSeekProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers, Tcl_GetChannelThread, Tcl_ChannelBuffered \- procedures for creating and manipulating channels
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
--- 7,17 ----
'\"
'\" RCS: @(#) $Id: CrtChannel.3,v 1.16 2002/07/01 18:24:39 jenglish Exp $
.so man.macros
! .TH Tcl_CreateChannel 3 8.5 Tcl "Tcl Library Procedures"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
! Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_ChannelWideSeekProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_ChannelCutProc, Tcl_ChannelSpliceProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers, Tcl_GetChannelThread, Tcl_ChannelBuffered \- procedures for creating and manipulating channels
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
***************
*** 98,103 ****
--- 98,113 ----
\fBTcl_ChannelWideSeekProc\fR(\fItypePtr\fR)
.VE 8.4
.sp
+ .VS 8.5
+ Tcl_DriverCutProc *
+ \fBTcl_ChannelCutProc\fR(\fItypePtr\fR)
+ .VE 8.5
+ .sp
+ .VS 8.5
+ Tcl_DriverSpliceProc *
+ \fBTcl_ChannelSpliceProc\fR(\fItypePtr\fR)
+ .VE 8.5
+ .sp
Tcl_DriverSetOptionProc *
\fBTcl_ChannelSetOptionProc\fR(\fItypePtr\fR)
.sp
***************
*** 286,295 ****
--- 296,313 ----
(thread)global list of all channels (of the current thread).
Application to a channel still registered in some interpreter
is not allowed.
+ .VS 8.5
+ Also notifiers the driver if the \fBTcl_ChannelType\fR version is
+ \fBTCL_CHANNEL_VERSION_4\fR (or higher).
+ .VE 8.5
.PP
\fBTcl_SpliceChannel\fR adds the specified \fIchannel\fR to the
(thread)global list of all channels (of the current thread).
Application to a channel registered in some interpreter is not allowed.
+ .VS 8.5
+ Also notifiers the driver if the \fBTcl_ChannelType\fR version is
+ \fBTCL_CHANNEL_VERSION_4\fR (or higher).
+ .VE 8.5
.PP
\fBTcl_ClearChannelHandlers\fR removes all channelhandlers and event
scripts associated with the specified \fIchannel\fR, thus shutting
***************
*** 323,328 ****
--- 341,348 ----
Tcl_DriverFlushProc *\fIflushProc\fR;
Tcl_DriverHandlerProc *\fIhandlerProc\fR;
Tcl_DriverWideSeekProc *\fIwideSeekProc\fR;
+ Tcl_DriverCutProc *\fIcutProc\fR;
+ Tcl_DriverSpliceProc *\fIspliceProc\fR;
} Tcl_ChannelType;
.CE
.PP
***************
*** 344,349 ****
--- 364,372 ----
.VS 8.4
\fBTcl_ChannelWideSeekProc\fR,
.VE 8.4
+ .VS 8.5
+ \fBTcl_ChannelCutProc\fR, \fBTcl_ChannelSpliceProc\fR,
+ .VE 8.5
\fBTcl_ChannelSetOptionProc\fR, \fBTcl_ChannelGetOptionProc\fR,
\fBTcl_ChannelWatchProc\fR, \fBTcl_ChannelGetHandleProc\fR,
\fBTcl_ChannelFlushProc\fR, or \fBTcl_ChannelHandlerProc\fR.
***************
*** 364,377 ****
.SH VERSION
.PP
! The \fIversion\fR field should be set to \fBTCL_CHANNEL_VERSION_2\fR.
! If it is not set to this value \fBTCL_CHANNEL_VERSION_3\fR, then this
! \fBTcl_ChannelType\fR is assumed to have the older structure. See
\fBOLD CHANNEL TYPES\fR for more details. While Tcl will recognize
! and function with either structure, stacked channels must be of at
least \fBTCL_CHANNEL_VERSION_2\fR to function correctly.
.PP
This value can be retrieved with \fBTcl_ChannelVersion\fR, which returns
.VS 8.4
one of \fBTCL_CHANNEL_VERSION_3\fR,
.VE 8.4
--- 387,411 ----
.SH VERSION
.PP
! The \fIversion\fR field should be set to the version of the structure
! that you require. \fBTCL_CHANNEL_VERSION_2\fR is the minimum recommended.
! .VS 8.4
! \fBTCL_CHANNEL_VERSION_3\fR must be set to specifiy the \fIwideSeekProc\fR member.
! .VE 8.4
! .VS 8.5
! \fBTCL_CHANNEL_VERSION_4\fR must be set to specifiy the \fIcutProc\fR and
! \fIspliceProc\fR members (includes \fIwideSeekProc\fR).
! .VE 8.5
! If it is not set to any of these, then this
! \fBTcl_ChannelType\fR is assumed to have the original structure. See
\fBOLD CHANNEL TYPES\fR for more details. While Tcl will recognize
! and function with either structures, stacked channels must be of at
least \fBTCL_CHANNEL_VERSION_2\fR to function correctly.
.PP
This value can be retrieved with \fBTcl_ChannelVersion\fR, which returns
+ .VS 8.5
+ one of \fBTCL_CHANNEL_VERSION_4\fR,
+ .VE 8.5
.VS 8.4
one of \fBTCL_CHANNEL_VERSION_3\fR,
.VE 8.4
***************
*** 779,784 ****
--- 813,847 ----
This value can be retrieved with \fBTcl_ChannelHandlerProc\fR, which returns
a pointer to the function.
+ .VS 8.5
+ .SH "CUTPROC AND SPLICEPROC"
+ .PP
+ The \fIcutProc\fR and \fIspliceProc\fR fields contain the addresses of
+ the functions called by the generic layer when a channel is to move to
+ a different thread and can be NULL. \fIcutProc\fR is used to notify the
+ driver that it should remove any thread-specific references it might be
+ maintaining. \fIcutProc\fR can also be called when the channel is closing,
+ too. \fIspliceProc\fR is used to notify the driver that it should update
+ any thread-specific references it might be maintaining using the calling
+ thread as the associate. See \fBTcl_CutChannel\fR and \fBTcl_SpliceChannel\fR
+ for more detail.
+ .PP
+ .CS
+ typedef void Tcl_DriverCutProc(
+ ClientData \fIinstanceData\fR);
+ .CE
+ .CS
+ typedef void Tcl_DriverSpliceProc(
+ ClientData \fIinstanceData\fR);
+ .CE
+ .PP
+ \fIInstanceData\fR is the same as the value passed to \fBTcl_CreateChannel\fR
+ when this channel was created.
+ .PP
+ These values can be retrieved with \fBTcl_ChannelCutProc\fR and
+ \fBTcl_ChannelCutProc\fR, which returns a pointer to the function.
+ .VE 8.5
+
.SH TCL_BADCHANNELOPTION
.PP
This procedure generates a "bad option" error message in an
*** generic/tcl.decls 29 Sep 2003 21:38:49 -0000 1.101
--- generic/tcl.decls 14 Jan 2004 02:18:05 -0000
***************
*** 1860,1865 ****
--- 1860,1873 ----
Tcl_ExitProc *Tcl_SetExitProc(Tcl_ExitProc *proc)
}
+ # davygrvy channelType ver 4 TIP#{unassigned}
+ declare 520 generic {
+ Tcl_DriverCutProc *Tcl_ChannelCutProc(Tcl_ChannelType *chanTypePtr)
+ }
+ declare 521 generic {
+ Tcl_DriverSpliceProc *Tcl_ChannelSpliceProc(Tcl_ChannelType *chanTypePtr)
+ }
+
##############################################################################
# Define the platform specific public Tcl interface. These functions are
*** generic/tcl.h 9 Jan 2004 20:55:26 -0000 1.170
--- generic/tcl.h 14 Jan 2004 02:18:09 -0000
***************
*** 1434,1440 ****
* should be closed.
*/
#define TCL_CLOSE_READ (1<<1)
! #define TCL_CLOSE_WRITE (1<<2)
/*
* Value to use as the closeProc for a channel that supports the
--- 1434,1440 ----
* should be closed.
*/
#define TCL_CLOSE_READ (1<<1)
! #define TCL_CLOSE_WRITE (1<<2)
/*
* Value to use as the closeProc for a channel that supports the
***************
*** 1448,1453 ****
--- 1448,1454 ----
#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)
/*
* Typedefs for the various operations in a channel type:
***************
*** 1482,1487 ****
--- 1483,1492 ----
typedef Tcl_WideInt (Tcl_DriverWideSeekProc) _ANSI_ARGS_((
ClientData instanceData, Tcl_WideInt offset,
int mode, int *errorCodePtr));
+ typedef void (Tcl_DriverCutProc) _ANSI_ARGS_((
+ ClientData instanceData));
+ typedef void (Tcl_DriverSpliceProc) _ANSI_ARGS_((
+ ClientData instanceData));
/*
***************
*** 1573,1578 ****
--- 1578,1594 ----
* 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
+ */
+ Tcl_DriverCutProc *cutProc; /* Procedure to call to allow the
+ * driver to remove any thread
+ * specific data. */
+ Tcl_DriverSpliceProc *spliceProc; /* Procedure to call to allow the
+ * driver to insert new thread
+ * specific data on the moved
+ * channel. */
+
} Tcl_ChannelType;
/*
***************
*** 1580,1587 ****
* set the channel into blocking or nonblocking mode. They are passed
* as arguments to the blockModeProc procedure in the above structure.
*/
! #define TCL_MODE_BLOCKING 0 /* Put channel into blocking mode. */
! #define TCL_MODE_NONBLOCKING 1 /* Put channel into nonblocking
* mode. */
/*
--- 1596,1603 ----
* set the channel into blocking or nonblocking mode. They are passed
* as arguments to the blockModeProc procedure in the above structure.
*/
! #define TCL_MODE_BLOCKING 0 /* Put channel into blocking mode. */
! #define TCL_MODE_NONBLOCKING 1 /* Put channel into nonblocking
* mode. */
/*
*** generic/tclInt.h 13 Jan 2004 23:15:03 -0000 1.140
--- generic/tclInt.h 14 Jan 2004 02:18:17 -0000
***************
*** 1786,1795 ****
EXTERN Tcl_Channel TclpOpenFileChannel _ANSI_ARGS_((Tcl_Interp *interp,
Tcl_Obj *pathPtr, int mode,
int permissions));
- EXTERN void TclpCutFileChannel _ANSI_ARGS_((Tcl_Channel chan));
- EXTERN void TclpCutSockChannel _ANSI_ARGS_((Tcl_Channel chan));
- EXTERN void TclpSpliceFileChannel _ANSI_ARGS_((Tcl_Channel chan));
- EXTERN void TclpSpliceSockChannel _ANSI_ARGS_((Tcl_Channel chan));
EXTERN void TclpPanic _ANSI_ARGS_(TCL_VARARGS(CONST char *,
format));
EXTERN char * TclpReadlink _ANSI_ARGS_((CONST char *fileName,
--- 1786,1791 ----
*** generic/tclIO.c 24 Dec 2003 04:18:19 -0000 1.69
--- generic/tclIO.c 14 Jan 2004 02:18:24 -0000
***************
*** 2388,2393 ****
--- 2388,2394 ----
* channel out of the list on close. */
ChannelState *statePtr = ((Channel *) chan)->state;
/* state of the channel stack. */
+ Tcl_DriverCutProc *cutProc;
/*
* Remove this channel from of the list of all channels
***************
*** 2410,2417 ****
statePtr->nextCSPtr = (ChannelState *) NULL;
! TclpCutFileChannel(chan);
! TclpCutSockChannel(chan);
}
/*
--- 2411,2420 ----
statePtr->nextCSPtr = (ChannelState *) NULL;
! cutProc = Tcl_ChannelCutProc(Tcl_GetChannelType(chan));
! if (cutProc != NULL) {
! (*cutProc)(Tcl_GetChannelInstanceData(chan));
! }
}
/*
***************
*** 2448,2453 ****
--- 2451,2457 ----
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
ChannelState *statePtr = ((Channel *) chan)->state;
+ Tcl_DriverSpliceProc *spliceProc;
if (statePtr->nextCSPtr != (ChannelState *) NULL) {
Tcl_Panic("Tcl_SpliceChannel: trying to add channel used in different list");
***************
*** 2462,2471 ****
* values even for a non-threaded core.
*/
! statePtr->managingThread = Tcl_GetCurrentThread ();
!
! TclpSpliceFileChannel(chan);
! TclpSpliceSockChannel(chan);
}
/*
--- 2466,2476 ----
* values even for a non-threaded core.
*/
! statePtr->managingThread = Tcl_GetCurrentThread();
! spliceProc = Tcl_ChannelSpliceProc(Tcl_GetChannelType(chan));
! if (spliceProc != NULL) {
! (*spliceProc)(Tcl_GetChannelInstanceData(chan));
! }
}
/*
***************
*** 8826,8831 ****
--- 8831,8838 ----
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
***************
*** 9178,9180 ****
--- 9185,9241 ----
return NULL;
}
}
+
+ /*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelCutProc --
+ *
+ * Return the Tcl_DriverCutProc of the channel type.
+ *
+ * Results:
+ * A pointer to the proc.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ Tcl_DriverCutProc *
+ Tcl_ChannelCutProc(chanTypePtr)
+ Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
+ {
+ if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_4)) {
+ return chanTypePtr->cutProc;
+ } else {
+ return NULL;
+ }
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelSpliceProc --
+ *
+ * Return the Tcl_DriverSpliceProc of the channel type.
+ *
+ * Results:
+ * A pointer to the proc.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ Tcl_DriverSpliceProc *
+ Tcl_ChannelSpliceProc(chanTypePtr)
+ Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
+ {
+ if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_4)) {
+ return chanTypePtr->spliceProc;
+ } else {
+ return NULL;
+ }
+ }
*** generic/tclIOGT.c 24 May 2002 21:19:06 -0000 1.7
--- generic/tclIOGT.c 14 Jan 2004 02:18:26 -0000
***************
*** 131,137 ****
static Tcl_ChannelType transformChannelType = {
"transform", /* Type name. */
! TCL_CHANNEL_VERSION_2,
TransformCloseProc, /* Close proc. */
TransformInputProc, /* Input proc. */
TransformOutputProc, /* Output proc. */
--- 131,137 ----
static Tcl_ChannelType transformChannelType = {
"transform", /* Type name. */
! TCL_CHANNEL_VERSION_3,
TransformCloseProc, /* Close proc. */
TransformInputProc, /* Input proc. */
TransformOutputProc, /* Output proc. */
*** mac/tclMacChan.c 24 Dec 2003 04:18:21 -0000 1.22
--- mac/tclMacChan.c 14 Jan 2004 02:18:30 -0000
***************
*** 79,129 ****
* Static routines for this file:
*/
! static int CommonGetHandle _ANSI_ARGS_((ClientData instanceData,
! int direction, ClientData *handlePtr));
! static void CommonWatch _ANSI_ARGS_((ClientData instanceData,
! int mask));
! static int FileBlockMode _ANSI_ARGS_((ClientData instanceData,
! int mode));
! static void FileChannelExitHandler _ANSI_ARGS_((
! ClientData clientData));
! static void FileCheckProc _ANSI_ARGS_((ClientData clientData,
! int flags));
! static int FileClose _ANSI_ARGS_((ClientData instanceData,
! Tcl_Interp *interp));
! static int FileEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
! int flags));
! static ThreadSpecificData *FileInit _ANSI_ARGS_((void));
! static int FileInput _ANSI_ARGS_((ClientData instanceData,
! char *buf, int toRead, int *errorCode));
! static int FileOutput _ANSI_ARGS_((ClientData instanceData,
! CONST char *buf, int toWrite, int *errorCode));
! static int FileSeek _ANSI_ARGS_((ClientData instanceData,
! long offset, int mode, int *errorCode));
! static void FileSetupProc _ANSI_ARGS_((ClientData clientData,
! int flags));
! static Tcl_Channel OpenFileChannel _ANSI_ARGS_((CONST char *fileName,
! int mode, int permissions, int *errorCodePtr));
! static int StdIOBlockMode _ANSI_ARGS_((ClientData instanceData,
! int mode));
! static int StdIOClose _ANSI_ARGS_((ClientData instanceData,
! Tcl_Interp *interp));
! static int StdIOInput _ANSI_ARGS_((ClientData instanceData,
! char *buf, int toRead, int *errorCode));
! static int StdIOOutput _ANSI_ARGS_((ClientData instanceData,
! CONST char *buf, int toWrite, int *errorCode));
! static int StdIOSeek _ANSI_ARGS_((ClientData instanceData,
! long offset, int mode, int *errorCode));
! static int StdReady _ANSI_ARGS_((ClientData instanceData,
! int mask));
/*
* This structure describes the channel type structure for file based IO:
*/
static Tcl_ChannelType consoleChannelType = {
! "file", /* Type name. */
! (Tcl_ChannelTypeVersion)StdIOBlockMode, /* Set blocking/nonblocking mode.*/
StdIOClose, /* Close proc. */
StdIOInput, /* Input proc. */
StdIOOutput, /* Output proc. */
--- 79,117 ----
* Static routines for this file:
*/
! static Tcl_DriverCutProc CommonCutProc;
! static Tcl_DriverGetHandleProc CommonGetHandle;
! static Tcl_DriverSpliceProc CommonSpliceProc;
! static Tcl_DriverWatchProc CommonWatch;
!
! static Tcl_DriverBlockModeProc FileBlockMode;
! static Tcl_ExitProc FileChannelExitHandler;
! static Tcl_EventCheckProc FileCheckProc;
! static Tcl_DriverCloseProc FileClose;
! static Tcl_EventProc FileEventProc;
! static ThreadSpecificData * FileInit _ANSI_ARGS_((void));
! static Tcl_DriverInputProc FileInput;
! static Tcl_DriverOutputProc FileOutput;
! static Tcl_DriverSeekProc FileSeek;
! static Tcl_EventSetupProc FileSetupProc;
! static Tcl_Channel OpenFileChannel _ANSI_ARGS_((
! CONST char *fileName, int mode,
! int permissions, int *errorCodePtr));
! static Tcl_DriverBlockModeProc StdIOBlockMode;
! static Tcl_DriverCloseProc StdIOClose;
! static Tcl_DriverInputProc StdIOInput;
! static Tcl_DriverOutputProc StdIOOutput;
! static Tcl_DriverSeekProc StdIOSeek;
! static int StdReady _ANSI_ARGS_((
! ClientData instanceData, int mask));
/*
* This structure describes the channel type structure for file based IO:
*/
static Tcl_ChannelType consoleChannelType = {
! "console", /* Type name. */
! TCL_CHANNEL_VERSION_4, /* v2 channel */
StdIOClose, /* Close proc. */
StdIOInput, /* Input proc. */
StdIOOutput, /* Output proc. */
***************
*** 131,137 ****
NULL, /* Set option proc. */
NULL, /* Get option proc. */
CommonWatch, /* Initialize notifier. */
! CommonGetHandle /* Get OS handles out of channel. */
};
/*
--- 119,132 ----
NULL, /* Set option proc. */
NULL, /* Get option proc. */
CommonWatch, /* Initialize notifier. */
! CommonGetHandle, /* Get OS handles out of channel. */
! NULL, /* close2 proc. */
! StdIOBlockMode, /* Set blocking/nonblocking mode.*/
! NULL, /* flush proc. */
! NULL, /* handler proc. */
! NULL, /* wide seek proc. */
! CommonCutProc, /* cut proc. */
! CommonSpliceProc, /* splice proc. */
};
/*
***************
*** 140,147 ****
static Tcl_ChannelType fileChannelType = {
"file", /* Type name. */
! (Tcl_ChannelTypeVersion)FileBlockMode, /* Set blocking or
! * non-blocking mode.*/
FileClose, /* Close proc. */
FileInput, /* Input proc. */
FileOutput, /* Output proc. */
--- 135,141 ----
static Tcl_ChannelType fileChannelType = {
"file", /* Type name. */
! TCL_CHANNEL_VERSION_4, /* v4 channel */
FileClose, /* Close proc. */
FileInput, /* Input proc. */
FileOutput, /* Output proc. */
***************
*** 149,155 ****
NULL, /* Set option proc. */
NULL, /* Get option proc. */
CommonWatch, /* Initialize notifier. */
! CommonGetHandle /* Get OS handles out of channel. */
};
--- 143,156 ----
NULL, /* Set option proc. */
NULL, /* Get option proc. */
CommonWatch, /* Initialize notifier. */
! CommonGetHandle, /* Get OS handles out of channel. */
! NULL, /* close2 proc. */
! FileBlockMode, /* Set blocking or non-blocking mode. */
! NULL, /* flush proc. */
! NULL, /* handler proc. */
! NULL, /* wide seek proc. */
! CommonCutProc, /* cut proc. */
! CommonSpliceProc, /* splice proc. */
};
***************
*** 241,247 ****
{
FileState *infoPtr;
Tcl_Time blockTime = { 0, 0 };
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
--- 242,250 ----
{
FileState *infoPtr;
Tcl_Time blockTime = { 0, 0 };
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = FileInit();
if (!(flags & TCL_FILE_EVENTS)) {
return;
***************
*** 286,292 ****
FileState *infoPtr;
int sentMsg = 0;
Tcl_Time blockTime = { 0, 0 };
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
--- 289,297 ----
FileState *infoPtr;
int sentMsg = 0;
Tcl_Time blockTime = { 0, 0 };
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = FileInit();
if (!(flags & TCL_FILE_EVENTS)) {
return;
***************
*** 338,344 ****
{
FileEvent *fileEvPtr = (FileEvent *)evPtr;
FileState *infoPtr;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return 0;
--- 343,351 ----
{
FileEvent *fileEvPtr = (FileEvent *)evPtr;
FileState *infoPtr;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = FileInit();
if (!(flags & TCL_FILE_EVENTS)) {
return 0;
***************
*** 416,422 ****
Tcl_Interp *interp) /* Unused. */
{
int fd, errorCode = 0;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
* Invalidate the stdio cache if necessary. Note that we assume that
--- 423,431 ----
Tcl_Interp *interp) /* Unused. */
{
int fd, errorCode = 0;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = FileInit();
/*
* Invalidate the stdio cache if necessary. Note that we assume that
***************
*** 673,678 ****
--- 682,690 ----
char channelName[16 + TCL_INTEGER_SPACE];
int channelPermissions;
FileState *fileState;
+ ThreadSpecificData *tsdPtr;
+
+ tsdPtr = FileInit();
/*
* If the channels were not created yet, create them now and
***************
*** 706,711 ****
--- 718,725 ----
(ClientData) fileState, channelPermissions);
fileState->fileChan = channel;
fileState->fileRef = fd;
+ fileState->nextPtr = tsdPtr->firstFilePtr;
+ tsdPtr->firstFilePtr = fileState;
/*
* Set up the normal channel options for stdio handles.
***************
*** 1212,1221 ****
/*
*----------------------------------------------------------------------
*
! * TclpCutFileChannel --
*
! * Remove any thread local refs to this channel. See
! * Tcl_CutChannel for more info.
*
* Results:
* None.
--- 1226,1235 ----
/*
*----------------------------------------------------------------------
*
! * CommonCutProc --
*
! * Driver procedure to remove any thread local refs to this
! * channel. See Tcl_CutChannel for more info.
*
* Results:
* None.
***************
*** 1226,1247 ****
*----------------------------------------------------------------------
*/
! void
! TclpCutFileChannel(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;
! FileState *infoPtr;
FileState **nextPtrPtr;
int removed = 0;
! if (chanPtr->typePtr != &fileChannelType)
! return;
!
! infoPtr = (FileState *) chanPtr->instanceData;
for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL;
nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
--- 1240,1255 ----
*----------------------------------------------------------------------
*/
! static void
! CommonCutProc(instanceData)
! ClientData instanceData, /* The file state. */
{
! ThreadSpecificData *tsdPtr;
! FileState *infoPtr = (FileState *) chanPtr->instanceData;
FileState **nextPtrPtr;
int removed = 0;
! tsdPtr = FileInit();
for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL;
nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
***************
*** 1259,1275 ****
*/
if (!removed) {
! Tcl_Panic("file info ptr not on thread channel list");
}
}
/*
*----------------------------------------------------------------------
*
! * TclpSpliceFileChannel --
*
! * Insert thread local ref for this channel.
! * Tcl_SpliceChannel for more info.
*
* Results:
* None.
--- 1267,1283 ----
*/
if (!removed) {
! Tcl_Panic("FileState ptr not on thread channel list");
}
}
/*
*----------------------------------------------------------------------
*
! * CommonSpliceProc --
*
! * Driver procedure to insert thread local ref for this channel.
! * See Tcl_SpliceChannel for more info.
*
* Results:
* None.
***************
*** 1280,1299 ****
*----------------------------------------------------------------------
*/
! 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;
! FileState *infoPtr;
!
! if (chanPtr->typePtr != &fileChannelType)
! return;
! infoPtr = (FileState *) chanPtr->instanceData;
infoPtr->nextPtr = tsdPtr->firstFilePtr;
tsdPtr->firstFilePtr = infoPtr;
--- 1288,1301 ----
*----------------------------------------------------------------------
*/
! static void
! CommonSpliceProc(instanceData)
! ClientData instanceData, /* The file state. */
{
! ThreadSpecificData *tsdPtr;
! FileState *infoPtr = (FileState *) chanPtr->instanceData;
! tsdPtr = FileInit();
infoPtr->nextPtr = tsdPtr->firstFilePtr;
tsdPtr->firstFilePtr = infoPtr;
*** mac/tclMacSock.c 24 Dec 2003 04:18:21 -0000 1.16
--- mac/tclMacSock.c 14 Jan 2004 02:18:34 -0000
***************
*** 130,186 ****
StreamPtr tcpStream; /* Low level Macintosh stream. */
} SocketEvent;
/*
* Static routines for this file:
*/
! static pascal void CleanUpExitProc _ANSI_ARGS_((void));
! static void ClearZombieSockets _ANSI_ARGS_((void));
! static void CloseCompletionRoutine _ANSI_ARGS_((TCPiopb *pb));
! static TcpState * CreateSocket _ANSI_ARGS_((Tcl_Interp *interp,
! int port, CONST char *host, CONST char *myAddr,
! int myPort, int server, int async));
! static pascal void DNRCompletionRoutine _ANSI_ARGS_((
! struct hostInfo *hostinfoPtr,
! DNRState *dnrStatePtr));
! static void FreeSocketInfo _ANSI_ARGS_((TcpState *statePtr));
! static long GetBufferSize _ANSI_ARGS_((void));
! static OSErr GetHostFromString _ANSI_ARGS_((CONST char *name,
! ip_addr *address));
! static OSErr GetLocalAddress _ANSI_ARGS_((unsigned long *addr));
! static void IOCompletionRoutine _ANSI_ARGS_((TCPiopb *pb));
! static void InitMacTCPParamBlock _ANSI_ARGS_((TCPiopb *pBlock,
! int csCode));
! static void InitSockets _ANSI_ARGS_((void));
! static TcpState * NewSocketInfo _ANSI_ARGS_((StreamPtr stream));
! static OSErr ResolveAddress _ANSI_ARGS_((ip_addr tcpAddress,
! Tcl_DString *dsPtr));
! static void SocketCheckProc _ANSI_ARGS_((ClientData clientData,
! int flags));
! static int SocketEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
! int flags));
! static void SocketExitHandler _ANSI_ARGS_((ClientData clientData));
! static void SocketFreeProc _ANSI_ARGS_((ClientData clientData));
! static int SocketReady _ANSI_ARGS_((TcpState *statePtr));
! static void SocketSetupProc _ANSI_ARGS_((ClientData clientData,
! int flags));
! static void TcpAccept _ANSI_ARGS_((TcpState *statePtr));
! static int TcpBlockMode _ANSI_ARGS_((ClientData instanceData, int mode));
! static int TcpClose _ANSI_ARGS_((ClientData instanceData,
! Tcl_Interp *interp));
! static int TcpGetHandle _ANSI_ARGS_((ClientData instanceData,
! int direction, ClientData *handlePtr));
! static int TcpGetOptionProc _ANSI_ARGS_((ClientData instanceData,
! Tcl_Interp *interp, CONST char *optionName,
! Tcl_DString *dsPtr));
! static int TcpInput _ANSI_ARGS_((ClientData instanceData,
! char *buf, int toRead, int *errorCodePtr));
! static int TcpOutput _ANSI_ARGS_((ClientData instanceData,
! CONST char *buf, int toWrite, int *errorCodePtr));
! static void TcpWatch _ANSI_ARGS_((ClientData instanceData,
! int mask));
! static int WaitForSocketEvent _ANSI_ARGS_((TcpState *infoPtr,
! int mask, int *errorCodePtr));
pascal void NotifyRoutine (
StreamPtr tcpStream,
--- 130,201 ----
StreamPtr tcpStream; /* Low level Macintosh stream. */
} SocketEvent;
+ typedef struct ThreadSpecificData {
+ /*
+ * Every open socket has an entry on the following list.
+ */
+
+ TcpState *socketList;
+ } ThreadSpecificData;
+
+ static Tcl_ThreadDataKey dataKey;
+
/*
* Static routines for this file:
*/
! static pascal void CleanUpExitProc _ANSI_ARGS_((void));
! static void ClearZombieSockets _ANSI_ARGS_((void));
! static void CloseCompletionRoutine _ANSI_ARGS_((
! TCPiopb *pb));
! static TcpState * CreateSocket _ANSI_ARGS_((
! Tcl_Interp *interp, int port,
! CONST char *host, CONST char *myAddr,
! int myPort, int server, int async));
! static pascal void DNRCompletionRoutine _ANSI_ARGS_((
! struct hostInfo *hostinfoPtr,
! DNRState *dnrStatePtr));
! static void FreeSocketInfo _ANSI_ARGS_((
! TcpState *statePtr));
! static long GetBufferSize _ANSI_ARGS_((void));
! static OSErr GetHostFromString _ANSI_ARGS_((
! CONST char *name, ip_addr *address));
! static OSErr GetLocalAddress _ANSI_ARGS_((
! unsigned long *addr));
! static void IOCompletionRoutine _ANSI_ARGS_((
! TCPiopb *pb));
! static void InitMacTCPParamBlock _ANSI_ARGS_((
! TCPiopb *pBlock, int csCode));
! static ThreadSpecificData * InitSockets _ANSI_ARGS_((void));
! static TcpState * NewSocketInfo _ANSI_ARGS_((
! StreamPtr stream));
! static OSErr ResolveAddress _ANSI_ARGS_((
! ip_addr tcpAddress,
! Tcl_DString *dsPtr));
! static Tcl_EventCheckProc SocketCheckProc;
! static Tcl_EventProc SocketEventProc;
! static Tcl_ExitProc SocketExitHandler;
! static void SocketFreeProc _ANSI_ARGS_((
! ClientData clientData));
! static int SocketReady _ANSI_ARGS_((
! TcpState *statePtr));
! static void SocketSetupProc _ANSI_ARGS_((
! ClientData clientData, int flags));
! static void TcpAccept _ANSI_ARGS_((
! TcpState *statePtr));
! static Tcl_DriverBlockModeProc TcpBlockMode;
! static Tcl_DriverCloseProc TcpClose;
! static Tcl_DriverCutProc TcpCutProc;
! static Tcl_DriverGetHandleProc TcpGetHandle;
! static Tcl_DriverGetOptionProc TcpGetOptionProc;
! static Tcl_DriverInputProc TcpInput;
! static Tcl_DriverOutputProc TcpOutput;
! static Tcl_DriverSpliceProc TcpSpliceProc;
! static Tcl_DriverWatchProc TcpWatch;
!
! static int WaitForSocketEvent _ANSI_ARGS_((
! TcpState *infoPtr, int mask,
! int *errorCodePtr));
pascal void NotifyRoutine (
StreamPtr tcpStream,
***************
*** 196,203 ****
static Tcl_ChannelType tcpChannelType = {
"tcp", /* Type name. */
! (Tcl_ChannelTypeVersion)TcpBlockMode, /* Set blocking or
! * non-blocking mode.*/
TcpClose, /* Close proc. */
TcpInput, /* Input proc. */
TcpOutput, /* Output proc. */
--- 211,217 ----
static Tcl_ChannelType tcpChannelType = {
"tcp", /* Type name. */
! TCL_CHANNEL_VERSION_4,
TcpClose, /* Close proc. */
TcpInput, /* Input proc. */
TcpOutput, /* Output proc. */
***************
*** 205,211 ****
NULL, /* Set option proc. */
TcpGetOptionProc, /* Get option proc. */
TcpWatch, /* Initialize notifier. */
! TcpGetHandle /* Get handles out of channel. */
};
/*
--- 219,232 ----
NULL, /* Set option proc. */
TcpGetOptionProc, /* Get option proc. */
TcpWatch, /* Initialize notifier. */
! TcpGetHandle, /* Get handles out of channel. */
! NULL, /* close2 proc. */
! TcpBlockMode, /* Set blocking or non-blocking mode.*/
! NULL, /* flush proc. */
! NULL, /* handler proc. */
! NULL, /* wide seek proc. */
! TcpCutProc, /* cut proc. */
! TcpSpliceProc, /* splice proc. */
};
/*
***************
*** 251,266 ****
{NULL, 0},
};
- typedef struct ThreadSpecificData {
- /*
- * Every open socket has an entry on the following list.
- */
-
- TcpState *socketList;
- } ThreadSpecificData;
-
- static Tcl_ThreadDataKey dataKey;
-
/*
* Globals for holding information about OS support for sockets.
*/
--- 272,277 ----
***************
*** 293,299 ****
*/
#define gestaltMacTCPVersion 'mtcp'
! static void
InitSockets()
{
ParamBlockRec pb;
--- 304,310 ----
*/
#define gestaltMacTCPVersion 'mtcp'
! static ThreadSpecificData *
InitSockets()
{
ParamBlockRec pb;
***************
*** 371,376 ****
--- 382,388 ----
Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL);
Tcl_CreateThreadExitHandler(SocketExitHandler, (ClientData) NULL);
}
+ return tsdPtr;
}
/*
***************
*** 460,466 ****
{
TcpState *statePtr;
Tcl_Time blockTime = { 0, 0 };
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
--- 472,480 ----
{
TcpState *statePtr;
Tcl_Time blockTime = { 0, 0 };
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = InitSockets();
if (!(flags & TCL_FILE_EVENTS)) {
return;
***************
*** 507,513 ****
TcpState *statePtr;
SocketEvent *evPtr;
TcpState dummyState;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
--- 521,529 ----
TcpState *statePtr;
SocketEvent *evPtr;
TcpState dummyState;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = InitSockets();
if (!(flags & TCL_FILE_EVENTS)) {
return;
***************
*** 869,875 ****
}
/*
! * It's very bad if the statePtr is nNULL - we should probably panic...
*/
if (statePtr == NULL) {
--- 885,891 ----
}
/*
! * It's very bad if the statePtr is NULL - we should probably panic...
*/
if (statePtr == NULL) {
***************
*** 1096,1102 ****
switch (err) {
case noErr:
/*
! * The channel remains readable only if this read succeds
* and we had more data then the size of the buffer we were
* trying to fill. Use the info from the call to status to
* determine this.
--- 1112,1118 ----
switch (err) {
case noErr:
/*
! * The channel remains readable only if this read succeeds
* and we had more data then the size of the buffer we were
* trying to fill. Use the info from the call to status to
* determine this.
***************
*** 1542,1547 ****
--- 1558,1640 ----
/*
*----------------------------------------------------------------------
*
+ * TcpCutProc --
+ *
+ * Driver procedure to remove any thread local refs to this
+ * channel. See Tcl_CutChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ TcpCutProc(instanceData)
+ ClientData instanceData; /* Socket state. */
+ {
+ ThreadSpecificData *tsdPtr;
+ TcpState *infoPtr = (TcpState *) instanceData;
+ TcpState **nextPtrPtr;
+ int removed = 0;
+
+ tsdPtr = InitSockets();
+
+ for (nextPtrPtr = &(tsdPtr->socketList); (*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("TcpState info ptr not on thread channel list");
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
+ * TcpSpliceProc --
+ *
+ * Driver procedure to insert thread local ref for this channel.
+ * See Tcl_SpliceChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ TcpSpliceProc(instanceData)
+ ClientData instanceData; /* Socket state. */
+ {
+ ThreadSpecificData *tsdPtr;
+ TcpState *infoPtr = (TcpState *) instanceData;
+
+ tsdPtr = InitSockets();
+
+ infoPtr->nextPtr = tsdPtr->socketList;
+ tsdPtr->socketList = infoPtr;
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
* NewSocketInfo --
*
* This function allocates and initializes a new SocketInfo
***************
*** 1561,1567 ****
StreamPtr tcpStream)
{
TcpState *statePtr;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState));
statePtr->tcpStream = tcpStream;
--- 1654,1662 ----
StreamPtr tcpStream)
{
TcpState *statePtr;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = InitSockets();
statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState));
statePtr->tcpStream = tcpStream;
***************
*** 1599,1605 ****
FreeSocketInfo(
TcpState *statePtr) /* The state pointer to free. */
{
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (statePtr == tsdPtr->socketList) {
tsdPtr->socketList = statePtr->nextPtr;
--- 1694,1702 ----
FreeSocketInfo(
TcpState *statePtr) /* The state pointer to free. */
{
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = InitSockets();
if (statePtr == tsdPtr->socketList) {
tsdPtr->socketList = statePtr->nextPtr;
***************
*** 1987,1993 ****
TcpState *statePtr;
SocketEvent *eventPtr = (SocketEvent *) evPtr;
int mask = 0;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return 0;
--- 2084,2092 ----
TcpState *statePtr;
SocketEvent *eventPtr = (SocketEvent *) evPtr;
int mask = 0;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = InitSockets();
if (!(flags & TCL_FILE_EVENTS)) {
return 0;
***************
*** 2743,2749 ****
ClearZombieSockets()
{
TcpState *statePtr;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
for (statePtr = tsdPtr->socketList; statePtr != NULL;
statePtr = statePtr->nextPtr) {
--- 2842,2850 ----
ClearZombieSockets()
{
TcpState *statePtr;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = InitSockets();
for (statePtr = tsdPtr->socketList; statePtr != NULL;
statePtr = statePtr->nextPtr) {
***************
*** 2790,2881 ****
localIcmpMsg = *icmpMsg;
}
-
- /*
- *----------------------------------------------------------------------
- *
- * TclpCutSockChannel --
- *
- * Remove any thread local refs to this channel. See
- * Tcl_CutChannel for more info.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Changes thread local list of valid channels.
- *
- *----------------------------------------------------------------------
- */
-
- void
- TclpCutSockChannel(chan)
- Tcl_Channel chan;
- {
- ThreadSpecificData *tsdPtr;
- TcpState *infoPtr;
- TcpState **nextPtrPtr;
- int removed = 0;
-
- if (Tcl_GetChannelType(chan) != &tcpChannelType)
- return;
-
- tsdPtr = TCL_TSD_INIT(&dataKey);
- infoPtr = (TcpState *) Tcl_GetChannelInstanceData (chan);
-
- for (nextPtrPtr = &(tsdPtr->socketList); (*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");
- return;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TclpSpliceSockChannel --
- *
- * Insert thread local ref for this channel.
- * Tcl_SpliceChannel for more info.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Changes thread local list of valid channels.
- *
- *----------------------------------------------------------------------
- */
-
- void
- TclpSpliceSockChannel(chan)
- Tcl_Channel chan;
- {
- ThreadSpecificData *tsdPtr;
- TcpState *infoPtr;
-
- if (Tcl_GetChannelType(chan) != &tcpChannelType)
- return;
-
- InitSockets ();
-
- tsdPtr = TCL_TSD_INIT(&dataKey);
- infoPtr = (TcpState *) Tcl_GetChannelInstanceData (chan);
-
- infoPtr->nextPtr = tsdPtr->socketList;
- tsdPtr->socketList = infoPtr;
- }
-
--- 2891,2893 ----
*** unix/tclUnixChan.c 24 Dec 2003 04:18:22 -0000 1.45
--- unix/tclUnixChan.c 14 Jan 2004 02:18:37 -0000
***************
*** 231,302 ****
* Static routines for this file:
*/
! static TcpState * CreateSocket _ANSI_ARGS_((Tcl_Interp *interp,
! int port, CONST char *host, int server,
! CONST char *myaddr, int myport, int async));
! static int CreateSocketAddress _ANSI_ARGS_(
! (struct sockaddr_in *sockaddrPtr,
! CONST char *host, int port));
! static int FileBlockModeProc _ANSI_ARGS_((
! ClientData instanceData, int mode));
! static int FileCloseProc _ANSI_ARGS_((ClientData instanceData,
! Tcl_Interp *interp));
! static int FileGetHandleProc _ANSI_ARGS_((ClientData instanceData,
! int direction, ClientData *handlePtr));
! static int FileInputProc _ANSI_ARGS_((ClientData instanceData,
! char *buf, int toRead, int *errorCode));
! static int FileOutputProc _ANSI_ARGS_((
! ClientData instanceData, CONST char *buf,
! int toWrite, int *errorCode));
! static int FileSeekProc _ANSI_ARGS_((ClientData instanceData,
! long offset, int mode, int *errorCode));
! static Tcl_WideInt FileWideSeekProc _ANSI_ARGS_((ClientData instanceData,
! Tcl_WideInt offset, int mode, int *errorCode));
! static void FileWatchProc _ANSI_ARGS_((ClientData instanceData,
! int mask));
! static void TcpAccept _ANSI_ARGS_((ClientData data, int mask));
! static int TcpBlockModeProc _ANSI_ARGS_((ClientData data,
! int mode));
! static int TcpCloseProc _ANSI_ARGS_((ClientData instanceData,
! Tcl_Interp *interp));
! static int TcpGetHandleProc _ANSI_ARGS_((ClientData instanceData,
! int direction, ClientData *handlePtr));
! static int TcpGetOptionProc _ANSI_ARGS_((ClientData instanceData,
! Tcl_Interp *interp, CONST char *optionName,
! Tcl_DString *dsPtr));
! static int TcpInputProc _ANSI_ARGS_((ClientData instanceData,
! char *buf, int toRead, int *errorCode));
! static int TcpOutputProc _ANSI_ARGS_((ClientData instanceData,
! CONST char *buf, int toWrite, int *errorCode));
! static void TcpWatchProc _ANSI_ARGS_((ClientData instanceData,
! int mask));
#ifdef SUPPORTS_TTY
! static int TtyCloseProc _ANSI_ARGS_((ClientData instanceData,
! Tcl_Interp *interp));
! static void TtyGetAttributes _ANSI_ARGS_((int fd,
! TtyAttrs *ttyPtr));
! static int TtyGetOptionProc _ANSI_ARGS_((ClientData instanceData,
! Tcl_Interp *interp, CONST char *optionName,
! Tcl_DString *dsPtr));
! static FileState * TtyInit _ANSI_ARGS_((int fd, int initialize));
#if BAD_TIP35_FLUSH
! static int TtyOutputProc _ANSI_ARGS_((ClientData instanceData,
! CONST char *buf, int toWrite, int *errorCode));
#endif /* BAD_TIP35_FLUSH */
! static int TtyParseMode _ANSI_ARGS_((Tcl_Interp *interp,
! CONST char *mode, int *speedPtr, int *parityPtr,
! int *dataPtr, int *stopPtr));
! static void TtySetAttributes _ANSI_ARGS_((int fd,
! TtyAttrs *ttyPtr));
! static int TtySetOptionProc _ANSI_ARGS_((ClientData instanceData,
! Tcl_Interp *interp, CONST char *optionName,
! CONST char *value));
#endif /* SUPPORTS_TTY */
! static int WaitForConnect _ANSI_ARGS_((TcpState *statePtr,
! int *errorCodePtr));
! static Tcl_Channel MakeTcpClientChannelMode _ANSI_ARGS_(
! (ClientData tcpSocket,
! int mode));
/*
--- 231,286 ----
* Static routines for this file:
*/
! static TcpState * CreateSocket _ANSI_ARGS_((
! Tcl_Interp *interp, int port,
! CONST char *host, int server,
! CONST char *myaddr, int myport,
! int async));
! static int CreateSocketAddress _ANSI_ARGS_(
! (struct sockaddr_in *sockaddrPtr,
! CONST char *host, int port));
! static Tcl_DriverBlockModeProc FileBlockModeProc;
! static Tcl_DriverCloseProc FileCloseProc;
! static Tcl_DriverCutProc FileCutProc;
! static Tcl_DriverGetHandleProc FileGetHandleProc;
! static Tcl_DriverInputProc FileInputProc;
! static Tcl_DriverOutputProc FileOutputProc);
! static Tcl_DriverSeekProc FileSeekProc;
! static Tcl_DriverSpliceProc FileSpliceProc;
! static Tcl_DriverWideSeekProc FileWideSeekProc;
! static Tcl_DriverWatchProc FileWatchProc;
! static void TcpAccept _ANSI_ARGS_((ClientData data,
! int mask));
! static Tcl_DriverBlockModeProc TcpBlockModeProc;
! static Tcl_DriverCloseProc TcpCloseProc;
! static Tcl_DriverGetHandleProc TcpGetHandleProc;
! static Tcl_DriverGetOptionProc TcpGetOptionProc;
! static Tcl_DriverInputProc TcpInputProc;
! static Tcl_DriverOutputProc TcpOutputProc;
! static Tcl_DriverWatchProc TcpWatchProc;
#ifdef SUPPORTS_TTY
! static Tcl_DriverCloseProc TtyCloseProc;
! static void TtyGetAttributes _ANSI_ARGS_((int fd,
! TtyAttrs *ttyPtr));
! static Tcl_DriverGetOptionProc TtyGetOptionProc;
! static FileState * TtyInit _ANSI_ARGS_((int fd,
! int initialize));
#if BAD_TIP35_FLUSH
! static Tcl_DriverOutputProc TtyOutputProc;
#endif /* BAD_TIP35_FLUSH */
! static int TtyParseMode _ANSI_ARGS_((
! Tcl_Interp *interp, CONST char *mode,
! int *speedPtr, int *parityPtr,
! int *dataPtr, int *stopPtr));
! static void TtySetAttributes _ANSI_ARGS_((int fd,
! TtyAttrs *ttyPtr));
! static Tcl_DriverSetOptionProc TtySetOptionProc;
#endif /* SUPPORTS_TTY */
! static int WaitForConnect _ANSI_ARGS_((
! TcpState *statePtr,
! int *errorCodePtr));
! static Tcl_Channel MakeTcpClientChannelMode _ANSI_ARGS_((
! ClientData tcpSocket, int mode));
/*
***************
*** 305,311 ****
static Tcl_ChannelType fileChannelType = {
"file", /* Type name. */
! TCL_CHANNEL_VERSION_3, /* v3 channel */
FileCloseProc, /* Close proc. */
FileInputProc, /* Input proc. */
FileOutputProc, /* Output proc. */
--- 289,295 ----
static Tcl_ChannelType fileChannelType = {
"file", /* Type name. */
! TCL_CHANNEL_VERSION_4, /* v4 channel */
FileCloseProc, /* Close proc. */
FileInputProc, /* Input proc. */
FileOutputProc, /* Output proc. */
***************
*** 319,324 ****
--- 303,310 ----
NULL, /* flush proc. */
NULL, /* handler proc. */
FileWideSeekProc, /* wide seek proc. */
+ FileCutProc, /* cut proc. */
+ FileSpliceProc, /* splice proc. */
};
#ifdef SUPPORTS_TTY
***************
*** 735,740 ****
--- 721,805 ----
return TCL_ERROR;
}
}
+
+ /*
+ *----------------------------------------------------------------------
+ *
+ * FileCutProc --
+ *
+ * Driver procedure to remove any thread local refs to this
+ * channel. See Tcl_CutChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ FileCutProc(instanceData)
+ ClientData instanceData; /* The file state. */
+ {
+ #ifdef DEPRECATED
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ FileState *fsPtr = (FileState *) instanceData;;
+ 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("FileState ptr not on thread channel list");
+ }
+
+ #endif /* DEPRECATED */
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
+ * FileSpliceProc --
+ *
+ * Driver procedure to insert thread local ref for this channel.
+ * Tcl_SpliceChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ FileSpliceProc(instanceData)
+ ClientData instanceData; /* The file state. */
+ {
+ #ifdef DEPRECATED
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ FileState *fsPtr = (FileState *) instanceData;
+
+ fsPtr->nextPtr = tsdPtr->firstFilePtr;
+ tsdPtr->firstFilePtr = fsPtr;
+ #endif /* DEPRECATED */
+ }
#ifdef SUPPORTS_TTY
***************
*** 3272,3369 ****
}
return result;
}
-
- /*
- *----------------------------------------------------------------------
- *
- * TclpCutFileChannel --
- *
- * Remove any thread local refs to this channel. See
- * Tcl_CutChannel for more info.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Changes thread local list of valid channels.
- *
- *----------------------------------------------------------------------
- */
-
- void
- TclpCutFileChannel(chan)
- Tcl_Channel chan; /* The channel being removed. Must
- * not be referenced in any
- * interpreter. */
- {
- #ifdef DEPRECATED
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- Channel *chanPtr = (Channel *) chan;
- FileState *fsPtr;
- FileState **nextPtrPtr;
- int removed = 0;
-
- if (chanPtr->typePtr != &fileChannelType)
- return;
-
- fsPtr = (FileState *) chanPtr->instanceData;
-
- 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 /* DEPRECATED */
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TclpSpliceFileChannel --
- *
- * Insert thread local ref for this channel.
- * 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. */
- {
- #ifdef DEPRECATED
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- Channel *chanPtr = (Channel *) chan;
- FileState *fsPtr;
-
- if (chanPtr->typePtr != &fileChannelType)
- return;
-
- fsPtr = (FileState *) chanPtr->instanceData;
-
- fsPtr->nextPtr = tsdPtr->firstFilePtr;
- tsdPtr->firstFilePtr = fsPtr;
- #endif /* DEPRECATED */
- }
--- 3337,3339 ----
*** unix/tclUnixSock.c 22 Apr 2003 23:20:43 -0000 1.7
--- unix/tclUnixSock.c 14 Jan 2004 02:18:39 -0000
***************
*** 148,196 ****
{
return TCL_OK;
}
-
- /*
- *----------------------------------------------------------------------
- *
- * TclpCutSockChannel --
- *
- * Remove any thread local refs to this channel. See
- * Tcl_CutChannel for more info. Dummy definition.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- void
- TclpCutSockChannel(chan)
- Tcl_Channel chan;
- {
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TclpSpliceSockChannel --
- *
- * Insert thread local ref for this channel.
- * Tcl_SpliceChannel for more info. Dummy definition.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- void
- TclpSpliceSockChannel(chan)
- Tcl_Channel chan;
- {
- }
--- 148,150 ----
*** win/tclWinChan.c 24 Dec 2003 04:18:22 -0000 1.33
--- win/tclWinChan.c 14 Jan 2004 02:18:41 -0000
***************
*** 73,103 ****
* Static routines for this file:
*/
! static int FileBlockProc _ANSI_ARGS_((ClientData instanceData,
! int mode));
! static void FileChannelExitHandler _ANSI_ARGS_((
! ClientData clientData));
! static void FileCheckProc _ANSI_ARGS_((ClientData clientData,
! int flags));
! static int FileCloseProc _ANSI_ARGS_((ClientData instanceData,
! Tcl_Interp *interp));
! static int FileEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
! int flags));
! static int FileGetHandleProc _ANSI_ARGS_((ClientData instanceData,
! int direction, ClientData *handlePtr));
! static ThreadSpecificData *FileInit _ANSI_ARGS_((void));
! static int FileInputProc _ANSI_ARGS_((ClientData instanceData,
! char *buf, int toRead, int *errorCode));
! static int FileOutputProc _ANSI_ARGS_((ClientData instanceData,
! CONST char *buf, int toWrite, int *errorCode));
! static int FileSeekProc _ANSI_ARGS_((ClientData instanceData,
! long offset, int mode, int *errorCode));
! static Tcl_WideInt FileWideSeekProc _ANSI_ARGS_((ClientData instanceData,
! Tcl_WideInt offset, int mode, int *errorCode));
! static void FileSetupProc _ANSI_ARGS_((ClientData clientData,
! int flags));
! static void FileWatchProc _ANSI_ARGS_((ClientData instanceData,
! int mask));
/*
--- 73,93 ----
* Static routines for this file:
*/
! static Tcl_DriverBlockModeProc FileBlockProc;
! static Tcl_ExitProc FileChannelExitHandler;
! static Tcl_EventCheckProc FileCheckProc;
! static Tcl_DriverCloseProc FileCloseProc;
! static Tcl_DriverCutProc FileCutProc;
! static Tcl_EventProc FileEventProc;
! static Tcl_DriverGetHandleProc FileGetHandleProc;
! static ThreadSpecificData * FileInit _ANSI_ARGS_((void));
! static Tcl_DriverInputProc FileInputProc;
! static Tcl_DriverOutputProc FileOutputProc;
! static Tcl_DriverSeekProc FileSeekProc;
! static Tcl_DriverWideSeekProc FileWideSeekProc;
! static Tcl_EventSetupProc FileSetupProc;
! static Tcl_DriverSpliceProc FileSpliceProc;
! static Tcl_DriverWatchProc FileWatchProc;
/*
***************
*** 106,112 ****
static Tcl_ChannelType fileChannelType = {
"file", /* Type name. */
! TCL_CHANNEL_VERSION_3, /* v3 channel */
FileCloseProc, /* Close proc. */
FileInputProc, /* Input proc. */
FileOutputProc, /* Output proc. */
--- 96,102 ----
static Tcl_ChannelType fileChannelType = {
"file", /* Type name. */
! TCL_CHANNEL_VERSION_4, /* v4 channel */
FileCloseProc, /* Close proc. */
FileInputProc, /* Input proc. */
FileOutputProc, /* Output proc. */
***************
*** 120,125 ****
--- 110,117 ----
NULL, /* flush proc. */
NULL, /* handler proc. */
FileWideSeekProc, /* Wide seek proc. */
+ FileCutProc, /* cut proc. */
+ FileSpliceProc, /* splice proc. */
};
#if defined(HAVE_NO_SEH) && defined(TCL_MEM_DEBUG)
***************
*** 181,187 ****
static void
FileChannelExitHandler(clientData)
! ClientData clientData; /* Old window proc */
{
Tcl_DeleteEventSource(FileSetupProc, FileCheckProc, NULL);
}
--- 173,179 ----
static void
FileChannelExitHandler(clientData)
! ClientData clientData; /* Not used. */
{
Tcl_DeleteEventSource(FileSetupProc, FileCheckProc, NULL);
}
***************
*** 210,216 ****
{
FileInfo *infoPtr;
Tcl_Time blockTime = { 0, 0 };
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
--- 202,210 ----
{
FileInfo *infoPtr;
Tcl_Time blockTime = { 0, 0 };
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = FileInit();
if (!(flags & TCL_FILE_EVENTS)) {
return;
***************
*** 253,259 ****
{
FileEvent *evPtr;
FileInfo *infoPtr;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
--- 247,255 ----
{
FileEvent *evPtr;
FileInfo *infoPtr;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = FileInit();
if (!(flags & TCL_FILE_EVENTS)) {
return;
***************
*** 305,311 ****
{
FileEvent *fileEvPtr = (FileEvent *)evPtr;
FileInfo *infoPtr;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return 0;
--- 301,309 ----
{
FileEvent *fileEvPtr = (FileEvent *)evPtr;
FileInfo *infoPtr;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = FileInit();
if (!(flags & TCL_FILE_EVENTS)) {
return 0;
***************
*** 720,733 ****
return TCL_ERROR;
}
}
/*
*----------------------------------------------------------------------
*
* TclpOpenFileChannel --
*
! * Open an File based channel on Unix systems.
*
* Results:
* The new channel or NULL. If NULL, the output argument
--- 718,808 ----
return TCL_ERROR;
}
}
+
+ /*
+ *----------------------------------------------------------------------
+ *
+ * FileCutProc --
+ *
+ * Driver procedure to remove any thread local refs to this
+ * channel. See Tcl_CutChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ FileCutProc(instanceData)
+ ClientData instanceData; /* The file state. */
+ {
+ ThreadSpecificData *tsdPtr;
+ FileInfo *infoPtr = (FileInfo *) instanceData;
+ FileInfo **nextPtrPtr;
+ int removed = 0;
+
+ tsdPtr = FileInit();
+
+ 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");
+ }
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
+ * FileSpliceProc --
+ *
+ * Insert thread local ref for this channel.
+ * Tcl_SpliceChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ FileSpliceProc(instanceData)
+ ClientData instanceData; /* The file state. */
+ {
+ ThreadSpecificData *tsdPtr;
+ FileInfo *infoPtr = (FileInfo *) instanceData;
+ tsdPtr = FileInit();
+
+ infoPtr->nextPtr = tsdPtr->firstFilePtr;
+ tsdPtr->firstFilePtr = infoPtr;
+ }
/*
*----------------------------------------------------------------------
*
* TclpOpenFileChannel --
*
! * Open a file based channel on Win32 systems.
*
* Results:
* The new channel or NULL. If NULL, the output argument
***************
*** 1338,1430 ****
}
}
}
-
- /*
- *----------------------------------------------------------------------
- *
- * TclpCutFileChannel --
- *
- * Remove any thread local refs to this channel. See
- * Tcl_CutChannel for more info.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Changes thread local list of valid channels.
- *
- *----------------------------------------------------------------------
- */
-
- void
- TclpCutFileChannel(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;
- FileInfo **nextPtrPtr;
- int removed = 0;
-
- if (chanPtr->typePtr != &fileChannelType)
- return;
-
- infoPtr = (FileInfo *) chanPtr->instanceData;
-
- 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.
- * 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;
-
- if (chanPtr->typePtr != &fileChannelType)
- return;
-
- infoPtr = (FileInfo *) chanPtr->instanceData;
-
- infoPtr->nextPtr = tsdPtr->firstFilePtr;
- tsdPtr->firstFilePtr = infoPtr;
- }
--- 1413,1415 ----
*** win/tclWinConsole.c 26 Nov 2002 22:41:58 -0000 1.11
--- win/tclWinConsole.c 14 Jan 2004 02:18:43 -0000
***************
*** 140,164 ****
* Declarations for functions used only in this file.
*/
! static int ConsoleBlockModeProc(ClientData instanceData, int mode);
! static void ConsoleCheckProc(ClientData clientData, int flags);
! static int ConsoleCloseProc(ClientData instanceData,
! Tcl_Interp *interp);
! static int ConsoleEventProc(Tcl_Event *evPtr, int flags);
! static void ConsoleExitHandler(ClientData clientData);
! static int ConsoleGetHandleProc(ClientData instanceData,
! int direction, ClientData *handlePtr);
! static ThreadSpecificData *ConsoleInit(void);
! static int ConsoleInputProc(ClientData instanceData, char *buf,
! int toRead, int *errorCode);
! static int ConsoleOutputProc(ClientData instanceData,
! CONST char *buf, int toWrite, int *errorCode);
! static DWORD WINAPI ConsoleReaderThread(LPVOID arg);
! static void ConsoleSetupProc(ClientData clientData, int flags);
! static void ConsoleWatchProc(ClientData instanceData, int mask);
! static DWORD WINAPI ConsoleWriterThread(LPVOID arg);
! static void ProcExitHandler(ClientData clientData);
! static int WaitForRead(ConsoleInfo *infoPtr, int blocking);
/*
* This structure describes the channel type structure for command console
--- 140,163 ----
* Declarations for functions used only in this file.
*/
! static Tcl_DriverBlockModeProc ConsoleBlockModeProc;
! static Tcl_EventCheckProc ConsoleCheckProc;
! static Tcl_DriverCloseProc ConsoleCloseProc;
! static Tcl_DriverCutProc ConsoleCutProc;
! static Tcl_EventProc ConsoleEventProc;
! static Tcl_ExitProc ConsoleExitHandler;
! static Tcl_DriverGetHandleProc ConsoleGetHandleProc;
! static ThreadSpecificData * ConsoleInit(void);
! static Tcl_DriverInputProc ConsoleInputProc;
! static Tcl_DriverOutputProc ConsoleOutputProc;
! static DWORD WINAPI ConsoleReaderThread(LPVOID arg);
! static Tcl_EventSetupProc ConsoleSetupProc;
! static Tcl_DriverSpliceProc ConsoleSpliceProc;
! static Tcl_DriverWatchProc ConsoleWatchProc;
! static DWORD WINAPI ConsoleWriterThread(LPVOID arg);
! static Tcl_ExitProc ProcExitHandler;
! static int WaitForRead(ConsoleInfo *infoPtr,
! int blocking);
/*
* This structure describes the channel type structure for command console
***************
*** 167,173 ****
static Tcl_ChannelType consoleChannelType = {
"console", /* Type name. */
! TCL_CHANNEL_VERSION_2, /* v2 channel */
ConsoleCloseProc, /* Close proc. */
ConsoleInputProc, /* Input proc. */
ConsoleOutputProc, /* Output proc. */
--- 166,172 ----
static Tcl_ChannelType consoleChannelType = {
"console", /* Type name. */
! TCL_CHANNEL_VERSION_4, /* v4 channel */
ConsoleCloseProc, /* Close proc. */
ConsoleInputProc, /* Input proc. */
ConsoleOutputProc, /* Output proc. */
***************
*** 180,185 ****
--- 179,187 ----
ConsoleBlockModeProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
+ NULL, /* wide seek proc. */
+ ConsoleCutProc, /* cut proc. */
+ ConsoleSpliceProc, /* splice proc. */
};
/*
***************
*** 246,252 ****
static void
ConsoleExitHandler(
! ClientData clientData) /* Old window proc */
{
Tcl_DeleteEventSource(ConsoleSetupProc, ConsoleCheckProc, NULL);
}
--- 248,254 ----
static void
ConsoleExitHandler(
! ClientData clientData) /* Not used. */
{
Tcl_DeleteEventSource(ConsoleSetupProc, ConsoleCheckProc, NULL);
}
***************
*** 270,276 ****
static void
ProcExitHandler(
! ClientData clientData) /* Old window proc */
{
Tcl_MutexLock(&consoleMutex);
initialized = 0;
--- 272,278 ----
static void
ProcExitHandler(
! ClientData clientData) /* Not used. */
{
Tcl_MutexLock(&consoleMutex);
initialized = 0;
***************
*** 302,308 ****
ConsoleInfo *infoPtr;
Tcl_Time blockTime = { 0, 0 };
int block = 1;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
--- 304,312 ----
ConsoleInfo *infoPtr;
Tcl_Time blockTime = { 0, 0 };
int block = 1;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = ConsoleInit();
if (!(flags & TCL_FILE_EVENTS)) {
return;
***************
*** 355,361 ****
ConsoleInfo *infoPtr;
ConsoleEvent *evPtr;
int needEvent;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
--- 359,367 ----
ConsoleInfo *infoPtr;
ConsoleEvent *evPtr;
int needEvent;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = ConsoleInit();
if (!(flags & TCL_FILE_EVENTS)) {
return;
***************
*** 463,479 ****
ConsoleInfo *consolePtr = (ConsoleInfo *) instanceData;
int errorCode;
ConsoleInfo *infoPtr, **nextPtrPtr;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
DWORD exitCode;
errorCode = 0;
!
/*
* Clean up the background thread if necessary. Note that this
* must be done before we can close the file, since the
* thread may be blocking trying to read from the console.
*/
!
if (consolePtr->readThread) {
/*
--- 469,486 ----
ConsoleInfo *consolePtr = (ConsoleInfo *) instanceData;
int errorCode;
ConsoleInfo *infoPtr, **nextPtrPtr;
! ThreadSpecificData *tsdPtr;
DWORD exitCode;
errorCode = 0;
! tsdPtr = ConsoleInit();
!
/*
* Clean up the background thread if necessary. Note that this
* must be done before we can close the file, since the
* thread may be blocking trying to read from the console.
*/
!
if (consolePtr->readThread) {
/*
***************
*** 832,838 ****
ConsoleEvent *consoleEvPtr = (ConsoleEvent *)evPtr;
ConsoleInfo *infoPtr;
int mask;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return 0;
--- 839,847 ----
ConsoleEvent *consoleEvPtr = (ConsoleEvent *)evPtr;
ConsoleInfo *infoPtr;
int mask;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = ConsoleInit();
if (!(flags & TCL_FILE_EVENTS)) {
return 0;
***************
*** 919,925 ****
ConsoleInfo **nextPtrPtr, *ptr;
ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
int oldMask = infoPtr->watchMask;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
* Since most of the work is handled by the background threads,
--- 928,936 ----
ConsoleInfo **nextPtrPtr, *ptr;
ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
int oldMask = infoPtr->watchMask;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = ConsoleInit();
/*
* Since most of the work is handled by the background threads,
***************
*** 986,991 ****
--- 997,1080 ----
/*
*----------------------------------------------------------------------
*
+ * ConsoleCutProc --
+ *
+ * Driver procedure to remove any thread local refs to this
+ * channel. See Tcl_CutChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ ConsoleCutProc(instanceData)
+ ClientData instanceData; /* Console state. */
+ {
+ ThreadSpecificData *tsdPtr;
+ ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
+ ConsoleInfo **nextPtrPtr;
+ int removed = 0;
+
+ tsdPtr = ConsoleInit();
+
+ for (nextPtrPtr = &(tsdPtr->firstConsolePtr); (*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("ConsoleInfo ptr not on thread channel list");
+ }
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
+ * ConsoleSpliceProc --
+ *
+ * Driver procedure to insert thread local ref for this channel.
+ * See Tcl_SpliceChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ ConsoleSpliceProc(instanceData)
+ ClientData instanceData; /* Console state. */
+ {
+ ThreadSpecificData *tsdPtr;
+ ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
+
+ tsdPtr = ConsoleInit();
+
+ infoPtr->nextPtr = tsdPtr->firstConsolePtr;
+ tsdPtr->firstConsolePtr = infoPtr;
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
* WaitForRead --
*
* Wait until some data is available, the console is at
*** win/tclWinFile.c 16 Dec 2003 02:55:38 -0000 1.58
--- win/tclWinFile.c 14 Jan 2004 02:18:47 -0000
***************
*** 14,21 ****
* RCS: @(#) $Id: tclWinFile.c,v 1.58 2003/12/16 02:55:38 davygrvy Exp $
*/
- //#define _WIN32_WINNT 0x0500
-
#include "tclWinInt.h"
#include <winioctl.h>
#include <sys/stat.h>
--- 14,19 ----
*** win/tclWinPipe.c 24 Dec 2003 04:18:23 -0000 1.39
--- win/tclWinPipe.c 14 Jan 2004 02:18:50 -0000
***************
*** 179,209 ****
* Declarations for functions used only in this file.
*/
! static int ApplicationType(Tcl_Interp *interp,
! const char *fileName, char *fullName);
! static void BuildCommandLine(const char *executable, int argc,
! CONST char **argv, Tcl_DString *linePtr);
! static BOOL HasConsole(void);
! static int PipeBlockModeProc(ClientData instanceData, int mode);
! static void PipeCheckProc(ClientData clientData, int flags);
! static int PipeClose2Proc(ClientData instanceData,
! Tcl_Interp *interp, int flags);
! static int PipeEventProc(Tcl_Event *evPtr, int flags);
! static void PipeExitHandler(ClientData clientData);
! static int PipeGetHandleProc(ClientData instanceData,
! int direction, ClientData *handlePtr);
! static void PipeInit(void);
! static int PipeInputProc(ClientData instanceData, char *buf,
! int toRead, int *errorCode);
! static int PipeOutputProc(ClientData instanceData,
! CONST char *buf, int toWrite, int *errorCode);
! static DWORD WINAPI PipeReaderThread(LPVOID arg);
! static void PipeSetupProc(ClientData clientData, int flags);
! static void PipeWatchProc(ClientData instanceData, int mask);
! static DWORD WINAPI PipeWriterThread(LPVOID arg);
! static void ProcExitHandler(ClientData clientData);
! static int TempFileName(WCHAR name[MAX_PATH]);
! static int WaitForRead(PipeInfo *infoPtr, int blocking);
/*
* This structure describes the channel type structure for command pipe
--- 179,209 ----
* Declarations for functions used only in this file.
*/
! static int ApplicationType(Tcl_Interp *interp,
! CONST char *fileName, char *fullName);
! static void BuildCommandLine(const char *executable,
! int argc, CONST char **argv,
! Tcl_DString *linePtr);
! static BOOL HasConsole(void);
! static Tcl_DriverBlockModeProc PipeBlockModeProc;
! static Tcl_EventCheckProc PipeCheckProc;
! static Tcl_DriverClose2Proc PipeClose2Proc;
! static Tcl_DriverCutProc PipeCutProc;
! static Tcl_EventProc PipeEventProc;
! static Tcl_ExitProc PipeExitHandler;
! static Tcl_DriverGetHandleProc PipeGetHandleProc;
! static ThreadSpecificData * PipeInit(void);
! static Tcl_DriverInputProc PipeInputProc;
! static Tcl_DriverOutputProc PipeOutputProc;
! static DWORD WINAPI PipeReaderThread(LPVOID arg);
! static Tcl_EventSetupProc PipeSetupProc;
! static Tcl_DriverSpliceProc PipeSpliceProc;
! static Tcl_DriverWatchProc PipeWatchProc;
! static DWORD WINAPI PipeWriterThread(LPVOID arg);
! static Tcl_ExitProc ProcExitHandler;
! static int TempFileName(WCHAR name[MAX_PATH]);
! static int WaitForRead(PipeInfo *infoPtr,
! int blocking);
/*
* This structure describes the channel type structure for command pipe
***************
*** 212,218 ****
static Tcl_ChannelType pipeChannelType = {
"pipe", /* Type name. */
! TCL_CHANNEL_VERSION_2, /* v2 channel */
TCL_CLOSE2PROC, /* Close proc. */
PipeInputProc, /* Input proc. */
PipeOutputProc, /* Output proc. */
--- 212,218 ----
static Tcl_ChannelType pipeChannelType = {
"pipe", /* Type name. */
! TCL_CHANNEL_VERSION_4, /* v4 channel */
TCL_CLOSE2PROC, /* Close proc. */
PipeInputProc, /* Input proc. */
PipeOutputProc, /* Output proc. */
***************
*** 225,230 ****
--- 225,233 ----
PipeBlockModeProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
+ NULL, /* wide seek proc. */
+ PipeCutProc, /* cut proc. */
+ PipeSpliceProc, /* splice proc. */
};
/*
***************
*** 243,249 ****
*----------------------------------------------------------------------
*/
! static void
PipeInit()
{
ThreadSpecificData *tsdPtr;
--- 246,252 ----
*----------------------------------------------------------------------
*/
! static ThreadSpecificData *
PipeInit()
{
ThreadSpecificData *tsdPtr;
***************
*** 270,275 ****
--- 273,279 ----
Tcl_CreateEventSource(PipeSetupProc, PipeCheckProc, NULL);
Tcl_CreateThreadExitHandler(PipeExitHandler, NULL);
}
+ return tsdPtr;
}
/*
***************
*** 315,321 ****
static void
ProcExitHandler(
! ClientData clientData) /* Old window proc */
{
Tcl_MutexLock(&pipeMutex);
initialized = 0;
--- 319,325 ----
static void
ProcExitHandler(
! ClientData clientData) /* Not used. */
{
Tcl_MutexLock(&pipeMutex);
initialized = 0;
***************
*** 404,410 ****
PipeEvent *evPtr;
WinFile *filePtr;
int needEvent;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
--- 408,416 ----
PipeEvent *evPtr;
WinFile *filePtr;
int needEvent;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = PipeInit();
if (!(flags & TCL_FILE_EVENTS)) {
return;
***************
*** 1882,1890 ****
Tcl_Channel errChan;
int errorCode, result;
PipeInfo *infoPtr, **nextPtrPtr;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
DWORD exitCode;
errorCode = 0;
if ((!flags || (flags == TCL_CLOSE_READ))
&& (pipePtr->readFile != NULL)) {
--- 1888,1898 ----
Tcl_Channel errChan;
int errorCode, result;
PipeInfo *infoPtr, **nextPtrPtr;
! ThreadSpecificData *tsdPtr;
DWORD exitCode;
+ tsdPtr = PipeInit();
+
errorCode = 0;
if ((!flags || (flags == TCL_CLOSE_READ))
&& (pipePtr->readFile != NULL)) {
***************
*** 2299,2305 ****
PipeInfo *infoPtr;
WinFile *filePtr;
int mask;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return 0;
--- 2307,2315 ----
PipeInfo *infoPtr;
WinFile *filePtr;
int mask;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = PipeInit();
if (!(flags & TCL_FILE_EVENTS)) {
return 0;
***************
*** 2386,2392 ****
PipeInfo **nextPtrPtr, *ptr;
PipeInfo *infoPtr = (PipeInfo *) instanceData;
int oldMask = infoPtr->watchMask;
! ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
* Since most of the work is handled by the background threads,
--- 2396,2404 ----
PipeInfo **nextPtrPtr, *ptr;
PipeInfo *infoPtr = (PipeInfo *) instanceData;
int oldMask = infoPtr->watchMask;
! ThreadSpecificData *tsdPtr;
!
! tsdPtr = PipeInit();
/*
* Since most of the work is handled by the background threads,
***************
*** 2463,2468 ****
--- 2475,2558 ----
/*
*----------------------------------------------------------------------
*
+ * PipeCutProc --
+ *
+ * Driver procedure to remove any thread local refs to this
+ * channel. See Tcl_CutChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ PipeCutProc(instanceData)
+ ClientData instanceData; /* Pipe state. */
+ {
+ ThreadSpecificData *tsdPtr;
+ PipeInfo *infoPtr = (PipeInfo *) instanceData;
+ PipeInfo **nextPtrPtr;
+ int removed = 0;
+
+ tsdPtr = PipeInit();
+
+ for (nextPtrPtr = &(tsdPtr->firstPipePtr); (*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("PipeInfo ptr not on thread channel list");
+ }
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
+ * PipeSpliceProc --
+ *
+ * Driver procedure to insert thread local ref for this channel.
+ * See Tcl_SpliceChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ PipeSpliceProc(instanceData)
+ ClientData instanceData; /* Pipe state. */
+ {
+ ThreadSpecificData *tsdPtr;
+ PipeInfo *infoPtr = (PipeInfo *) instanceData;
+
+ tsdPtr = PipeInit();
+
+ infoPtr->nextPtr = tsdPtr->firstPipePtr;
+ tsdPtr->firstPipePtr = infoPtr;
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
* Tcl_WaitPid --
*
* Emulates the waitpid system call.
*** win/tclWinSerial.c 19 Aug 2003 19:39:56 -0000 1.28
--- win/tclWinSerial.c 14 Jan 2004 02:18:53 -0000
***************
*** 169,203 ****
* Declarations for functions used only in this file.
*/
! static int SerialBlockProc(ClientData instanceData,
! int mode);
! static void SerialCheckProc(ClientData clientData,
! int flags);
! static int SerialCloseProc(ClientData instanceData,
! Tcl_Interp *interp);
! static int SerialEventProc(Tcl_Event *evPtr, int flags);
! static void SerialExitHandler(ClientData clientData);
! static int SerialGetHandleProc(ClientData instanceData,
! int direction, ClientData *handlePtr);
static ThreadSpecificData * SerialInit(void);
! static int SerialInputProc(ClientData instanceData,
! char *buf, int toRead, int *errorCode);
! static int SerialOutputProc(ClientData instanceData,
! CONST char *buf, int toWrite,
! int *errorCode);
! static void SerialSetupProc(ClientData clientData,
! int flags);
! static void SerialWatchProc(ClientData instanceData,
! int mask);
! static void ProcExitHandler(ClientData clientData);
! static int SerialGetOptionProc _ANSI_ARGS_((
! ClientData instanceData,
! Tcl_Interp *interp, CONST char *optionName,
! Tcl_DString *dsPtr));
! static int SerialSetOptionProc _ANSI_ARGS_((
! ClientData instanceData,
! Tcl_Interp *interp, CONST char *optionName,
! CONST char *value));
static DWORD WINAPI SerialWriterThread(LPVOID arg);
/*
--- 169,190 ----
* Declarations for functions used only in this file.
*/
! static Tcl_DriverBlockModeProc SerialBlockProc;
! static Tcl_EventCheckProc SerialCheckProc;
! static Tcl_DriverCloseProc SerialCloseProc;
! static Tcl_DriverCutProc SerialCutProc;
! static Tcl_EventProc SerialEventProc;
! static Tcl_ExitProc SerialExitHandler;
! static Tcl_DriverGetHandleProc SerialGetHandleProc;
static ThreadSpecificData * SerialInit(void);
! static Tcl_DriverInputProc SerialInputProc;
! static Tcl_DriverOutputProc SerialOutputProc;
! static Tcl_EventSetupProc SerialSetupProc;
! static Tcl_DriverSpliceProc SerialSpliceProc;
! static Tcl_DriverWatchProc SerialWatchProc;
! static Tcl_ExitProc ProcExitHandler;
! static Tcl_DriverGetOptionProc SerialGetOptionProc;
! static Tcl_DriverSetOptionProc SerialSetOptionProc;
static DWORD WINAPI SerialWriterThread(LPVOID arg);
/*
***************
*** 207,213 ****
static Tcl_ChannelType serialChannelType = {
"serial", /* Type name. */
! TCL_CHANNEL_VERSION_2, /* v2 channel */
SerialCloseProc, /* Close proc. */
SerialInputProc, /* Input proc. */
SerialOutputProc, /* Output proc. */
--- 194,200 ----
static Tcl_ChannelType serialChannelType = {
"serial", /* Type name. */
! TCL_CHANNEL_VERSION_4, /* v4 channel */
SerialCloseProc, /* Close proc. */
SerialInputProc, /* Input proc. */
SerialOutputProc, /* Output proc. */
***************
*** 220,225 ****
--- 207,215 ----
SerialBlockProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
+ NULL, /* wide seek proc. */
+ SerialCutProc, /* cut proc. */
+ SerialSpliceProc, /* splice proc. */
};
/*
***************
*** 1288,1293 ****
--- 1278,1361 ----
/*
*----------------------------------------------------------------------
*
+ * SerialCutProc --
+ *
+ * Driver procedure to remove any thread local refs to this
+ * channel. See Tcl_CutChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ SerialCutProc(instanceData)
+ ClientData instanceData; /* Serial state. */
+ {
+ ThreadSpecificData *tsdPtr;
+ SerialInfo *infoPtr = (SerialInfo *) instanceData;
+ SerialInfo **nextPtrPtr;
+ int removed = 0;
+
+ tsdPtr = SerialInit();
+
+ for (nextPtrPtr = &(tsdPtr->firstSerialPtr); (*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("SerialInfo ptr not on thread channel list");
+ }
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
+ * SerialSpliceProc --
+ *
+ * Driver procedure to insert thread local ref for this channel.
+ * See Tcl_SpliceChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ SerialSpliceProc(instanceData)
+ ClientData instanceData; /* Serial state. */
+ {
+ ThreadSpecificData *tsdPtr;
+ SerialInfo *infoPtr = (SerialInfo *) instanceData;
+
+ tsdPtr = SerialInit();
+
+ infoPtr->nextPtr = tsdPtr->firstSerialPtr;
+ tsdPtr->firstSerialPtr = infoPtr;
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
* SerialWriterThread --
*
* This function runs in a separate thread and writes data
*** win/tclWinSock.c 24 Dec 2003 04:18:23 -0000 1.41
--- win/tclWinSock.c 14 Jan 2004 02:18:56 -0000
***************
*** 232,257 ****
* Static functions defined in this file.
*/
! static SocketInfo * CreateSocket _ANSI_ARGS_((Tcl_Interp *interp,
int port, CONST char *host,
int server, CONST char *myaddr,
int myport, int async));
! static int CreateSocketAddress _ANSI_ARGS_(
! (LPSOCKADDR_IN sockaddrPtr,
CONST char *host, int port));
! static void InitSockets _ANSI_ARGS_((void));
! static SocketInfo * NewSocketInfo _ANSI_ARGS_((SOCKET socket));
! static Tcl_EventCheckProc SocketCheckProc;
! static Tcl_EventProc SocketEventProc;
! static void SocketExitHandler _ANSI_ARGS_((
! ClientData clientData));
! static LRESULT CALLBACK SocketProc _ANSI_ARGS_((HWND hwnd,
UINT message, WPARAM wParam,
LPARAM lParam));
! static Tcl_EventSetupProc SocketSetupProc;
! static Tcl_ExitProc SocketThreadExitHandler;
! static int SocketsEnabled _ANSI_ARGS_((void));
! static void TcpAccept _ANSI_ARGS_((SocketInfo *infoPtr));
static Tcl_DriverBlockModeProc TcpBlockProc;
static Tcl_DriverCloseProc TcpCloseProc;
static Tcl_DriverSetOptionProc TcpSetOptionProc;
--- 232,256 ----
* Static functions defined in this file.
*/
! static SocketInfo * CreateSocket _ANSI_ARGS_((Tcl_Interp *interp,
int port, CONST char *host,
int server, CONST char *myaddr,
int myport, int async));
! static int CreateSocketAddress _ANSI_ARGS_((
! LPSOCKADDR_IN sockaddrPtr,
CONST char *host, int port));
! static void InitSockets _ANSI_ARGS_((void));
! static SocketInfo * NewSocketInfo _ANSI_ARGS_((SOCKET socket));
! static Tcl_EventCheckProc SocketCheckProc;
! static Tcl_EventProc SocketEventProc;
! static Tcl_ExitProc SocketExitHandler;
! static LRESULT CALLBACK SocketProc _ANSI_ARGS_((HWND hwnd,
UINT message, WPARAM wParam,
LPARAM lParam));
! static Tcl_EventSetupProc SocketSetupProc;
! static Tcl_ExitProc SocketThreadExitHandler;
! static int SocketsEnabled _ANSI_ARGS_((void));
! static void TcpAccept _ANSI_ARGS_((SocketInfo *infoPtr));
static Tcl_DriverBlockModeProc TcpBlockProc;
static Tcl_DriverCloseProc TcpCloseProc;
static Tcl_DriverSetOptionProc TcpSetOptionProc;
***************
*** 260,269 ****
static Tcl_DriverOutputProc TcpOutputProc;
static Tcl_DriverWatchProc TcpWatchProc;
static Tcl_DriverGetHandleProc TcpGetHandleProc;
! static int WaitForSocketEvent _ANSI_ARGS_((
! SocketInfo *infoPtr, int events,
! int *errorCodePtr));
! static DWORD WINAPI SocketThread _ANSI_ARGS_((LPVOID arg));
/*
* This structure describes the channel type structure for TCP socket
--- 259,271 ----
static Tcl_DriverOutputProc TcpOutputProc;
static Tcl_DriverWatchProc TcpWatchProc;
static Tcl_DriverGetHandleProc TcpGetHandleProc;
! static Tcl_DriverCutProc TcpCutProc;
! static Tcl_DriverSpliceProc TcpSpliceProc;
!
! static int WaitForSocketEvent _ANSI_ARGS_((
! SocketInfo *infoPtr, int events,
! int *errorCodePtr));
! static DWORD WINAPI SocketThread _ANSI_ARGS_((LPVOID arg));
/*
* This structure describes the channel type structure for TCP socket
***************
*** 272,278 ****
static Tcl_ChannelType tcpChannelType = {
"tcp", /* Type name. */
! TCL_CHANNEL_VERSION_2, /* v2 channel */
TcpCloseProc, /* Close proc. */
TcpInputProc, /* Input proc. */
TcpOutputProc, /* Output proc. */
--- 274,280 ----
static Tcl_ChannelType tcpChannelType = {
"tcp", /* Type name. */
! TCL_CHANNEL_VERSION_4, /* v4 channel */
TcpCloseProc, /* Close proc. */
TcpInputProc, /* Input proc. */
TcpOutputProc, /* Output proc. */
***************
*** 285,290 ****
--- 287,295 ----
TcpBlockProc, /* Set socket into (non-)blocking mode. */
NULL, /* flush proc. */
NULL, /* handler proc. */
+ NULL, /* wideseek proc. */
+ TcpCutProc, /* cut proc. */
+ TcpSpliceProc, /* splice proc. */
};
***************
*** 2284,2290 ****
/*
*----------------------------------------------------------------------
*
! * TcpGetProc --
*
* Called from Tcl_GetChannelHandle to retrieve an OS handle from inside
* a TCP socket based channel.
--- 2289,2295 ----
/*
*----------------------------------------------------------------------
*
! * TcpGetHandleProc --
*
* Called from Tcl_GetChannelHandle to retrieve an OS handle from inside
* a TCP socket based channel.
***************
*** 2313,2318 ****
--- 2318,2431 ----
/*
*----------------------------------------------------------------------
*
+ * TcpCutProc --
+ *
+ * Remove any thread local refs to this channel. See
+ * Tcl_CutChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ TcpCutProc(instanceData)
+ ClientData instanceData; /* The socket state. */
+ {
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ SocketInfo *infoPtr = (SocketInfo *) instanceData;
+ SocketInfo **nextPtrPtr;
+ int removed = 0;
+
+ for (nextPtrPtr = &(tsdPtr->socketList); (*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");
+ }
+
+ /*
+ * Stop notifications for the socket to occur in this thread.
+ */
+
+ SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
+ (WPARAM) UNSELECT, (LPARAM) infoPtr);
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
+ * TcpSpliceProc --
+ *
+ * Insert thread local ref for this channel.
+ * Tcl_SpliceChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ TcpSpliceProc(instanceData)
+ ClientData instanceData; /* The socket state. */
+ {
+ ThreadSpecificData *tsdPtr;
+ SocketInfo *infoPtr = (SocketInfo *) instanceData;
+
+ /*
+ * Ensure that socket subsystem is initialized in this thread, or
+ * else sockets will not work.
+ */
+
+ Tcl_MutexLock(&socketMutex);
+ InitSockets();
+ Tcl_MutexUnlock(&socketMutex);
+
+ /*
+ * The initializtion of tsdPtr _after_ we have determined that we
+ * are dealing with socket is necessary. Doing it before causes
+ * the module to access th tdsPtr when it is not initialized yet,
+ * causing a lockup.
+ */
+
+ tsdPtr = TCL_TSD_INIT(&dataKey);
+
+ WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
+ infoPtr->nextPtr = tsdPtr->socketList;
+ tsdPtr->socketList = infoPtr;
+ SetEvent(tsdPtr->socketListLock);
+
+ /*
+ * Ensure that notifications for the socket occur in this thread.
+ */
+
+ SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
+ (WPARAM) SELECT, (LPARAM) infoPtr);
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
* SocketThread --
*
* Helper thread used to manage the socket event handling window.
***************
*** 2666,2799 ****
return winSock.getservbyname(name, proto);
}
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * TclpCutSockChannel --
- *
- * Remove any thread local refs to this channel. See
- * Tcl_CutChannel for more info.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Changes thread local list of valid channels.
- *
- *----------------------------------------------------------------------
- */
-
- void
- TclpCutSockChannel(chan)
- Tcl_Channel chan; /* The channel being removed. Must
- * not be referenced in any
- * interpreter. */
- {
- ThreadSpecificData *tsdPtr;
- SocketInfo *infoPtr;
- SocketInfo **nextPtrPtr;
- int removed = 0;
-
- if (Tcl_GetChannelType(chan) != &tcpChannelType)
- return;
-
- /*
- * The initializtion of tsdPtr _after_ we have determined that we
- * are dealing with socket is necessary. Doing it before causes
- * the module to access th tdsPtr when it is not initialized yet,
- * causing a lockup.
- */
-
- tsdPtr = TCL_TSD_INIT(&dataKey);
- infoPtr = (SocketInfo *) Tcl_GetChannelInstanceData (chan);
-
- for (nextPtrPtr = &(tsdPtr->socketList); (*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");
- }
-
- /*
- * Stop notifications for the socket to occur in this thread.
- */
-
- SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
- (WPARAM) UNSELECT, (LPARAM) infoPtr);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TclpSpliceSockChannel --
- *
- * Insert thread local ref for this channel.
- * Tcl_SpliceChannel for more info.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Changes thread local list of valid channels.
- *
- *----------------------------------------------------------------------
- */
-
- void
- TclpSpliceSockChannel(chan)
- Tcl_Channel chan; /* The channel being removed. Must
- * not be referenced in any
- * interpreter. */
- {
- ThreadSpecificData *tsdPtr;
- SocketInfo *infoPtr;
-
- if (Tcl_GetChannelType(chan) != &tcpChannelType)
- return;
-
- /*
- * Ensure that socket subsystem is initialized in this thread, or
- * else sockets will not work.
- */
-
- Tcl_MutexLock(&socketMutex);
- InitSockets();
- Tcl_MutexUnlock(&socketMutex);
-
- /*
- * The initializtion of tsdPtr _after_ we have determined that we
- * are dealing with socket is necessary. Doing it before causes
- * the module to access th tdsPtr when it is not initialized yet,
- * causing a lockup.
- */
-
- tsdPtr = TCL_TSD_INIT(&dataKey);
- infoPtr = (SocketInfo *) Tcl_GetChannelInstanceData (chan);
-
- WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
- infoPtr->nextPtr = tsdPtr->socketList;
- tsdPtr->socketList = infoPtr;
- SetEvent(tsdPtr->socketListLock);
-
- /*
- * Ensure that notifications for the socket occur in this thread.
- */
-
- SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
- (WPARAM) SELECT, (LPARAM) infoPtr);
- }
--- 2779,2781 ----