// Copyright 2020 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 MOJO_CORE_CHANNEL_LINUX_H_ #define MOJO_CORE_CHANNEL_LINUX_H_ #include #include #include "build/build_config.h" #include "mojo/core/channel_posix.h" namespace mojo { namespace core { class DataAvailableNotifier; // ChannelLinux is a specialization of ChannelPosix which has support for shared // memory via Mojo channel upgrades. By default on Linux, CrOS, and Android // every channel will be of type ChannelLinux which can be upgraded at runtime // to take advantage of shared memory when all required kernel features are // present. class MOJO_SYSTEM_IMPL_EXPORT ChannelLinux : public ChannelPosix { public: ChannelLinux(Delegate* delegate, ConnectionParams connection_params, HandlePolicy handle_policy, scoped_refptr io_task_runner); ChannelLinux(const ChannelLinux&) = delete; ChannelLinux& operator=(const ChannelLinux&) = delete; // KernelSupportsUpgradeRequirements will return true if the kernel supports // the features necessary to use an upgrade channel. How the channel will be // upgraded is an implementation detail and this just tells the caller that // calling Channel::UpgradeChannel() will have some effect. static bool KernelSupportsUpgradeRequirements(); // Will return true if at least one feature that is available via upgrade is // enabled. static bool UpgradesEnabled(); // SetSharedMemParams will control whether shared memory is used for this // channel. static void SetSharedMemParameters(bool enabled, uint32_t num_pages, bool use_zero_on_wake); // ChannelPosix impl: void Write(MessagePtr message) override; void OfferSharedMemUpgrade(); bool OnControlMessage(Message::MessageType message_type, const void* payload, size_t payload_size, std::vector handles) override; void OnWriteError(Error error) override; void StartOnIOThread() override; void ShutDownOnIOThread() override; private: ~ChannelLinux() override; class SharedBuffer; void OfferSharedMemUpgradeInternal(); void SharedMemReadReady(); // We only offer once, we use an atomic flag to guarantee no races to offer. std::atomic_flag offered_{false}; // This flag keeps track of whether or not we've established a shared memory // channel with the remote. If false we always fall back to the PosixChannel // (socket). std::atomic_bool shared_mem_writer_{false}; std::unique_ptr write_notifier_; std::unique_ptr write_buffer_; std::unique_ptr read_notifier_; std::unique_ptr read_buffer_; uint32_t num_pages_ = 0; std::atomic_bool reject_writes_{false}; // This is a temporary buffer we use to remove messages from the shared buffer // for validation and dispatching. std::vector read_buf_; }; } // namespace core } // namespace mojo #endif // MOJO_CORE_CHANNEL_LINUX_H_