This is an archive of the discontinued LLVM Phabricator instance.

[Support] Add TempFailureRetry helper function
ClosedPublic

Authored by labath on Jun 5 2017, 7:24 AM.

Details

Summary

This function retries an operation if it was interrupted by a signal
(failed with EINTR). It's inspired by the TEMP_FAILURE_RETRY macro in
glibc, but I've turned that into a template function. I've also added a
fail-value argument, to enable the function to be used with e.g.
fopen(3), which is documented to fail for any reason that open(2) can
fail (which includes EINTR).

The main user of this function will be lldb, but there were also a
couple of uses within llvm that I could simplify using this function.

Diff Detail

Repository
rL LLVM

Event Timeline

labath created this revision.Jun 5 2017, 7:24 AM

Ping. :)

Any thoughts on this? Or suggestions for other reviewers?

joerg added inline comments.Jun 14 2017, 6:19 AM
include/llvm/Support/Errno.h
39 ↗(On Diff #101404)

Maybe RetryAfterSignal. Is FailT as template really necessary or can you use the decltype(F(As...)) directly?

I like the approach otherwise.

labath updated this revision to Diff 102545.Jun 14 2017, 7:11 AM

I've renamed the function.

Decltype trick will not work for the fail value because F and As... are not yet
defined at that point (although this isn't the reason why I originally added the
extra template param). It's possible to achieve it with std::result_of though.

I've replaced the other uses of decltype with result_of as I think it would be
confusing to use both.

Is this good to go now? :)

EricWF added a subscriber: EricWF.Jun 15 2017, 12:59 PM
EricWF added inline comments.
include/llvm/Support/Errno.h
32 ↗(On Diff #102545)

The value-categories seem all messed up here. There is no reason to be using && anywhere, since all of the arguments and the function are lvalues. Personally I would write this function as:

template <typename Fun, typename... Args,
          typename ResultT = typename std::result_of<Fun const& (const Args&...)>::type>
inline ResultT RetryAfterSignal(ResultT Fail, const Fun &F, const Args &... As) {
  ResultT Res;
  do
    Res = F(As...);
  while (Res == Fail && errno == EINTR);
  return Res;
}
labath updated this revision to Diff 102792.Jun 16 2017, 2:27 AM
labath marked 2 inline comments as done.

Fix the function, as suggested by EricWF.

include/llvm/Support/Errno.h
32 ↗(On Diff #102545)

Thanks, that looks much better. I'll have to remember the extra template arg trick.

Using the correct value category is still somewhat of a mystery to me.

labath marked an inline comment as done.Jun 20 2017, 7:18 AM

If there are no further comments, can I commit this?

joerg accepted this revision.Jun 20 2017, 3:05 PM

Go ahead.

This revision is now accepted and ready to land.Jun 20 2017, 3:05 PM
This revision was automatically updated to reflect the committed changes.
labath reopened this revision.Jun 22 2017, 7:35 AM
labath added inline comments.
include/llvm/Support/Errno.h
32 ↗(On Diff #102545)

When I started using this function, I noticed that the ResultT trick did not work after all, because the template argument deduction would override the default template value. My attempt to fix that in r306003 uncovered another issue -- libc++'s implementation of std::result_of does not handle the prototype of open(2) correctly (it's a variadic function), so I've reverted this patch until that is sorted.

At this point I don't see any other solution than to go back to the initial implementation of having a separate FailT template argument, and using decltype instead of std::result_of. Do you have a better idea?

This revision is now accepted and ready to land.Jun 22 2017, 7:35 AM
labath requested review of this revision.Jun 22 2017, 7:36 AM
labath edited edge metadata.
joerg added a comment.Jun 22 2017, 8:13 AM

Do you need someone to commit this?

Do you need someone to commit this?

Thanks, but I have already committed it, and then backed it out because I ran into a wall with the std::result_of idea. :)
I reopened to review to see if you'd be ok with the original implementation with FailT and decltype.

labath updated this revision to Diff 103580.Jun 22 2017, 8:32 AM

Go back to the decltype version

This revision was automatically updated to reflect the committed changes.