Retry FS system calls on EINTR

Summary: EINTR means 'please retry'. We don't do that currenty. We should.

Test Plan: make check, although it doesn't really test the new code. we'll just have to believe in the code!

Reviewers: haobo, ljin

Reviewed By: haobo

CC: leveldb

Differential Revision: https://reviews.facebook.net/D17349
main
Igor Canadi 11 years ago
parent 577556d5f9
commit 726c8084cd
  1. 29
      util/env_posix.cc

@ -174,7 +174,10 @@ class PosixSequentialFile: public SequentialFile {
virtual Status Read(size_t n, Slice* result, char* scratch) { virtual Status Read(size_t n, Slice* result, char* scratch) {
Status s; Status s;
size_t r = fread_unlocked(scratch, 1, n, file_); size_t r = -1;
do {
r = fread_unlocked(scratch, 1, n, file_);
} while (r < 0 && errno == EINTR);
*result = Slice(scratch, r); *result = Slice(scratch, r);
if (r < n) { if (r < n) {
if (feof(file_)) { if (feof(file_)) {
@ -231,7 +234,10 @@ class PosixRandomAccessFile: public RandomAccessFile {
virtual Status Read(uint64_t offset, size_t n, Slice* result, virtual Status Read(uint64_t offset, size_t n, Slice* result,
char* scratch) const { char* scratch) const {
Status s; Status s;
ssize_t r = pread(fd_, scratch, n, static_cast<off_t>(offset)); ssize_t r = -1;
do {
r = pread(fd_, scratch, n, static_cast<off_t>(offset));
} while (r < 0 && errno == EINTR);
*result = Slice(scratch, (r < 0) ? 0 : r); *result = Slice(scratch, (r < 0) ? 0 : r);
if (r < 0) { if (r < 0) {
// An error: return a non-ok status // An error: return a non-ok status
@ -680,6 +686,9 @@ class PosixWritableFile : public WritableFile {
while (left != 0) { while (left != 0) {
ssize_t done = write(fd_, src, left); ssize_t done = write(fd_, src, left);
if (done < 0) { if (done < 0) {
if (errno == EINTR) {
continue;
}
return IOError(filename_, errno); return IOError(filename_, errno);
} }
TEST_KILL_RANDOM(rocksdb_kill_odds); TEST_KILL_RANDOM(rocksdb_kill_odds);
@ -727,6 +736,9 @@ class PosixWritableFile : public WritableFile {
while (left != 0) { while (left != 0) {
ssize_t done = write(fd_, src, left); ssize_t done = write(fd_, src, left);
if (done < 0) { if (done < 0) {
if (errno == EINTR) {
continue;
}
return IOError(filename_, errno); return IOError(filename_, errno);
} }
TEST_KILL_RANDOM(rocksdb_kill_odds * REDUCE_ODDS2); TEST_KILL_RANDOM(rocksdb_kill_odds * REDUCE_ODDS2);
@ -849,6 +861,9 @@ class PosixRandomRWFile : public RandomRWFile {
while (left != 0) { while (left != 0) {
ssize_t done = pwrite(fd_, src, left, offset); ssize_t done = pwrite(fd_, src, left, offset);
if (done < 0) { if (done < 0) {
if (errno == EINTR) {
continue;
}
return IOError(filename_, errno); return IOError(filename_, errno);
} }
@ -1003,7 +1018,10 @@ class PosixEnv : public Env {
unique_ptr<SequentialFile>* result, unique_ptr<SequentialFile>* result,
const EnvOptions& options) { const EnvOptions& options) {
result->reset(); result->reset();
FILE* f = fopen(fname.c_str(), "r"); FILE* f = nullptr;
do {
f = fopen(fname.c_str(), "r");
} while (f == nullptr && errno == EINTR);
if (f == nullptr) { if (f == nullptr) {
*result = nullptr; *result = nullptr;
return IOError(fname, errno); return IOError(fname, errno);
@ -1051,7 +1069,10 @@ class PosixEnv : public Env {
const EnvOptions& options) { const EnvOptions& options) {
result->reset(); result->reset();
Status s; Status s;
const int fd = open(fname.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0644); int fd = -1;
do {
fd = open(fname.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0644);
} while (fd < 0 && errno == EINTR);
if (fd < 0) { if (fd < 0) {
s = IOError(fname, errno); s = IOError(fname, errno);
} else { } else {

Loading…
Cancel
Save