diff options
author | dgp <dgp@users.sourceforge.net> | 2020-04-01 12:37:52 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2020-04-01 12:37:52 (GMT) |
commit | 8ab2c9cf62965aff558352a4f02db0eb16c3e3b6 (patch) | |
tree | 66bb60cf1fdd4d321fce40ac56181630eb073968 /unix/tclUnixSock.c | |
parent | 6a1a8526f171c8a9a808de4f653436d86ecfc8b3 (diff) | |
parent | 14c6f5491be3cd441df1f7142510835c67f78e9d (diff) | |
download | tcl-8ab2c9cf62965aff558352a4f02db0eb16c3e3b6.zip tcl-8ab2c9cf62965aff558352a4f02db0eb16c3e3b6.tar.gz tcl-8ab2c9cf62965aff558352a4f02db0eb16c3e3b6.tar.bz2 |
merge 8.7
Diffstat (limited to 'unix/tclUnixSock.c')
-rw-r--r-- | unix/tclUnixSock.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 67f8614..1bbf8e1 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); @@ -170,7 +172,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. */ }; @@ -980,6 +982,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. |