Changeset: 9f2d3d897cb3 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/9f2d3d897cb3
Modified Files:
        clients/mapilib/connect.c
        clients/mapilib/connect_unix.c
        common/stream/socket_stream.c
Branch: odbc-tls
Log Message:

Obey MP_CONNECT_TIMEOUT and MP_REPLY_TIMEOUT in libmapi


diffs (132 lines):

diff --git a/clients/mapilib/connect.c b/clients/mapilib/connect.c
--- a/clients/mapilib/connect.c
+++ b/clients/mapilib/connect.c
@@ -144,6 +144,17 @@ establish_connection(Mapi mid)
                msg = mapi_handshake(mid);
        }
 
+       // Switch from MP_CONNECT_TIMEOUT to MP_REPLY_TIMEOUT
+       if (msg == MOK) {
+               long connect_timeout = msetting_long(mid->settings, 
MP_CONNECT_TIMEOUT);
+               long reply_timeout = msetting_long(mid->settings, 
MP_REPLY_TIMEOUT);
+               if (connect_timeout > 0 || reply_timeout > 0) {
+                       if (reply_timeout < 0)
+                               reply_timeout = 0;
+                       msg = mapi_timeout(mid, reply_timeout);
+               }
+       }
+
        return msg;
 }
 
@@ -153,6 +164,7 @@ connect_socket(Mapi mid)
        assert(!mid->connected);
        const char *sockname = msettings_connect_unix(mid->settings);
        const char *tcp_host = msettings_connect_tcp(mid->settings);
+       long timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT);
 
        assert(*sockname || *tcp_host);
        do {
@@ -165,6 +177,11 @@ connect_socket(Mapi mid)
                return mid->error;
        } while (0);
 
+       // the socket code may have set SO_SNDTIMEO and SO_RCVTIMEO but
+       // the mapi layer doesn't know this yet.
+       if (timeout > 0)
+               mapi_timeout(mid, timeout);
+
        mid->connected = true;
        return MOK;
 }
@@ -293,6 +310,8 @@ connect_socket_tcp(Mapi mid)
 static SOCKET
 connect_socket_tcp_addr(Mapi mid, struct addrinfo *info)
 {
+       long timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT);
+
        if (mid->tracelog) {
                char addrbuf[100] = {0};
                const char *addrtext;
@@ -332,6 +351,22 @@ connect_socket_tcp_addr(Mapi mid, struct
        (void) fcntl(s, F_SETFD, FD_CLOEXEC);
 #endif
 
+       if (timeout > 0) {
+               struct timeval tv = {
+                       .tv_sec = timeout / 1000,
+                       .tv_usec = timeout % 1000,
+               };
+               if (
+                       setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) 
== SOCKET_ERROR
+                       || setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, 
sizeof(tv)) == SOCKET_ERROR
+               ) {
+                       closesocket(s);
+                       return mapi_printError(
+                               mid, __func__, MERROR,
+                               "could not set connect timeout: %s", 
strerror(errno));
+               }
+       }
+
        // cast addrlen to int to satisfy Windows.
        if (connect(s, info->ai_addr, (int)info->ai_addrlen) == SOCKET_ERROR) {
                mapi_printError(
diff --git a/clients/mapilib/connect_unix.c b/clients/mapilib/connect_unix.c
--- a/clients/mapilib/connect_unix.c
+++ b/clients/mapilib/connect_unix.c
@@ -130,15 +130,16 @@ connect_socket_unix(Mapi mid)
 {
        const char *sockname = msettings_connect_unix(mid->settings);
        assert (*sockname != '\0');
+       long timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT);
 
-       mapi_log_record(mid, "CONN", "Connecting to Unix domain socket %s", 
sockname);
+       mapi_log_record(mid, "CONN", "Connecting to Unix domain socket %s with 
timeout %ld", sockname, timeout);
 
        struct sockaddr_un userver;
        if (strlen(sockname) >= sizeof(userver.sun_path)) {
                return mapi_printError(mid, __func__, MERROR, "path name '%s' 
too long", sockname);
        }
 
-       // Create the socket, taking care of CLOEXEC
+       // Create the socket, taking care of CLOEXEC and SNDTIMEO
 
 #ifdef SOCK_CLOEXEC
        int s = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
@@ -154,6 +155,22 @@ connect_socket_unix(Mapi mid)
        (void) fcntl(s, F_SETFD, FD_CLOEXEC);
 #endif
 
+       if (timeout > 0) {
+               struct timeval tv = {
+                       .tv_sec = timeout / 1000,
+                       .tv_usec = timeout % 1000,
+               };
+               if (
+                       setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) 
== SOCKET_ERROR
+                       || setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, 
sizeof(tv)) == SOCKET_ERROR
+               ) {
+                       closesocket(s);
+                       return mapi_printError(
+                               mid, __func__, MERROR,
+                               "could not set connect timeout: %s", 
strerror(errno));
+               }
+       }
+
        // Attempt to connect
 
        userver = (struct sockaddr_un) {
diff --git a/common/stream/socket_stream.c b/common/stream/socket_stream.c
--- a/common/stream/socket_stream.c
+++ b/common/stream/socket_stream.c
@@ -259,7 +259,9 @@ socket_update_timeout(stream *s)
        tv.tv_sec = s->timeout / 1000;
        tv.tv_usec = (s->timeout % 1000) * 1000;
        /* cast to char * for Windows, no harm on "normal" systems */
-       if (!s->readonly)
+       if (s->readonly)
+               (void) setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, 
(socklen_t) sizeof(tv));
+       else
                (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *) &tv, 
(socklen_t) sizeof(tv));
 }
 
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to