mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 988251 - Enable sending more than 4 file descriptors in the IPC channel (r=bent)
This commit is contained in:
parent
81c8d70bcc
commit
8c69e33908
@ -21,16 +21,10 @@ class FileDescriptorSet : public base::RefCountedThreadSafe<FileDescriptorSet> {
|
||||
FileDescriptorSet();
|
||||
~FileDescriptorSet();
|
||||
|
||||
// This is the maximum number of descriptors per message. We need to know this
|
||||
// because the control message kernel interface has to be given a buffer which
|
||||
// is large enough to store all the descriptor numbers. Otherwise the kernel
|
||||
// tells us that it truncated the control data and the extra descriptors are
|
||||
// lost.
|
||||
//
|
||||
// In debugging mode, it's a fatal error to try and add more than this number
|
||||
// of descriptors to a FileDescriptorSet.
|
||||
// Mac and Linux both limit the number of file descriptors per message to
|
||||
// slightly more than 250.
|
||||
enum {
|
||||
MAX_DESCRIPTORS_PER_MESSAGE = 7
|
||||
MAX_DESCRIPTORS_PER_MESSAGE = 250
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -283,6 +283,8 @@ Channel::ChannelImpl::ChannelImpl(int fd, Mode mode, Listener* listener)
|
||||
}
|
||||
|
||||
void Channel::ChannelImpl::Init(Mode mode, Listener* listener) {
|
||||
DCHECK(kControlBufferSlopBytes >= CMSG_SPACE(0));
|
||||
|
||||
mode_ = mode;
|
||||
is_blocked_on_write_ = false;
|
||||
message_send_bytes_written_ = 0;
|
||||
|
@ -103,20 +103,27 @@ class Channel::ChannelImpl : public MessageLoopForIO::Watcher {
|
||||
// We read from the pipe into this buffer
|
||||
char input_buf_[Channel::kReadBufferSize];
|
||||
|
||||
// We want input_cmsg_buf_ to be big enough to hold
|
||||
// CMSG_SPACE(Channel::kReadBufferSize) bytes (see the comment below for an
|
||||
// explanation of where Channel::kReadBufferSize comes from). However,
|
||||
// CMSG_SPACE is apparently not a constant on Macs, so we can't use it in the
|
||||
// array size. Consequently, we pick a number here that is at least
|
||||
// CMSG_SPACE(0) on all platforms. And we assert at runtime, in
|
||||
// Channel::ChannelImpl::Init, that it's big enough.
|
||||
enum {
|
||||
// We assume a worst case: kReadBufferSize bytes of messages, where each
|
||||
// message has no payload and a full complement of descriptors.
|
||||
MAX_READ_FDS = (Channel::kReadBufferSize / sizeof(IPC::Message::Header)) *
|
||||
FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE
|
||||
kControlBufferSlopBytes = 32
|
||||
};
|
||||
|
||||
// This is a control message buffer large enough to hold kMaxReadFDs
|
||||
#if defined(OS_MACOSX) || defined(OS_NETBSD)
|
||||
// TODO(agl): OSX appears to have non-constant CMSG macros!
|
||||
char input_cmsg_buf_[1024];
|
||||
#else
|
||||
char input_cmsg_buf_[CMSG_SPACE(sizeof(int) * MAX_READ_FDS)];
|
||||
#endif
|
||||
// This is a control message buffer large enough to hold all the file
|
||||
// descriptors that will be read in when reading Channel::kReadBufferSize
|
||||
// bytes of data. Message::WriteFileDescriptor always writes one word of
|
||||
// data for every file descriptor added to the message, so kReadBufferSize
|
||||
// bytes of data can never be accompanied by more than
|
||||
// kReadBufferSize / sizeof(int) file descriptors. Since a file descriptor
|
||||
// takes sizeof(int) bytes, the control buffer must be
|
||||
// Channel::kReadBufferSize bytes. We add kControlBufferSlopBytes bytes
|
||||
// for the control header.
|
||||
char input_cmsg_buf_[Channel::kReadBufferSize + kControlBufferSlopBytes];
|
||||
|
||||
// Large messages that span multiple pipe buffers, get built-up using
|
||||
// this buffer.
|
||||
|
@ -128,6 +128,8 @@ void Message::set_received_time(int64_t time) const {
|
||||
bool Message::WriteFileDescriptor(const base::FileDescriptor& descriptor) {
|
||||
// We write the index of the descriptor so that we don't have to
|
||||
// keep the current descriptor as extra decoding state when deserialising.
|
||||
// Also, we rely on each file descriptor being accompanied by sizeof(int)
|
||||
// bytes of data in the message. See the comment for input_cmsg_buf_.
|
||||
WriteInt(file_descriptor_set()->size());
|
||||
if (descriptor.auto_close) {
|
||||
return file_descriptor_set()->AddAndAutoClose(descriptor.fd);
|
||||
|
Loading…
Reference in New Issue
Block a user