summaryrefslogtreecommitdiffstats
path: root/win/tclWinSock.c
diff options
context:
space:
mode:
authorandreas_kupries <andreas_kupries@noemail.net>2003-04-22 23:20:39 (GMT)
committerandreas_kupries <andreas_kupries@noemail.net>2003-04-22 23:20:39 (GMT)
commitaa905507a335cd8f795473255881d3610abc7df0 (patch)
treeda7afb848b9cd285191c219ffb2b279fe3ee2429 /win/tclWinSock.c
parentfa323e3030a4e522fa8363be34a0af91be6375ce (diff)
downloadtcl-aa905507a335cd8f795473255881d3610abc7df0.zip
tcl-aa905507a335cd8f795473255881d3610abc7df0.tar.gz
tcl-aa905507a335cd8f795473255881d3610abc7df0.tar.bz2
* The changes below fix SF bugs [593810], and [718045].
* generic/tclIO.c (Tcl_CutChannel, Tcl_SpliceChannel): Invoke TclpCutSockChannel and TclpSpliceSockChannel. * generic/tclInt.h: Declare TclpCutSockChannel and TclpSpliceSockChannel. * unix/tclUnixSock.c (TclpCutSockChannel, TclpSpliceSockChannel): Dummy functions, on unix the sockets are _not_ handled specially. * mac/tclMacSock.c (TclpCutSockChannel, TclpSpliceSockChannel): * win/tclWinSock.c (TclpCutSockChannel, TclpSpliceSockChannel): New functions to handle socket specific cut/splice operations: auto-initi of socket system for thread on splice, management of the module internal per-thread list of sockets, management of association of sockets with HWNDs for event notification. * win/tclWinSock.c (NewSocketInfo): Extended initialization assignments to cover all items of the structure. During debugging of the new code mentioned above I found that two fileds could contain bogus data. * win/tclWinFile.c: Added #undef HAVE_NO_FINDEX_ENUMS before definition because when compiling in debug mode the compiler complains about a redefinition, and this warning is also treated as an error. FossilOrigin-Name: 1aff0f8acbbcab828d9c26c2f4234c3f0da301fd
Diffstat (limited to 'win/tclWinSock.c')
-rw-r--r--win/tclWinSock.c133
1 files changed, 132 insertions, 1 deletions
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index b92109b..bca4b72 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinSock.c,v 1.36 2003/01/16 19:02:00 mdejong Exp $
+ * RCS: @(#) $Id: tclWinSock.c,v 1.37 2003/04/22 23:20:44 andreas_kupries Exp $
*/
#include "tclWinInt.h"
@@ -1033,6 +1033,7 @@ NewSocketInfo(socket)
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
infoPtr = (SocketInfo *) ckalloc((unsigned) sizeof(SocketInfo));
+ infoPtr->channel = 0;
infoPtr->socket = socket;
infoPtr->flags = 0;
infoPtr->watchEvents = 0;
@@ -1040,6 +1041,7 @@ NewSocketInfo(socket)
infoPtr->selectEvents = 0;
infoPtr->acceptEventCount = 0;
infoPtr->acceptProc = NULL;
+ infoPtr->acceptProcData = NULL;
infoPtr->lastError = 0;
WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
@@ -2656,3 +2658,132 @@ TclWinGetServByName(const char * name, const char * 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) {
+ 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);
+}