summaryrefslogtreecommitdiffstats
path: root/unix/tclUnixSock.c
diff options
context:
space:
mode:
authormax <max@tclers.tk>2014-03-14 14:26:22 (GMT)
committermax <max@tclers.tk>2014-03-14 14:26:22 (GMT)
commitc02f2ee223615fe5b82e63c097199e34d0803814 (patch)
treeded930dd502e4646777269b0109421cc98f759bb /unix/tclUnixSock.c
parentf52bc4c0b11afcb0144f828bd128be56202099a6 (diff)
downloadtcl-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/tclUnixSock.c')
-rw-r--r--unix/tclUnixSock.c28
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;