blob: e5c0acab16a46534dd0a7b60aa16195b9c1f18af [file] [log] [blame]
Avi Drissmand387f0922022-09-14 20:51:311// Copyright 2020 The Chromium Authors
Brian Geffone6bc5ff2021-01-05 20:07:482// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef MOJO_CORE_CHANNEL_POSIX_H_
6#define MOJO_CORE_CHANNEL_POSIX_H_
7
Joseph Koshy23851dc2022-12-16 18:02:498#include "base/containers/circular_deque.h"
Lei Zhangb8567682023-01-06 17:54:049#include "base/memory/scoped_refptr.h"
Ken Rockot49a5e7a22024-11-28 00:43:2110#include "base/message_loop/io_watcher.h"
Brian Geffone6bc5ff2021-01-05 20:07:4811#include "base/synchronization/lock.h"
12#include "base/task/current_thread.h"
Sean Mahere672a662023-01-09 21:42:2813#include "base/task/single_thread_task_runner.h"
Peter Boströmd5c1e1442024-01-31 21:38:5014#include "base/thread_annotations.h"
Brian Geffone6bc5ff2021-01-05 20:07:4815#include "build/build_config.h"
Ken Rockot49a5e7a22024-11-28 00:43:2116#include "mojo/core/channel.h"
Brian Geffone6bc5ff2021-01-05 20:07:4817
18namespace mojo {
19namespace core {
20
21class MessageView;
22
23class ChannelPosix : public Channel,
24 public base::CurrentThread::DestructionObserver,
Ken Rockot49a5e7a22024-11-28 00:43:2125 public base::IOWatcher::FdWatcher {
Brian Geffone6bc5ff2021-01-05 20:07:4826 public:
27 ChannelPosix(Delegate* delegate,
28 ConnectionParams connection_params,
29 HandlePolicy handle_policy,
30 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
31
Peter Boströmfeef05a2021-10-05 21:35:0832 ChannelPosix(const ChannelPosix&) = delete;
33 ChannelPosix& operator=(const ChannelPosix&) = delete;
34
Brian Geffone6bc5ff2021-01-05 20:07:4835 void Start() override;
36 void ShutDownImpl() override;
Peter Boströmd5c1e1442024-01-31 21:38:5037 void Write(MessagePtr message) override LOCKS_EXCLUDED(write_lock_);
Brian Geffone6bc5ff2021-01-05 20:07:4838 void LeakHandle() override;
39 bool GetReadPlatformHandles(const void* payload,
40 size_t payload_size,
41 size_t num_handles,
42 const void* extra_header,
43 size_t extra_header_size,
44 std::vector<PlatformHandle>* handles,
45 bool* deferred) override;
Ken Rockot36d44a572022-08-15 23:19:5746 bool GetReadPlatformHandlesForIpcz(
47 size_t num_handles,
48 std::vector<PlatformHandle>& handles) override;
Brian Geffon12b581a2021-02-03 23:48:0349 bool OnControlMessage(Message::MessageType message_type,
50 const void* payload,
51 size_t payload_size,
52 std::vector<PlatformHandle> handles) override;
53
54 protected:
55 ~ChannelPosix() override;
Peter Boströmd5c1e1442024-01-31 21:38:5056 virtual void StartOnIOThread() LOCKS_EXCLUDED(write_lock_);
57 virtual void ShutDownOnIOThread() LOCKS_EXCLUDED(write_lock_
58#if BUILDFLAG(IS_IOS)
59 ,
60 fds_to_close_lock_
61#endif // BUILDFLAG(IS_IOS)
62 );
63 virtual void OnWriteError(Error error) LOCKS_EXCLUDED(write_lock_);
Brian Geffon12b581a2021-02-03 23:48:0364
65 void RejectUpgradeOffer();
66 void AcceptUpgradeOffer();
67
68 // Keeps the Channel alive at least until explicit shutdown on the IO thread.
69 scoped_refptr<Channel> self_;
70
71 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
Brian Geffone6bc5ff2021-01-05 20:07:4872
73 private:
Peter Boströmd5c1e1442024-01-31 21:38:5074 void WaitForWriteOnIOThread() LOCKS_EXCLUDED(write_lock_);
75 void WaitForWriteOnIOThreadNoLock() EXCLUSIVE_LOCKS_REQUIRED(write_lock_);
Brian Geffone6bc5ff2021-01-05 20:07:4876
77 // base::CurrentThread::DestructionObserver:
78 void WillDestroyCurrentMessageLoop() override;
79
Ken Rockot49a5e7a22024-11-28 00:43:2180 // base::IOWatcher::FdWatcher:
81 void OnFdReadable(int fd) override;
82 void OnFdWritable(int fd) override LOCKS_EXCLUDED(write_lock_);
Brian Geffone6bc5ff2021-01-05 20:07:4883
84 // Attempts to write a message directly to the channel. If the full message
85 // cannot be written, it's queued and a wait is initiated to write the message
86 // ASAP on the I/O thread.
Peter Boströmd5c1e1442024-01-31 21:38:5087 bool WriteNoLock(MessageView message_view)
88 EXCLUSIVE_LOCKS_REQUIRED(write_lock_)
89#if BUILDFLAG(IS_IOS)
90 LOCKS_EXCLUDED(fds_to_close_lock_)
91#endif // BUILDFLAG(IS_IOS)
92 ;
93 bool FlushOutgoingMessagesNoLock() EXCLUSIVE_LOCKS_REQUIRED(write_lock_);
Brian Geffone6bc5ff2021-01-05 20:07:4894
Peter Boströmd5c1e1442024-01-31 21:38:5095 bool WriteOutgoingMessagesWithWritev() EXCLUSIVE_LOCKS_REQUIRED(write_lock_);
Brian Geffone6bc5ff2021-01-05 20:07:4896
97 // FlushOutgoingMessagesWritevNoLock is equivalent to
98 // FlushOutgoingMessagesNoLock except it looks for opportunities to make
99 // only a single write syscall by using writev(2) instead of write(2). In
100 // most situations this is very straight forward; however, when a handle
101 // needs to be transferred we cannot use writev(2) and instead will fall
102 // back to the standard write.
Peter Boströmd5c1e1442024-01-31 21:38:50103 bool FlushOutgoingMessagesWritevNoLock()
104 EXCLUSIVE_LOCKS_REQUIRED(write_lock_);
Brian Geffone6bc5ff2021-01-05 20:07:48105
Xiaohan Wangaa41c682022-01-14 18:50:49106#if BUILDFLAG(IS_IOS)
Peter Boströmd5c1e1442024-01-31 21:38:50107 bool CloseHandles(const int* fds, size_t num_fds)
108 LOCKS_EXCLUDED(fds_to_close_lock_);
Xiaohan Wangaa41c682022-01-14 18:50:49109#endif // BUILDFLAG(IS_IOS)
Brian Geffone6bc5ff2021-01-05 20:07:48110
Ken Rockotef8611632023-04-04 02:57:50111 // The socket over which to communicate.
Brian Geffone6bc5ff2021-01-05 20:07:48112 base::ScopedFD socket_;
113
Peter Boström75187962024-01-31 23:26:24114 // These watchers must only be accessed on the IO thread. These are locked for
115 // allowing concurrent nullptr checking the unique_ptr but not dereferencing
116 // outside of the `io_task_runner_`.
Ken Rockot49a5e7a22024-11-28 00:43:21117 std::unique_ptr<base::IOWatcher::FdWatch> read_watcher_
Peter Boström75187962024-01-31 23:26:24118 GUARDED_BY(write_lock_);
Ken Rockot49a5e7a22024-11-28 00:43:21119 std::unique_ptr<base::IOWatcher::FdWatch> write_watcher_
Peter Boström75187962024-01-31 23:26:24120 GUARDED_BY(write_lock_);
Brian Geffone6bc5ff2021-01-05 20:07:48121
122 base::circular_deque<base::ScopedFD> incoming_fds_;
123
Brian Geffone6bc5ff2021-01-05 20:07:48124 base::Lock write_lock_;
Peter Boströmd5c1e1442024-01-31 21:38:50125 bool pending_write_ GUARDED_BY(write_lock_) = false;
126 bool reject_writes_ GUARDED_BY(write_lock_) = false;
127 base::circular_deque<MessageView> outgoing_messages_ GUARDED_BY(write_lock_);
Brian Geffone6bc5ff2021-01-05 20:07:48128
129 bool leak_handle_ = false;
130
Xiaohan Wangaa41c682022-01-14 18:50:49131#if BUILDFLAG(IS_IOS)
Brian Geffone6bc5ff2021-01-05 20:07:48132 base::Lock fds_to_close_lock_;
Peter Boströmd5c1e1442024-01-31 21:38:50133 std::vector<base::ScopedFD> fds_to_close_ GUARDED_BY(fds_to_close_lock_);
Xiaohan Wangaa41c682022-01-14 18:50:49134#endif // BUILDFLAG(IS_IOS)
Brian Geffone6bc5ff2021-01-05 20:07:48135};
136
137} // namespace core
138} // namespace mojo
139
Lei Zhang4d3c5812021-04-21 20:31:05140#endif // MOJO_CORE_CHANNEL_POSIX_H_