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 -- [email protected]
To unsubscribe send an email to [email protected]