0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-09-06 08:45:20 +02:00

ircd::util: Add uninterruptible_syscall() for use with some POSIX syscalls.

This commit is contained in:
Jason Volk 2017-10-11 17:48:16 -07:00
parent dffe222a78
commit 14e5306713

View file

@ -820,19 +820,48 @@ struct values
}; };
//
// Error-checking closure for POSIX system calls. Note the usage is
// syscall(read, foo, bar, baz) not a macro like syscall(read(foo, bar, baz));
//
template<long ERROR_CODE = -1,
class function,
class... args>
auto
syscall(function&& f,
args&&... a)
-> typename std::enable_if<std::is_same<int, decltype(f(a...))>::value, int>::type
{
const int ret
{
f(std::forward<args>(a)...)
};
if(unlikely(ret == ERROR_CODE))
throw std::system_error(errno, std::system_category());
return ret;
}
// //
// Error-checking closure for POSIX system calls. Note the usage is // Error-checking closure for POSIX system calls. Note the usage is
// syscall(read, foo, bar, baz) not a macro like syscall(read(foo, bar, baz)); // syscall(read, foo, bar, baz) not a macro like syscall(read(foo, bar, baz));
// //
template<class function, template<long ERROR_CODE = -1,
class function,
class... args> class... args>
auto auto
syscall(function&& f, uninterruptible_syscall(function&& f,
args&&... a) args&&... a)
-> typename std::enable_if<std::is_same<int, decltype(f(a...))>::value, int>::type
{ {
const auto ret(f(a...)); int ret; do
if(unlikely(long(ret) == -1)) {
ret = f(std::forward<args>(a)...);
}
while(unlikely(ret == ERROR_CODE && errno == EINTR));
if(unlikely(ret == ERROR_CODE))
throw std::system_error(errno, std::system_category()); throw std::system_error(errno, std::system_category());
return ret; return ret;