# define TEMP_FAILURE_RETRY(expression) \ (__extension__ \ ({ long int __result; \ do __result = (long int) (expression); \ while (__result == -1L && errno == EINTR); \ __result; })) #endifand it wasn't exactly easy to find the pieces to get that done by googling (Nor was it particularly easy to get blogger to display this article correctly!). I did eventually find it and present it here for reference by my future-self, in a template function I called uninterrupted. Instead of
return TEMP_FAILURE_RETRY(read(sockFd, buf, len, flags));you would write
return uninterrupted(read, sockFd, buf, len, flags);The glue that gets it done looks like this:
template< class F, class... Args > inline auto uninterrupted(F&& f, Args&&...args) -> decltype(std::forward<F>(f)(std::forward<Args>(args)...)) { decltype(std::forward<F>(f)(std::forward<Args>(args)...)) rc; do { rc = std::forward<F>(f)(std::forward<Args>(args)...); } while(rc == static_cast<decltype(rc)>(-1) && errno == EINTR); return rc; }It's type-safe. It's easy to use. It's concise. And a modern compiler will optimize it down to assembler that's as tight or more so, as what C could produce with the macro that inspired it. And you don't have to worry about getting all the trailing back-slashes right when you write it!
If that's "too geeky for you", fine... just keep moving.
No comments:
Post a Comment