0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-10 14:08:56 +02:00

ircd::fs: Add read/write options to restart operation on EINTR.

This commit is contained in:
Jason Volk 2018-12-18 14:17:38 -08:00
parent 254d5ccb50
commit 582628fb71
3 changed files with 28 additions and 2 deletions

View file

@ -57,6 +57,12 @@ struct ircd::fs::read_opts
/// any return value from a function in the read suite will not be a
/// partial value requiring another invocation of read.
bool all {true};
/// Whether to propagate an EINTR; otherwise we reinvoke the syscall. For a
/// read(2) family call this can only happen before any data was read;
/// an exception will be thrown. We default to true because we have faith
/// in the useful propagation of an exception for this event.
bool interruptible {true};
};
inline

View file

@ -79,6 +79,12 @@ struct ircd::fs::write_opts
/// any return value from a function in the write() suite will not be a
/// partial value requiring another invocation of write().
bool all {true};
/// Whether to propagate an EINTR; otherwise we reinvoke the syscall. For a
/// write(2) family call this can only happen before any data was written;
/// an exception will be thrown. We default to true because we have faith
/// in the useful propagation of an exception for this event.
bool interruptible {true};
};
inline

View file

@ -710,7 +710,14 @@ ircd::fs::read(const fd &fd,
return aio::read(fd, iov, opts);
#endif
return syscall(::preadv, fd, iov.data(), iov.size(), opts.offset);
const auto ret
{
opts.interruptible?
syscall(::preadv, fd, iov.data(), iov.size(), opts.offset):
syscall_nointr(::preadv, fd, iov.data(), iov.size(), opts.offset)
};
return size_t(ret);
}
///////////////////////////////////////////////////////////////////////////////
@ -944,7 +951,14 @@ ircd::fs::write(const fd &fd,
return aio::write(fd, iov, opts);
#endif
return size_t(syscall(::pwritev, fd, iov.data(), iov.size(), opts.offset));
const auto ret
{
opts.interruptible?
syscall(::pwritev, fd, iov.data(), iov.size(), opts.offset):
syscall_nointr(::pwritev, fd, iov.data(), iov.size(), opts.offset)
};
return size_t(ret);
}
///////////////////////////////////////////////////////////////////////////////