mirror of
https://github.com/matrix-construct/construct
synced 2024-10-06 15:48:53 +02:00
ircd::util: Add uninterruptible_syscall() for use with some POSIX syscalls.
This commit is contained in:
parent
dffe222a78
commit
14e5306713
1 changed files with 34 additions and 5 deletions
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue