# define TEMP_FAILURE_RETRY(expression) \
(__extension__ \
({ long int __result; \
do __result = (long int) (expression); \
while (__result == -1L && errno == EINTR); \
__result; }))
#endif
and 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