Unify FileFd::read implementation.

GitOrigin-RevId: bfe86b448459ba7ef875256d99796122bb486e4d
This commit is contained in:
levlam 2018-09-11 17:13:53 +03:00
parent 10118d0449
commit 94f2fca814

View File

@ -201,144 +201,85 @@ FileFd FileFd::from_native_fd(NativeFd native_fd) {
} }
Result<size_t> FileFd::write(Slice slice) { Result<size_t> FileFd::write(Slice slice) {
auto native_fd = get_native_fd().fd();
#if TD_PORT_POSIX #if TD_PORT_POSIX
auto native_fd = get_native_fd().fd(); auto bytes_written = detail::skip_eintr([&] { return ::write(native_fd, slice.begin(), slice.size()); });
auto write_res = detail::skip_eintr([&] { return ::write(native_fd, slice.begin(), slice.size()); }); bool success = bytes_written >= 0;
if (write_res >= 0) {
return narrow_cast<size_t>(write_res);
}
auto write_errno = errno;
auto error = Status::PosixError(write_errno, PSLICE() << "Write to [fd = " << native_fd << "] has failed");
if (write_errno != EAGAIN
#if EAGAIN != EWOULDBLOCK
&& write_errno != EWOULDBLOCK
#endif
&& write_errno != EIO) {
LOG(ERROR) << error;
}
return std::move(error);
#elif TD_PORT_WINDOWS #elif TD_PORT_WINDOWS
auto native_fd = get_native_fd().fd();
DWORD bytes_written = 0; DWORD bytes_written = 0;
auto res = WriteFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_written, nullptr); BOOL success = WriteFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_written, nullptr);
if (res) { #endif
return bytes_written; if (success) {
return narrow_cast<size_t>(bytes_written);
} }
return OS_ERROR(PSLICE() << "Write to [fd = " << native_fd << "] has failed"); return OS_ERROR(PSLICE() << "Write to [fd = " << native_fd << "] has failed");
#endif
} }
Result<size_t> FileFd::read(MutableSlice slice) { Result<size_t> FileFd::read(MutableSlice slice) {
auto native_fd = get_native_fd().fd();
#if TD_PORT_POSIX #if TD_PORT_POSIX
auto native_fd = get_native_fd().fd(); auto bytes_read = detail::skip_eintr([&] { return ::read(native_fd, slice.begin(), slice.size()); });
auto read_res = detail::skip_eintr([&] { return ::read(native_fd, slice.begin(), slice.size()); }); bool success = bytes_read >= 0;
auto read_errno = errno; bool is_eof = narrow_cast<size_t>(bytes_read) < slice.size();
if (read_res >= 0) {
if (narrow_cast<size_t>(read_res) < slice.size()) {
get_poll_info().clear_flags(PollFlags::Read());
}
return static_cast<size_t>(read_res);
}
auto error = Status::PosixError(read_errno, PSLICE() << "Read from [fd = " << native_fd << "] has failed");
if (read_errno != EAGAIN
#if EAGAIN != EWOULDBLOCK
&& read_errno != EWOULDBLOCK
#endif
&& read_errno != EIO) {
LOG(ERROR) << error;
}
return std::move(error);
#elif TD_PORT_WINDOWS #elif TD_PORT_WINDOWS
auto native_fd = get_native_fd().fd();
DWORD bytes_read = 0; DWORD bytes_read = 0;
auto res = ReadFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_read, nullptr); BOOL success = ReadFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_read, nullptr);
if (res) { bool is_eof = bytes_read == 0;
if (bytes_read == 0) { #endif
if (success) {
if (is_eof) {
get_poll_info().clear_flags(PollFlags::Read()); get_poll_info().clear_flags(PollFlags::Read());
} }
return static_cast<size_t>(bytes_read); return static_cast<size_t>(bytes_read);
} }
return OS_ERROR(PSLICE() << "Read from [fd = " << native_fd << "] has failed"); return OS_ERROR(PSLICE() << "Read from [fd = " << native_fd << "] has failed");
#endif
} }
Result<size_t> FileFd::pwrite(Slice slice, int64 offset) { Result<size_t> FileFd::pwrite(Slice slice, int64 offset) {
if (offset < 0) { if (offset < 0) {
return Status::Error("Offset must be non-negative"); return Status::Error("Offset must be non-negative");
} }
auto native_fd = get_native_fd().fd();
#if TD_PORT_POSIX #if TD_PORT_POSIX
auto native_fd = get_native_fd().fd();
TRY_RESULT(offset_off_t, narrow_cast_safe<off_t>(offset)); TRY_RESULT(offset_off_t, narrow_cast_safe<off_t>(offset));
auto pwrite_res = detail::skip_eintr([&] { return ::pwrite(native_fd, slice.begin(), slice.size(), offset_off_t); }); auto bytes_written =
if (pwrite_res >= 0) { detail::skip_eintr([&] { return ::pwrite(native_fd, slice.begin(), slice.size(), offset_off_t); });
return narrow_cast<size_t>(pwrite_res); bool success = bytes_written >= 0;
}
auto pwrite_errno = errno;
auto error = Status::PosixError(
pwrite_errno, PSLICE() << "Pwrite to [fd = " << native_fd << "] at [offset = " << offset << "] has failed");
if (pwrite_errno != EAGAIN
#if EAGAIN != EWOULDBLOCK
&& pwrite_errno != EWOULDBLOCK
#endif
&& pwrite_errno != EIO) {
LOG(ERROR) << error;
}
return std::move(error);
#elif TD_PORT_WINDOWS #elif TD_PORT_WINDOWS
auto native_fd = get_native_fd().fd();
DWORD bytes_written = 0; DWORD bytes_written = 0;
OVERLAPPED overlapped; OVERLAPPED overlapped;
std::memset(&overlapped, 0, sizeof(overlapped)); std::memset(&overlapped, 0, sizeof(overlapped));
overlapped.Offset = static_cast<DWORD>(offset); overlapped.Offset = static_cast<DWORD>(offset);
overlapped.OffsetHigh = static_cast<DWORD>(offset >> 32); overlapped.OffsetHigh = static_cast<DWORD>(offset >> 32);
auto res = WriteFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_written, &overlapped); BOOL success = WriteFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_written, &overlapped);
if (res) { #endif
return bytes_written; if (success) {
return narrow_cast<size_t>(bytes_written);
} }
return OS_ERROR(PSLICE() << "Pwrite to [fd = " << native_fd << "] at [offset = " << offset << "] has failed"); return OS_ERROR(PSLICE() << "Pwrite to [fd = " << native_fd << "] at [offset = " << offset << "] has failed");
#endif
} }
Result<size_t> FileFd::pread(MutableSlice slice, int64 offset) { Result<size_t> FileFd::pread(MutableSlice slice, int64 offset) {
if (offset < 0) { if (offset < 0) {
return Status::Error("Offset must be non-negative"); return Status::Error("Offset must be non-negative");
} }
auto native_fd = get_native_fd().fd();
#if TD_PORT_POSIX #if TD_PORT_POSIX
auto native_fd = get_native_fd().fd();
TRY_RESULT(offset_off_t, narrow_cast_safe<off_t>(offset)); TRY_RESULT(offset_off_t, narrow_cast_safe<off_t>(offset));
auto pread_res = detail::skip_eintr([&] { return ::pread(native_fd, slice.begin(), slice.size(), offset_off_t); }); auto bytes_read = detail::skip_eintr([&] { return ::pread(native_fd, slice.begin(), slice.size(), offset_off_t); });
if (pread_res >= 0) { bool success = bytes_read >= 0;
return narrow_cast<size_t>(pread_res);
}
auto pread_errno = errno;
auto error = Status::PosixError(
pread_errno, PSLICE() << "Pread from [fd = " << native_fd << "] at [offset = " << offset << "] has failed");
if (pread_errno != EAGAIN
#if EAGAIN != EWOULDBLOCK
&& pread_errno != EWOULDBLOCK
#endif
&& pread_errno != EIO) {
LOG(ERROR) << error;
}
return std::move(error);
#elif TD_PORT_WINDOWS #elif TD_PORT_WINDOWS
auto native_fd = get_native_fd().fd();
DWORD bytes_read = 0; DWORD bytes_read = 0;
OVERLAPPED overlapped; OVERLAPPED overlapped;
std::memset(&overlapped, 0, sizeof(overlapped)); std::memset(&overlapped, 0, sizeof(overlapped));
overlapped.Offset = static_cast<DWORD>(offset); overlapped.Offset = static_cast<DWORD>(offset);
overlapped.OffsetHigh = static_cast<DWORD>(offset >> 32); overlapped.OffsetHigh = static_cast<DWORD>(offset >> 32);
auto res = ReadFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_read, &overlapped); BOOL success = ReadFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_read, &overlapped);
if (res) { #endif
return bytes_read; if (success) {
return narrow_cast<size_t>(bytes_read);
} }
return OS_ERROR(PSLICE() << "Pread from [fd = " << native_fd << "] at [offset = " << offset << "] has failed"); return OS_ERROR(PSLICE() << "Pread from [fd = " << native_fd << "] at [offset = " << offset << "] has failed");
#endif
} }
Status FileFd::lock(FileFd::LockFlags flags, int32 max_tries) { Status FileFd::lock(FileFd::LockFlags flags, int32 max_tries) {