blob: b43be7b77882d46c28e53fb314187e1603818fa4 [file] [log] [blame]
Avi Drissmand387f0922022-09-14 20:51:311// Copyright 2015 The Chromium Authors
Ken Rockotdba46db2018-07-04 18:41:042// 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_EMBEDDER_SCOPED_IPC_SUPPORT_H_
6#define MOJO_CORE_EMBEDDER_SCOPED_IPC_SUPPORT_H_
7
8#include "base/component_export.h"
Lei Zhangb8567682023-01-06 17:54:049#include "base/memory/scoped_refptr.h"
Ken Rockotdba46db2018-07-04 18:41:0410
11namespace base {
Gabriel Charettee926fc12019-12-16 19:00:0212class SingleThreadTaskRunner;
Ken Rockotdba46db2018-07-04 18:41:0413}
14
15namespace mojo {
16namespace core {
17
18// A simple class that initialized Mojo IPC support on construction and shuts
19// down IPC support on destruction, optionally blocking the destructor on clean
20// IPC shutdown completion.
21class COMPONENT_EXPORT(MOJO_CORE_EMBEDDER) ScopedIPCSupport {
22 public:
23 // ShutdownPolicy is a type for specifying the desired Mojo IPC support
24 // shutdown behavior used during ScopedIPCSupport destruction.
25 //
Nico Weber709b8d12024-12-09 23:37:5626 // It only has an effect if BUILDFLAG(MOJO_SUPPORT_LEGACY_CORE),
27 // which currently is on ChromeOS and in fuzzer builds.
28 //
Ken Rockotdba46db2018-07-04 18:41:0429 // What follows is a quick overview of why shutdown behavior is interesting
30 // and how you might decide which behavior is right for your use case.
31 //
32 // BACKGROUND
33 // ==========
34 //
35 // In order to facilitate efficient and reliable transfer of Mojo message pipe
36 // endpoints across process boundaries, the underlying model for a message
37 // pipe is actually a self-collapsing cycle of "ports." See
38 // //mojo/core/ports for gritty implementation details.
39 //
40 // Ports are essentially globally unique identifiers used for system-wide
41 // message routing. Every message pipe consists of at least two such ports:
42 // the pipe's two concrete endpoints.
43 //
44 // When a message pipe endpoint is transferred over another message pipe, that
45 // endpoint's port (which subsequently exists only internally with no
46 // publicly-reachable handle) enters a transient proxying state for the
47 // remainder of its lifetime. Once sufficient information has been
48 // proagated throughout the system and this proxying port can be safely
49 // bypassed, it is garbage-collected.
50 //
51 // If a process is terminated while hosting any active proxy ports, this
52 // will necessarily break the message pipe(s) to which those ports belong.
53 //
54 // WHEN TO USE CLEAN SHUTDOWN
55 // ==========================
56 //
57 // Consider three processes, A, B, and C. Suppose A creates a message pipe,
58 // sending one end to B and the other to C. For some brief period of time,
59 // messages sent by B or C over this pipe may be proxied through A.
60 //
61 // If A is suddenly terminated, there may be no way for B's messages to reach
62 // C (and vice versa), since the message pipe state may not have been fully
63 // propagated to all concerned processes in the system. As such, both B and C
64 // may have no choice but to signal peer closure on their respective ends of
65 // the pipe, and thus the pipe may be broken despite a lack of intent by
66 // either B or C.
67 //
68 // This can also happen if A creates a pipe and passes one end to B, who then
69 // passes it along to C. B may temporarily proxy messages for this pipe
70 // between A and C, and B's sudden demise will in turn beget the pipe's
71 // own sudden demise.
72 //
73 // In situations where these sort of arrangements may occur, potentially
74 // proxying processes must ensure they are shut down cleanly in order to avoid
75 // flaky system behavior.
76 //
77 // WHEN TO USE FAST SHUTDOWN
78 // =========================
79 //
80 // As a general rule of thumb, if your process never creates a message pipe
81 // where both ends are passed to other processes, or never forwards a pipe
82 // endpoint from one process to another, fast shutdown is safe. Satisfaction
83 // of these constraints can be difficult to prove though, so clean shutdown is
84 // a safe default choice.
85 //
86 // Content renderer processes are a good example of a case where fast shutdown
87 // is safe, because as a matter of security and stability, a renderer cannot
88 // be trusted to do any proxying on behalf of two other processes anyway.
89 //
90 // There are other practical scenarios where fast shutdown is safe even if
91 // the process may have live proxies. For example, content's browser process
Ken Rockotcd23f752020-06-20 01:22:3192 // is treated as a sort of root process in the system, in the sense that if
Ken Rockotdba46db2018-07-04 18:41:0493 // the browser is terminated, no other part of the system is expected to
94 // continue normal operation anyway. In this case the side-effects of fast
95 // shutdown are irrelevant, so fast shutdown is preferred.
96 enum class ShutdownPolicy {
97 // Clean shutdown. This causes the ScopedIPCSupport destructor to *block*
98 // the calling thread until clean shutdown is complete. See explanation
99 // above for details.
100 CLEAN,
101
102 // Fast shutdown. In this case a cheap best-effort attempt is made to
103 // shut down the IPC system, but no effort is made to wait for its
104 // completion. See explanation above for details.
105 FAST,
106 };
107
Gabriel Charettee926fc12019-12-16 19:00:02108 ScopedIPCSupport(
109 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner,
110 ShutdownPolicy shutdown_policy);
Peter Boströma8176282021-09-23 22:33:56111
112 ScopedIPCSupport(const ScopedIPCSupport&) = delete;
113 ScopedIPCSupport& operator=(const ScopedIPCSupport&) = delete;
114
Ken Rockotdba46db2018-07-04 18:41:04115 ~ScopedIPCSupport();
116
117 private:
118 const ShutdownPolicy shutdown_policy_;
Ken Rockotdba46db2018-07-04 18:41:04119};
120
121} // namespace core
122} // namespace mojo
123
124#endif // MOJO_CORE_EMBEDDER_SCOPED_IPC_SUPPORT_H_