Bug 17168 - Can GLibc expose futex now?
Summary: Can GLibc expose futex now?
Status: RESOLVED DUPLICATE of bug 9712
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: unspecified
: P2 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-07-17 04:44 UTC by Steven Stewart-Gallus
Modified: 2014-07-19 18:55 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Steven Stewart-Gallus 2014-07-17 04:44:43 UTC
Most application writers should use standard pthread synchronization
functionality and not use low level functionality instead.  However,
certain performance concerned programmers might want to use futexes
directly.  Unfortunately, as FUTEX_WAIT is a blocking system call this
leaves a critical piece of functionality unimplemented and missing.
In the past, one could have used FUTEX_FD to wait on memory locations
to change asynchronously (although it would have been racy).  However,
FUTEX_FD is not supported anymore on Linux (as it is racy).  Now, the
only choice to use FUTEX_WAIT asynchronously is to use multiple
threads and cancel the thread waiting on the memory location to
change.  Except one can't as futex is not exposed by GLibc and I do
not want to try reimplementing pthread_cancel myself which might be
seriously difficult.  Taking the five seconds to wrap the futex calls
with the syscall function is not a problem but I can't use futex
asynchronously without support from GLibc.
Comment 1 Steven Stewart-Gallus 2014-07-17 04:57:14 UTC
This really isn't a huge problem because I can use timeouts and eventfds instead for most purposes but it is a bit annoying.
Comment 2 Steven Stewart-Gallus 2014-07-19 01:10:03 UTC
I'm confused, in the source in nptl/nptl-init.c the signal handler is
not set with the flag for the SA_RESTART and so I should be able to
simply handle pthread_cancel by waiting for EINTR and then using
pthread_testcancel? However, pthread_cancel only seems to send the
signal when asynchronous cancels are enabled and not for deferred
cancels?

The source:

  struct sigaction sa;
  sa.sa_sigaction = sigcancel_handler;
  sa.sa_flags = SA_SIGINFO;
  __sigemptyset (&sa.sa_mask);

  (void) __libc_sigaction (SIGCANCEL, &sa, NULL);

The possible workaround:

static errno_t futex_wait(int *uaddr, int val, struct timespec const *timeout)
{
    int xx = syscall(__NR_futex, (intptr_t)uaddr, (intptr_t)FUTEX_WAIT,
                     (intptr_t)val,
                     (intptr_t)timeout);
    if (xx < 0) {
        errno_t errnum = errno;
        if (EINTR == errnum) {
            pthread_testcancel();
        }
        return errnum;
    }

    return 0;
}
Comment 3 Steven Stewart-Gallus 2014-07-19 18:34:34 UTC
Note that I could set the cancellation state to asynchronous and
synchronous back again but that'd have the same problems as with
https://sourceware.org/bugzilla/show_bug.cgi?id=12683 . In particular,
a FUTEX_WAIT could consume a notification but not act on it. As well,
someone could jump out of a signal handler and leave the cancellation
state set to asynchronous.
Comment 4 Rich Felker 2014-07-19 18:55:06 UTC
This seems to be a request for a feature for which there is already an open request, issue #9712.

*** This bug has been marked as a duplicate of bug 9712 ***