mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 1142693 - Recognize EMSGSIZE as non-fatal on OS X for IPC sendmsg(). r=bent
Loosely based on Chromium git commit 86c3d9ef4fdf, but redone to insert a sched_yield(), because treating EMSGSIZE as if it were EAGAIN/EWOULDBLOCK is (as the Chromium developers note) likely to act as a busy-wait for the receiver to make progress.
This commit is contained in:
parent
ddba70e696
commit
9596875de6
@ -6,6 +6,9 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#if defined(OS_MACOSX)
|
||||
#include <sched.h>
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
@ -724,9 +727,39 @@ bool Channel::ChannelImpl::ProcessOutgoingMessages() {
|
||||
msg->file_descriptor_set()->CommitAll();
|
||||
#endif
|
||||
|
||||
if (bytes_written < 0 && errno != EAGAIN) {
|
||||
CHROMIUM_LOG(ERROR) << "pipe error: " << strerror(errno);
|
||||
return false;
|
||||
if (bytes_written < 0) {
|
||||
switch (errno) {
|
||||
case EAGAIN:
|
||||
// Not an error; the sendmsg would have blocked, so return to the
|
||||
// event loop and try again later.
|
||||
break;
|
||||
#if defined(OS_MACOSX)
|
||||
// (Note: this comment is copied from https://crrev.com/86c3d9ef4fdf6;
|
||||
// see also bug 1142693 comment #73.)
|
||||
//
|
||||
// On OS X if sendmsg() is trying to send fds between processes and
|
||||
// there isn't enough room in the output buffer to send the fd
|
||||
// structure over atomically then EMSGSIZE is returned.
|
||||
//
|
||||
// EMSGSIZE presents a problem since the system APIs can only call us
|
||||
// when there's room in the socket buffer and not when there is
|
||||
// "enough" room.
|
||||
//
|
||||
// The current behavior is to return to the event loop when EMSGSIZE
|
||||
// is received and hopefull service another FD. This is however still
|
||||
// technically a busy wait since the event loop will call us right
|
||||
// back until the receiver has read enough data to allow passing the
|
||||
// FD over atomically.
|
||||
case EMSGSIZE:
|
||||
// Because this is likely to result in a busy-wait, we'll try to make
|
||||
// it easier for the receiver to make progress.
|
||||
sched_yield();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
CHROMIUM_LOG(ERROR) << "pipe error: " << strerror(errno);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (static_cast<size_t>(bytes_written) != amt_to_write) {
|
||||
|
Loading…
Reference in New Issue
Block a user