Attachment "patch.txt" to
ticket [593810ffff]
added by
davygrvy
2002-11-11 03:42:21.
*** generic/tcl.decls 31 Aug 2002 06:09:45 -0000 1.94
--- generic/tcl.decls 10 Nov 2002 20:31:06 -0000
***************
*** 1754,1759 ****
--- 1754,1765 ----
Tcl_ChannelType *chanTypePtr)
}
+ # new for channel version 4
+ declare 494 generic {
+ Tcl_DriverRegisterInitProc * Tcl_ChannelRegisterInitProc(
+ Tcl_ChannelType *chanTypePtr)
+ }
+
##############################################################################
# Define the platform specific public Tcl interface. These functions are
*** generic/tcl.h 21 Oct 2002 04:35:50 -0000 1.147
--- generic/tcl.h 10 Nov 2002 20:31:33 -0000
***************
*** 1423,1428 ****
--- 1423,1429 ----
#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:
***************
*** 1457,1462 ****
--- 1458,1464 ----
typedef Tcl_WideInt (Tcl_DriverWideSeekProc) _ANSI_ARGS_((
ClientData instanceData, Tcl_WideInt offset,
int mode, int *errorCodePtr));
+ typedef void (Tcl_DriverRegisterInitProc) _ANSI_ARGS_((void));
/*
***************
*** 1548,1553 ****
--- 1550,1566 ----
* 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_DriverRegisterInitProc *regProc;
+ /* Procedure to call when
+ * registering a channel into an
+ * interp. This allows the
+ * driver to do any needed per
+ * thread initialization should
+ * the channel have come from
+ * another thread. */
} Tcl_ChannelType;
/*
*** generic/tclIO.c 30 Jul 2002 18:36:25 -0000 1.57
--- generic/tclIO.c 10 Nov 2002 20:34:05 -0000
***************
*** 748,753 ****
--- 748,755 ----
int new; /* Is the hash entry new or does it exist? */
Channel *chanPtr; /* The actual channel. */
ChannelState *statePtr; /* State of the actual channel. */
+ Tcl_DriverRegisterInitProc *regProc;
+ /* the regProc for the channel type */
/*
* Always (un)register bottom-most channel in the stack. This makes
***************
*** 771,776 ****
--- 773,788 ----
panic("Tcl_RegisterChannel: duplicate channel names");
}
Tcl_SetHashValue(hPtr, (ClientData) chanPtr);
+
+ /*
+ * Make sure any needed per thread initialization the actual
+ * driver needs has been done on channel drivers that support
+ * this feature.
+ */
+ regProc = Tcl_ChannelRegisterInitProc(chanPtr->typePtr);
+ if (regProc != NULL) {
+ (*regProc)();
+ }
}
statePtr->refCount++;
}
***************
*** 8751,8756 ****
--- 8763,8770 ----
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
***************
*** 9099,9104 ****
--- 9113,9145 ----
{
if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_3)) {
return chanTypePtr->wideSeekProc;
+ } else {
+ return NULL;
+ }
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelRegisterInitProc --
+ *
+ * Return the Tcl_DriverRegisterInitProc of the channel type.
+ *
+ * Results:
+ * A pointer to the proc.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ Tcl_DriverRegisterInitProc *
+ Tcl_ChannelRegisterInitProc(chanTypePtr)
+ Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
+ {
+ if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_4)) {
+ return chanTypePtr->regProc;
} else {
return NULL;
}
*** win/tclWinSock.c 24 May 2002 18:57:09 -0000 1.26
--- win/tclWinSock.c 10 Nov 2002 20:35:41 -0000
***************
*** 205,210 ****
--- 205,211 ----
int mask));
static int TcpGetHandleProc _ANSI_ARGS_((ClientData instanceData,
int direction, ClientData *handlePtr));
+ static void TcpRegInitProc _ANSI_ARGS_((void));
static int WaitForSocketEvent _ANSI_ARGS_((SocketInfo *infoPtr,
int events, int *errorCodePtr));
static DWORD WINAPI SocketThread _ANSI_ARGS_((LPVOID arg));
***************
*** 216,222 ****
static Tcl_ChannelType tcpChannelType = {
"tcp", /* Type name. */
! TCL_CHANNEL_VERSION_2, /* v2 channel */
TcpCloseProc, /* Close proc. */
TcpInputProc, /* Input proc. */
TcpOutputProc, /* Output proc. */
--- 217,223 ----
static Tcl_ChannelType tcpChannelType = {
"tcp", /* Type name. */
! TCL_CHANNEL_VERSION_4, /* v4 channel */
TcpCloseProc, /* Close proc. */
TcpInputProc, /* Input proc. */
TcpOutputProc, /* Output proc. */
***************
*** 229,234 ****
--- 230,237 ----
TcpBlockProc, /* Set socket into (non-)blocking mode. */
NULL, /* flush proc. */
NULL, /* handler proc. */
+ NULL, /* wide seek proc. */
+ TcpRegInitProc /* register init proc.*/
};
/*
***************
*** 277,283 ****
* Initialize the function table.
*/
! if (!SocketsEnabled()) {
return;
}
--- 280,286 ----
* Initialize the function table.
*/
! if (winSock.hInstance == NULL) {
return;
}
***************
*** 2117,2122 ****
--- 2120,2152 ----
return TCL_OK;
}
+ /*
+ *----------------------------------------------------------------------
+ *
+ * TcpRegInitProc --
+ *
+ * Makes sure per-thread initialization happens when a channel
+ * is registered into an interp that might be in a different
+ * thread than where the socket was created.
+ *
+ * Results:
+ * none.
+ *
+ * Side effects:
+ * Creates a new TSD structure and the socket handler thread
+ * if one does not already exist for the calling thread.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ static void
+ TcpRegInitProc (void)
+ {
+ Tcl_MutexLock(&socketMutex);
+ InitSockets();
+ Tcl_MutexUnlock(&socketMutex);
+ }
+
/*
*----------------------------------------------------------------------
*