diff options
author | max <max@tclers.tk> | 2014-03-14 14:26:22 (GMT) |
---|---|---|
committer | max <max@tclers.tk> | 2014-03-14 14:26:22 (GMT) |
commit | c02f2ee223615fe5b82e63c097199e34d0803814 (patch) | |
tree | ded930dd502e4646777269b0109421cc98f759bb /unix | |
parent | f52bc4c0b11afcb0144f828bd128be56202099a6 (diff) | |
download | tcl-c02f2ee223615fe5b82e63c097199e34d0803814.zip tcl-c02f2ee223615fe5b82e63c097199e34d0803814.tar.gz tcl-c02f2ee223615fe5b82e63c097199e34d0803814.tar.bz2 |
* More test improvements for async sockets.
* Advance async connections whenever the channel is touched (e.g. by [chan configure]).
* Add a noblock argument to WaitForConnect(), so that advancing async connections from [chan configure] doesn't block even on a blocking socket.
Diffstat (limited to 'unix')
-rw-r--r-- | unix/tclUnixSock.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 8336bdb..b26d707 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -128,7 +128,8 @@ static int TcpInputProc(ClientData instanceData, char *buf, static int TcpOutputProc(ClientData instanceData, const char *buf, int toWrite, int *errorCode); static void TcpWatchProc(ClientData instanceData, int mask); -static int WaitForConnect(TcpState *statePtr, int *errorCodePtr); +static int WaitForConnect(TcpState *statePtr, int *errorCodePtr, + int noblock); /* * This structure describes the channel type structure for TCP socket @@ -385,7 +386,8 @@ TcpBlockModeProc( * * Wait for a connection on an asynchronously opened socket to be * completed. In nonblocking mode, just test if the connection - * has completed without blocking. + * has completed without blocking. The noblock parameter allows to + * enforce nonblocking behaviour even on sockets in blocking mode. * * Results: * 0 if the connection has completed, -1 if still in progress @@ -397,7 +399,8 @@ TcpBlockModeProc( static int WaitForConnect( TcpState *statePtr, /* State of the socket. */ - int *errorCodePtr) /* Where to store errors? */ + int *errorCodePtr, /* Where to store errors? */ + int noblock) /* Don't wait, even for sockets in blocking mode */ { int timeOut; /* How long to wait. */ int state; /* Of calling TclWaitForFile. */ @@ -408,7 +411,7 @@ WaitForConnect( */ if (statePtr->flags & TCP_ASYNC_CONNECT) { - if (statePtr->flags & TCP_ASYNC_SOCKET) { + if (noblock || statePtr->flags & TCP_ASYNC_SOCKET) { timeOut = 0; } else { timeOut = -1; @@ -417,7 +420,7 @@ WaitForConnect( errno = 0; state = TclUnixWaitForFile(statePtr->fds.fd, TCL_WRITABLE | TCL_EXCEPTION, timeOut); - if (timeOut == -1 && state != 0) { + if (state != 0) { CreateClientSocket(NULL, statePtr); } if (statePtr->flags & TCP_ASYNC_CONNECT) { @@ -468,7 +471,7 @@ TcpInputProc( int bytesRead; *errorCodePtr = 0; - if (WaitForConnect(statePtr, errorCodePtr) != 0) { + if (WaitForConnect(statePtr, errorCodePtr, 0) != 0) { return -1; } bytesRead = recv(statePtr->fds.fd, buf, (size_t) bufSize, 0); @@ -518,7 +521,7 @@ TcpOutputProc( int written; *errorCodePtr = 0; - if (WaitForConnect(statePtr, errorCodePtr) != 0) { + if (WaitForConnect(statePtr, errorCodePtr, 0) != 0) { return -1; } written = send(statePtr->fds.fd, buf, (size_t) toWrite, 0); @@ -745,6 +748,9 @@ TcpGetOptionProc( { TcpState *statePtr = instanceData; size_t len = 0; + int errorCode; + + WaitForConnect(statePtr, &errorCode, 1); if (optionName != NULL) { len = strlen(optionName); @@ -772,6 +778,14 @@ TcpGetOptionProc( return TCL_OK; } + if ((len > 1) && (optionName[1] == 'c') && + (strncmp(optionName, "-connecting", len) == 0)) { + + Tcl_DStringAppend(dsPtr, + (statePtr->flags & TCP_ASYNC_CONNECT) ? "1" : "0", -1); + return TCL_OK; + } + if ((len == 0) || ((len > 1) && (optionName[1] == 'p') && (strncmp(optionName, "-peername", len) == 0))) { address peername; |