// Copyright (c) 2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_COMMON_IPC_CHANNEL_MACH_H_ #define CHROME_COMMON_IPC_CHANNEL_MACH_H_ #include "chrome/common/ipc_channel.h" #include "base/message_loop.h" #include "base/process.h" #include "mozilla/EventTargetAndLockCapability.h" #include "mozilla/Maybe.h" #include "mozilla/Mutex.h" #include "mozilla/Queue.h" #include "mozilla/UniquePtr.h" #include "mozilla/UniquePtrExtensions.h" #include "nsISupports.h" namespace IPC { // An implementation of ChannelImpl for macOS and iOS that works via // mach ports. See the .cc file for an overview of the implementation. class ChannelMach final : public Channel, public MessageLoopForIO::MachPortWatcher { public: ChannelMach(mozilla::UniqueMachReceiveRight receive, mozilla::UniqueMachSendRight send, Mode mode, base::ProcessId other_pid); bool Connect(Listener* listener) MOZ_EXCLUDES(SendMutex()) override; void Close() MOZ_EXCLUDES(SendMutex()) override; // NOTE: `Send` may be called on threads other than the I/O thread. bool Send(mozilla::UniquePtr message) MOZ_EXCLUDES(SendMutex()) override; void SetOtherPid(base::ProcessId other_pid) override; // These are only relevant to ChannelPosix, so we ignore them. void SetOtherMachTask(task_t) override {} const ChannelKind* GetKind() const override { return &sKind; } static const ChannelKind sKind; private: ~ChannelMach() { Close(); } static bool CreateRawPipe(ChannelHandle* server, ChannelHandle* client); static bool CreateRawPipe(mozilla::UniqueMachReceiveRight* server, mozilla::UniqueMachSendRight* client); static uint32_t NumRelayedAttachments(const Message& message); static bool IsValidHandle(const ChannelHandle& handle); bool EnqueueHelloMessage() MOZ_REQUIRES(SendMutex(), IOThread()); bool ContinueConnect(mozilla::UniqueMachSendRight send_port) MOZ_REQUIRES(SendMutex(), IOThread()); void CloseLocked() MOZ_REQUIRES(SendMutex(), IOThread()); bool ProcessIncomingMessage() MOZ_REQUIRES(IOThread()); bool ProcessOutgoingMessages() MOZ_REQUIRES(SendMutex()); // MessageLoopForIO::MachPortWatcher implementation. virtual void OnMachMessageReceived(mach_port_t port) override; void OutputQueuePush(mozilla::UniquePtr msg) MOZ_REQUIRES(SendMutex()); void OutputQueuePop() MOZ_REQUIRES(SendMutex()); // Watch controller for |receive_port_|, calls OnMachMessageReceived() when // new messages are available. MessageLoopForIO::MachPortWatchController watch_controller_; // We always initialize |receive_port_| in the constructor, but |send_port_| // may not be initialized until we've received a message from our peer. mozilla::UniqueMachReceiveRight receive_port_ MOZ_GUARDED_BY(chan_cap_); mozilla::UniqueMachSendRight send_port_ MOZ_GUARDED_BY(chan_cap_); Listener* listener_ MOZ_GUARDED_BY(IOThread()) = nullptr; // Buffers used for constructing mach IPC message payloads. mozilla::UniquePtr send_buffer_ MOZ_GUARDED_BY(SendMutex()); mozilla::UniquePtr receive_buffer_ MOZ_GUARDED_BY(IOThread()); // Messages to be sent are queued here. mozilla::Queue, 64> output_queue_ MOZ_GUARDED_BY(SendMutex()); // Indicates whether we've already serialized into the send buffer. bool send_buffer_has_message_ MOZ_GUARDED_BY(SendMutex()) = false; // Will be set to `true` until `Connect()` has been called and communication // is ready. bool waiting_connect_ MOZ_GUARDED_BY(chan_cap_) = true; // We keep track of the PID of the other side of this channel so that we can // record this when generating logs of IPC messages. base::ProcessId other_pid_ MOZ_GUARDED_BY(chan_cap_) = base::kInvalidProcessId; mozilla::Maybe peer_audit_token_ MOZ_GUARDED_BY(IOThread()); }; } // namespace IPC #endif // CHROME_COMMON_IPC_CHANNEL_MACH_H_