summaryrefslogtreecommitdiffstats
path: root/unix/tclUnixSock.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2020-04-01 11:54:27 (GMT)
committerdgp <dgp@users.sourceforge.net>2020-04-01 11:54:27 (GMT)
commit14c6f5491be3cd441df1f7142510835c67f78e9d (patch)
tree2154042e4fc5ed59be9173811bb3f8a0803d8d40 /unix/tclUnixSock.c
parentf8ae8cc375adc04ed8d810255e0d282cce9ae35e (diff)
parentf394d8c0d4ef97cd0aebf1ce7de1ecb86a50ba9d (diff)
downloadtcl-14c6f5491be3cd441df1f7142510835c67f78e9d.zip
tcl-14c6f5491be3cd441df1f7142510835c67f78e9d.tar.gz
tcl-14c6f5491be3cd441df1f7142510835c67f78e9d.tar.bz2
merge 8.6
Diffstat (limited to 'unix/tclUnixSock.c')
-rw-r--r--unix/tclUnixSock.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c
index 80de491..b707be4 100644
--- a/unix/tclUnixSock.c
+++ b/unix/tclUnixSock.c
@@ -129,6 +129,7 @@ struct TcpState {
* Static routines for this file:
*/
+static void TcpAsyncCallback(void *clientData, int mask);
static int TcpConnect(Tcl_Interp *interp, TcpState *state);
static void TcpAccept(void *data, int mask);
static int TcpBlockModeProc(void *data, int mode);
@@ -145,6 +146,7 @@ static int TcpInputProc(void *instanceData, char *buf,
int toRead, int *errorCode);
static int TcpOutputProc(void *instanceData,
const char *buf, int toWrite, int *errorCode);
+static void TcpThreadActionProc(void *instanceData, int action);
static void TcpWatchProc(void *instanceData, int mask);
static int WaitForConnect(TcpState *statePtr, int *errorCodePtr);
static void WrapNotify(void *clientData, int mask);
@@ -174,7 +176,7 @@ static const Tcl_ChannelType tcpChannelType = {
NULL, /* flush proc. */
NULL, /* handler proc. */
NULL, /* wide seek proc. */
- NULL, /* thread action proc. */
+ TcpThreadActionProc, /* thread action proc. */
NULL /* truncate proc. */
};
@@ -983,6 +985,51 @@ TcpGetOptionProc(
/*
* ----------------------------------------------------------------------
*
+ * TcpThreadActionProc --
+ *
+ * Handles detach/attach for asynchronously connecting socket.
+ *
+ * Reassigning the file handler associated with thread-related channel
+ * notification, responsible for callbacks (signaling that asynchronous
+ * connection attempt has succeeded or failed).
+ *
+ * Results:
+ * None.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+TcpThreadActionProc(
+ void *instanceData,
+ int action)
+{
+ TcpState *statePtr = (TcpState *)instanceData;
+
+ if (GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT)) {
+ /*
+ * Async-connecting socket must get reassigned handler if it have been
+ * transferred to another thread. Remove the handler if the socket is
+ * not managed by this thread anymore and create new handler (TSD related)
+ * so the callback will run in the correct thread, bug [f583715154].
+ */
+ switch (action) {
+ case TCL_CHANNEL_THREAD_REMOVE:
+ CLEAR_BITS(statePtr->flags, TCP_ASYNC_PENDING);
+ Tcl_DeleteFileHandler(statePtr->fds.fd);
+ break;
+ case TCL_CHANNEL_THREAD_INSERT:
+ Tcl_CreateFileHandler(statePtr->fds.fd,
+ TCL_WRITABLE | TCL_EXCEPTION, TcpAsyncCallback, statePtr);
+ SET_BITS(statePtr->flags, TCP_ASYNC_PENDING);
+ break;
+ }
+ }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
* TcpWatchProc --
*
* Initialize the notifier to watch the fd from this channel.