• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // 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"
9 #include "base/memory/ref_counted.h"
10 
11 namespace base {
12 class TaskRunner;
13 }
14 
15 namespace mojo {
16 namespace 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.
COMPONENT_EXPORT(MOJO_CORE_EMBEDDER)21 class 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   //
26   // What follows is a quick overview of why shutdown behavior is interesting
27   // and how you might decide which behavior is right for your use case.
28   //
29   // BACKGROUND
30   // ==========
31   //
32   // In order to facilitate efficient and reliable transfer of Mojo message pipe
33   // endpoints across process boundaries, the underlying model for a message
34   // pipe is actually a self-collapsing cycle of "ports." See
35   // //mojo/core/ports for gritty implementation details.
36   //
37   // Ports are essentially globally unique identifiers used for system-wide
38   // message routing. Every message pipe consists of at least two such ports:
39   // the pipe's two concrete endpoints.
40   //
41   // When a message pipe endpoint is transferred over another message pipe, that
42   // endpoint's port (which subsequently exists only internally with no
43   // publicly-reachable handle) enters a transient proxying state for the
44   // remainder of its lifetime. Once sufficient information has been
45   // proagated throughout the system and this proxying port can be safely
46   // bypassed, it is garbage-collected.
47   //
48   // If a process is terminated while hosting any active proxy ports, this
49   // will necessarily break the message pipe(s) to which those ports belong.
50   //
51   // WHEN TO USE CLEAN SHUTDOWN
52   // ==========================
53   //
54   // Consider three processes, A, B, and C. Suppose A creates a message pipe,
55   // sending one end to B and the other to C. For some brief period of time,
56   // messages sent by B or C over this pipe may be proxied through A.
57   //
58   // If A is suddenly terminated, there may be no way for B's messages to reach
59   // C (and vice versa), since the message pipe state may not have been fully
60   // propagated to all concerned processes in the system. As such, both B and C
61   // may have no choice but to signal peer closure on their respective ends of
62   // the pipe, and thus the pipe may be broken despite a lack of intent by
63   // either B or C.
64   //
65   // This can also happen if A creates a pipe and passes one end to B, who then
66   // passes it along to C. B may temporarily proxy messages for this pipe
67   // between A and C, and B's sudden demise will in turn beget the pipe's
68   // own sudden demise.
69   //
70   // In situations where these sort of arrangements may occur, potentially
71   // proxying processes must ensure they are shut down cleanly in order to avoid
72   // flaky system behavior.
73   //
74   // WHEN TO USE FAST SHUTDOWN
75   // =========================
76   //
77   // As a general rule of thumb, if your process never creates a message pipe
78   // where both ends are passed to other processes, or never forwards a pipe
79   // endpoint from one process to another, fast shutdown is safe. Satisfaction
80   // of these constraints can be difficult to prove though, so clean shutdown is
81   // a safe default choice.
82   //
83   // Content renderer processes are a good example of a case where fast shutdown
84   // is safe, because as a matter of security and stability, a renderer cannot
85   // be trusted to do any proxying on behalf of two other processes anyway.
86   //
87   // There are other practical scenarios where fast shutdown is safe even if
88   // the process may have live proxies. For example, content's browser process
89   // is treated as a sort of master process in the system, in the sense that if
90   // the browser is terminated, no other part of the system is expected to
91   // continue normal operation anyway. In this case the side-effects of fast
92   // shutdown are irrelevant, so fast shutdown is preferred.
93   enum class ShutdownPolicy {
94     // Clean shutdown. This causes the ScopedIPCSupport destructor to *block*
95     // the calling thread until clean shutdown is complete. See explanation
96     // above for details.
97     CLEAN,
98 
99     // Fast shutdown. In this case a cheap best-effort attempt is made to
100     // shut down the IPC system, but no effort is made to wait for its
101     // completion. See explanation above for details.
102     FAST,
103   };
104 
105   ScopedIPCSupport(scoped_refptr<base::TaskRunner> io_thread_task_runner,
106                    ShutdownPolicy shutdown_policy);
107   ~ScopedIPCSupport();
108 
109  private:
110   const ShutdownPolicy shutdown_policy_;
111 
112   DISALLOW_COPY_AND_ASSIGN(ScopedIPCSupport);
113 };
114 
115 }  // namespace core
116 }  // namespace mojo
117 
118 #endif  // MOJO_CORE_EMBEDDER_SCOPED_IPC_SUPPORT_H_
119