Handle EINTR in socket functions and continue incomplete sends.

Based on a patch by Ben Noordhuis <info@bnoordhuis.nl>.

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
This commit is contained in:
yangguo@chromium.org 2012-05-21 12:58:48 +00:00
parent 7813b1dd70
commit db509d17e6
2 changed files with 36 additions and 7 deletions

View File

@ -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;
}

View File

@ -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;
}