#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "mojo/core/channel_posix.h"
#include <errno.h>
#include <sys/socket.h>
#include <atomic>
#include <limits>
#include <memory>
#include <tuple>
#include "base/cpu_reduction_experiment.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/message_loop/message_pump_for_io.h"
#include "base/metrics/histogram_macros.h"
#include "base/synchronization/lock.h"
#include "base/task/current_thread.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/task_runner.h"
#include "base/time/time.h"
#include "base/types/fixed_array.h"
#include "build/build_config.h"
#include "mojo/public/cpp/platform/socket_utils_posix.h"
#if !BUILDFLAG(IS_NACL)
#include <limits.h>
#include <sys/uio.h>
#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID))
#include "mojo/core/channel_linux.h"
#endif
#endif
#if BUILDFLAG(IS_ANDROID)
#include "mojo/core/channel_binder.h"
#endif
namespace mojo::core {
namespace {
#if !BUILDFLAG(IS_NACL)
std::atomic<bool> g_use_writev{ … };
#endif
const size_t kMaxBatchReadCapacity = …;
}
class MessageView { … };
ChannelPosix::ChannelPosix(
Delegate* delegate,
ConnectionParams connection_params,
HandlePolicy handle_policy,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
: … { … }
ChannelPosix::~ChannelPosix() { … }
void ChannelPosix::Start() { … }
void ChannelPosix::ShutDownImpl() { … }
void ChannelPosix::Write(MessagePtr message) { … }
void ChannelPosix::LeakHandle() { … }
bool ChannelPosix::GetReadPlatformHandles(const void* payload,
size_t payload_size,
size_t num_handles,
const void* extra_header,
size_t extra_header_size,
std::vector<PlatformHandle>* handles,
bool* deferred) { … }
bool ChannelPosix::GetReadPlatformHandlesForIpcz(
size_t num_handles,
std::vector<PlatformHandle>& handles) { … }
void ChannelPosix::StartOnIOThread() { … }
void ChannelPosix::WaitForWriteOnIOThread() { … }
void ChannelPosix::WaitForWriteOnIOThreadNoLock() { … }
void ChannelPosix::ShutDownOnIOThread() { … }
void ChannelPosix::WillDestroyCurrentMessageLoop() { … }
void ChannelPosix::OnFileCanReadWithoutBlocking(int fd) { … }
void ChannelPosix::OnFileCanWriteWithoutBlocking(int fd) { … }
bool ChannelPosix::WriteNoLock(MessageView message_view) { … }
bool ChannelPosix::FlushOutgoingMessagesNoLock() { … }
void ChannelPosix::RejectUpgradeOffer() { … }
void ChannelPosix::AcceptUpgradeOffer() { … }
void ChannelPosix::OnWriteError(Error error) { … }
#if !BUILDFLAG(IS_NACL)
bool ChannelPosix::WriteOutgoingMessagesWithWritev() { … }
bool ChannelPosix::FlushOutgoingMessagesWritevNoLock() { … }
#endif
bool ChannelPosix::OnControlMessage(Message::MessageType message_type,
const void* payload,
size_t payload_size,
std::vector<PlatformHandle> handles) { … }
#if BUILDFLAG(IS_IOS)
bool ChannelPosix::CloseHandles(const int* fds, size_t num_fds) {
base::AutoLock l(fds_to_close_lock_);
if (!num_fds)
return false;
auto start = base::ranges::find(fds_to_close_, fds[0], &base::ScopedFD::get);
if (start == fds_to_close_.end())
return false;
auto it = start;
size_t i = 0;
for (; i < num_fds && it != fds_to_close_.end(); i++, ++it) {
if (it->get() != fds[i])
return false;
}
if (i != num_fds)
return false;
fds_to_close_.erase(start, it);
return true;
}
#endif
#if !BUILDFLAG(IS_NACL)
void Channel::set_posix_use_writev(bool use_writev) { … }
#endif
scoped_refptr<Channel> Channel::Create(
Delegate* delegate,
ConnectionParams connection_params,
HandlePolicy handle_policy,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) { … }
#if !BUILDFLAG(IS_NACL)
#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID))
bool Channel::SupportsChannelUpgrade() { … }
void Channel::OfferChannelUpgrade() { … }
#endif
#endif
}