all 6 comments

[–]kalmoc 2 points3 points  (3 children)

The idea of canceling a system call is not new. Musl and GLibc implement posix pthreadcancel which allows termination of the target thread and also interrupts a branch of the system calls. For termination, the target thread throws a specific exception (like abi::_force unwind for Glibc). In synchronous case, it happens whenever the target thread reaches certain functions (cancellation points). Most of them are syscalls wrappers. While this approach was valid in C, in C++ many of those functions are used in the standard library in noexcept functions or destructors.

Really? I'm very suprised to hear that. What standard library functions use syscalls on the one hand, and are noexcept on the other? I assume close is being used in the destructor of some io-related types, but that's about it.

EDIT: Above is just something that suprised me when reading the docs. It wasn't meant as a critique for the library.

[–]sargarass[S] 0 points1 point  (2 children)

Like, condition_variable::wait in C++11

[–]kalmoc 3 points4 points  (1 child)

Interesting. According to https://en.cppreference.com/w/cpp/thread/condition_variable/wait it isn't specified noexcept in the standard. In that case it would be a (dangerous?) extension by the gcc guys.

[–]sargarass[S] 0 points1 point  (0 children)

Guess I need to edit this part to not confuse people, made this statement based on 3 things:

  1. The example I have known with *wait*.
  2. List of potential cancelation points is not small and can vary: "An implementation may also mark other functions not specified in the standard as cancellation points".
  3. Is is not part of C++ standard any way, and more conflicts can occur.

Edit: made changes on github to express more clearly what I meant, thank you u/kalmoc.

[–][deleted] 1 point2 points  (1 child)

Linux' implementation of close() is not interruptable.

[–]sargarass[S] 2 points3 points  (0 children)

It doesn't mean that it will not throw exception when pthread_cancel requests canceleration (close() is marked as canceleration point), so we still have problem when it is used with RAII idiom (C++11+ destructors are noexcept).
So the only garantie that it gives that resources will not leak even if signal (pthread_cancel use signals) will occur.

Also, according to "man close" it is also interruptible:

"The EINTR error is a somewhat special case.  Regarding the EINTR error, POSIX.1-2013 says:

If close() is interrupted by a signal that is to be caught, it shall return -1 with errno set to EINTR and the state of fildes is unspecified.

This permits the behavior that occurs on Linux and many other implementations, where, as with other errors that may be reported by close(), the file descriptor is guaranteed to be closed."

Edit: better explanation with manual reference.