diff options
author | dgp <dgp@users.sourceforge.net> | 2020-04-01 11:54:27 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2020-04-01 11:54:27 (GMT) |
commit | 14c6f5491be3cd441df1f7142510835c67f78e9d (patch) | |
tree | 2154042e4fc5ed59be9173811bb3f8a0803d8d40 /unix | |
parent | f8ae8cc375adc04ed8d810255e0d282cce9ae35e (diff) | |
parent | f394d8c0d4ef97cd0aebf1ce7de1ecb86a50ba9d (diff) | |
download | tcl-14c6f5491be3cd441df1f7142510835c67f78e9d.zip tcl-14c6f5491be3cd441df1f7142510835c67f78e9d.tar.gz tcl-14c6f5491be3cd441df1f7142510835c67f78e9d.tar.bz2 |
merge 8.6
Diffstat (limited to 'unix')
-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 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. |