Changeset: ee2098dc8a1f for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ee2098dc8a1f Modified Files: common/stream/stream.c Branch: Oct2014 Log Message:
Use select to implement read timeout on sockets. This should fix the problem of disconnected servers while debugging the server. diffs (93 lines): diff --git a/common/stream/stream.c b/common/stream/stream.c --- a/common/stream/stream.c +++ b/common/stream/stream.c @@ -1670,24 +1670,53 @@ socket_read(stream *s, void *buf, size_t if (size == 0) return 0; - do { - errno = 0; -#ifdef NATIVE_WIN32 - if (size > INT_MAX) - size = elmsize * (INT_MAX / elmsize); +#ifdef _MSC_VER + /* recv only takes an int parameter, and read does not accept + * sockets */ + if (size > INT_MAX) + size = elmsize * (INT_MAX / elmsize); +#endif + for (;;) { + if (s->timeout) { + struct timeval tv; + fd_set fds; + int ret; + + errno = 0; + FD_ZERO(&fds); + FD_SET(s->stream_data.s, &fds); + tv.tv_sec = s->timeout / 1000; + tv.tv_usec = (s->timeout % 1000) * 1000; + ret = select( +#ifdef _MSC_VER + 0, /* ignored on Windows */ +#else + s->stream_data.s + 1, +#endif + &fds, NULL, NULL, &tv); + if (s->timeout_func && (*s->timeout_func)()) { + s->errnr = MNSTR_TIMEOUT; + return -1; + } + if (ret == -1) { + s->errnr = MNSTR_READ_ERROR; + return -1; + } + if (ret == 0) + continue; + assert(ret == 1); + assert(FD_ISSET(s->stream_data.s, &fds)); + } +#ifdef _MSC_VER nr = recv(s->stream_data.s, buf, (int) size, 0); #else nr = read(s->stream_data.s, buf, size); #endif - } while (nr == -1 && s->timeout > 0 && - (errno == EAGAIN || errno == EWOULDBLOCK) && - s->timeout_func && !(*s->timeout_func)()); - if (nr < 0) { - if (s->timeout > 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) - s->errnr = MNSTR_TIMEOUT; - else + if (nr == -1) { s->errnr = MNSTR_READ_ERROR; - return -1; + return -1; + } + break; } if (nr == 0) return 0; /* end of file */ @@ -1704,12 +1733,7 @@ socket_read(stream *s, void *buf, size_t ssize_t n; n = socket_read(s, (char *) buf + nr, 1, (size_t) (size - nr)); if (n < 0) { - if (s->errnr == MNSTR_TIMEOUT) { - /* ignore timeout */ - s->errnr = MNSTR_NO__ERROR; - continue; - } - /* some other read error is serious */ + s->errnr = MNSTR_READ_ERROR; return -1; } if (n == 0) /* unexpected end of file */ @@ -1755,8 +1779,6 @@ 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->access == ST_READ) - (void) setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, (socklen_t) sizeof(tv)); if (s->access == ST_WRITE) (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *) &tv, (socklen_t) sizeof(tv)); } _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list