folly
folly copied to clipboard
EventBaseAtomicNotificationQueue NotifyFd function crashes on android system
terminating with uncaught exception of type std::__ndk1::system_error: failed to signal AtomicNotificationQueue after write32: Broken pipe
@Robin Cheng @yfeldblum
template <typename Task, typename Consumer>
void EventBaseAtomicNotificationQueue<Task, Consumer>::notifyFd() {
checkPid();
ssize_t bytes_written = 0;
size_t bytes_expected = 0;
do {
if (eventfd_ >= 0) {
// eventfd(2) dictates that we must write a 64-bit integer
uint64_t signal = 1;
bytes_expected = sizeof(signal);
bytes_written = ::write(eventfd_, &signal, bytes_expected);
} else {
uint8_t signal = 1;
bytes_expected = sizeof(signal);
bytes_written = ::write(pipeFds_[1], &signal, bytes_expected);
}
} while (bytes_written == -1 && errno == EINTR);
if (bytes_written != ssize_t(bytes_expected)) {
folly::throwSystemError(
"failed to signal AtomicNotificationQueue after "
"write",
errno);
}
}
I haven't updated to the latest folly yet. I would like to ask whether the following changes have fixed the crash problem above?
- Unregister event handler fd before closing the fd in EventBaseAtomicNotificationQueue.
Summary: Thread 1:
- Creates an eventfd X
- Registers X with an event base
- Closes X
- Unregisters X from the event base
Thread 2:
- Creates some other file descriptor (eventfd or socket or whatever); the operating system reuses file descriptor #X.
The unregistering of X from the event base in thread 1 races with the opening of reused X in thread 2.
The fix is to unregister X before closing X.
Reviewed By: yfeldblum
Differential Revision: D27962155
fbshipit-source-id: 1bcb62c7ebe0297ab9687e1a0edf37d319637fda