From 14e530671359fa225584d332411629c1e3bb8b37 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Wed, 11 Oct 2017 17:48:16 -0700 Subject: [PATCH] ircd::util: Add uninterruptible_syscall() for use with some POSIX syscalls. --- include/ircd/util.h | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/include/ircd/util.h b/include/ircd/util.h index 87ed10aed..9511d09a2 100644 --- a/include/ircd/util.h +++ b/include/ircd/util.h @@ -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 +auto +syscall(function&& f, + args&&... a) +-> typename std::enable_if::value, int>::type +{ + const int ret + { + f(std::forward(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 // syscall(read, foo, bar, baz) not a macro like syscall(read(foo, bar, baz)); // -template auto -syscall(function&& f, - args&&... a) +uninterruptible_syscall(function&& f, + args&&... a) +-> typename std::enable_if::value, int>::type { - const auto ret(f(a...)); - if(unlikely(long(ret) == -1)) + int ret; do + { + ret = f(std::forward(a)...); + } + while(unlikely(ret == ERROR_CODE && errno == EINTR)); + + if(unlikely(ret == ERROR_CODE)) throw std::system_error(errno, std::system_category()); return ret;