From db509d17e6c2f57ad9550bd9336dc198853377bb Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Mon, 21 May 2012 12:58:48 +0000 Subject: [PATCH] Handle EINTR in socket functions and continue incomplete sends. Based on a patch by Ben Noordhuis . BUG=v8:2098 TEST= Review URL: https://chromiumcodereview.appspot.com/10416006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11609 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/platform-posix.cc | 29 ++++++++++++++++++++++++----- src/platform-win32.cc | 14 ++++++++++++-- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/platform-posix.cc b/src/platform-posix.cc index 3e143d2..d942d78 100644 --- a/src/platform-posix.cc +++ b/src/platform-posix.cc @@ -421,7 +421,11 @@ Socket* POSIXSocket::Accept() const { return NULL; } - int socket = accept(socket_, NULL, NULL); + int socket; + do { + socket = accept(socket_, NULL, NULL); + } while (socket == -1 && errno == EINTR); + if (socket == -1) { return NULL; } else { @@ -448,7 +452,9 @@ bool POSIXSocket::Connect(const char* host, const char* port) { } // Connect. - status = connect(socket_, result->ai_addr, result->ai_addrlen); + do { + status = connect(socket_, result->ai_addr, result->ai_addrlen); + } while (status == -1 && errno == EINTR); freeaddrinfo(result); return status == 0; } @@ -468,14 +474,27 @@ bool POSIXSocket::Shutdown() { int POSIXSocket::Send(const char* data, int len) const { if (len <= 0) return 0; - int status = send(socket_, data, len, 0); - return (status < 0) ? 0 : status; + int written = 0; + while (written < len) { + int status = send(socket_, data + written, len - written, 0); + if (status == 0) { + break; + } else if (status > 0) { + written += status; + } else if (errno != EINTR) { + return 0; + } + } + return written; } int POSIXSocket::Receive(char* data, int len) const { if (len <= 0) return 0; - int status = recv(socket_, data, len, 0); + int status; + do { + status = recv(socket_, data, len, 0); + } while (status == -1 && errno == EINTR); return (status < 0) ? 0 : status; } diff --git a/src/platform-win32.cc b/src/platform-win32.cc index aa2a71a..2473949 100644 --- a/src/platform-win32.cc +++ b/src/platform-win32.cc @@ -1849,8 +1849,18 @@ bool Win32Socket::Shutdown() { int Win32Socket::Send(const char* data, int len) const { if (len <= 0) return 0; - int status = send(socket_, data, len, 0); - return (status == SOCKET_ERROR) ? 0 : status; + int written = 0; + while (written < len) { + int status = send(socket_, data + written, len - written, 0); + if (status == 0) { + break; + } else if (status > 0) { + written += status; + } else { + return 0; + } + } + return written; } -- 2.7.4