OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef MOJO_EDK_SYSTEM_HANDLE_TABLE_H_ | 5 #ifndef MOJO_EDK_SYSTEM_HANDLE_TABLE_H_ |
6 #define MOJO_EDK_SYSTEM_HANDLE_TABLE_H_ | 6 #define MOJO_EDK_SYSTEM_HANDLE_TABLE_H_ |
7 | 7 |
8 #include <unordered_map> | 8 #include <unordered_map> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/memory/ref_counted.h" | 12 #include "mojo/edk/system/ref_ptr.h" |
13 #include "mojo/public/c/system/types.h" | 13 #include "mojo/public/c/system/types.h" |
14 #include "mojo/public/cpp/system/macros.h" | 14 #include "mojo/public/cpp/system/macros.h" |
15 | 15 |
16 namespace mojo { | 16 namespace mojo { |
17 namespace system { | 17 namespace system { |
18 | 18 |
19 class Core; | 19 class Core; |
20 class Dispatcher; | 20 class Dispatcher; |
21 class DispatcherTransport; | 21 class DispatcherTransport; |
22 | 22 |
23 using DispatcherVector = std::vector<scoped_refptr<Dispatcher>>; | 23 using DispatcherVector = std::vector<RefPtr<Dispatcher>>; |
24 | 24 |
25 // Test-only function (defined/used in embedder/test_embedder.cc). Declared here | 25 // Test-only function (defined/used in embedder/test_embedder.cc). Declared here |
26 // so it can be friended. | 26 // so it can be friended. |
27 namespace internal { | 27 namespace internal { |
28 bool ShutdownCheckNoLeaks(Core*); | 28 bool ShutdownCheckNoLeaks(Core*); |
29 } | 29 } |
30 | 30 |
31 // This class provides the (global) handle table (owned by |Core|), which maps | 31 // This class provides the (global) handle table (owned by |Core|), which maps |
32 // (valid) |MojoHandle|s to |Dispatcher|s. This is abstracted so that, e.g., | 32 // (valid) |MojoHandle|s to |Dispatcher|s. This is abstracted so that, e.g., |
33 // caching may be added. | 33 // caching may be added. |
34 // | 34 // |
35 // This class is NOT thread-safe; locking is left to |Core| (since it may need | 35 // This class is NOT thread-safe; locking is left to |Core| (since it may need |
36 // to make several changes -- "atomically" or in rapid successsion, in which | 36 // to make several changes -- "atomically" or in rapid successsion, in which |
37 // case the extra locking/unlocking would be unnecessary overhead). | 37 // case the extra locking/unlocking would be unnecessary overhead). |
38 | 38 |
39 class HandleTable { | 39 class HandleTable { |
40 public: | 40 public: |
41 HandleTable(); | 41 HandleTable(); |
42 ~HandleTable(); | 42 ~HandleTable(); |
43 | 43 |
44 // Gets the dispatcher for a given handle (which should not be | 44 // Gets the dispatcher for a given handle (which should not be |
45 // |MOJO_HANDLE_INVALID|). Returns null if there's no dispatcher for the given | 45 // |MOJO_HANDLE_INVALID|). Returns null if there's no dispatcher for the given |
46 // handle. | 46 // handle. |
47 // WARNING: For efficiency, this returns a dumb pointer. If you're going to | 47 // WARNING: For efficiency, this returns a dumb pointer. If you're going to |
48 // use the result outside |Core|'s lock, you MUST take a reference (e.g., by | 48 // use the result outside |Core|'s lock, you MUST take a reference (e.g., by |
49 // storing the result inside a |scoped_refptr|). | 49 // storing the result inside a |RefPtr|). |
50 Dispatcher* GetDispatcher(MojoHandle handle); | 50 Dispatcher* GetDispatcher(MojoHandle handle); |
51 | 51 |
52 // On success, gets the dispatcher for a given handle (which should not be | 52 // On success, gets the dispatcher for a given handle (which should not be |
53 // |MOJO_HANDLE_INVALID|) and removes it. (On failure, returns an appropriate | 53 // |MOJO_HANDLE_INVALID|) and removes it. (On failure, returns an appropriate |
54 // result (and leaves |dispatcher| alone), namely | 54 // result (and leaves |dispatcher| alone), namely |
55 // |MOJO_RESULT_INVALID_ARGUMENT| if there's no dispatcher for the given | 55 // |MOJO_RESULT_INVALID_ARGUMENT| if there's no dispatcher for the given |
56 // handle or |MOJO_RESULT_BUSY| if the handle is marked as busy.) | 56 // handle or |MOJO_RESULT_BUSY| if the handle is marked as busy.) |
57 MojoResult GetAndRemoveDispatcher(MojoHandle handle, | 57 MojoResult GetAndRemoveDispatcher(MojoHandle handle, |
58 scoped_refptr<Dispatcher>* dispatcher); | 58 RefPtr<Dispatcher>* dispatcher); |
59 | 59 |
60 // Adds a dispatcher (which must be valid), returning the handle for it. | 60 // Adds a dispatcher (which must be valid), returning the handle for it. |
61 // Returns |MOJO_HANDLE_INVALID| on failure (if the handle table is full). | 61 // Returns |MOJO_HANDLE_INVALID| on failure (if the handle table is full). |
62 MojoHandle AddDispatcher(const scoped_refptr<Dispatcher>& dispatcher); | 62 MojoHandle AddDispatcher(Dispatcher* dispatcher); |
63 | 63 |
64 // Adds a pair of dispatchers (which must be valid), return a pair of handles | 64 // Adds a pair of dispatchers (which must be valid), return a pair of handles |
65 // for them. On failure (if the handle table is full), the first (and second) | 65 // for them. On failure (if the handle table is full), the first (and second) |
66 // handles will be |MOJO_HANDLE_INVALID|, and neither dispatcher will be | 66 // handles will be |MOJO_HANDLE_INVALID|, and neither dispatcher will be |
67 // added. | 67 // added. |
68 std::pair<MojoHandle, MojoHandle> AddDispatcherPair( | 68 std::pair<MojoHandle, MojoHandle> AddDispatcherPair(Dispatcher* dispatcher0, |
69 const scoped_refptr<Dispatcher>& dispatcher0, | 69 Dispatcher* dispatcher1); |
70 const scoped_refptr<Dispatcher>& dispatcher1); | |
71 | 70 |
72 // Adds the given vector of dispatchers (of size at most | 71 // Adds the given vector of dispatchers (of size at most |
73 // |kMaxMessageNumHandles|). |handles| must point to an array of size at least | 72 // |kMaxMessageNumHandles|). |handles| must point to an array of size at least |
74 // |dispatchers.size()|. Unlike the other |AddDispatcher...()| functions, some | 73 // |dispatchers.size()|. Unlike the other |AddDispatcher...()| functions, some |
75 // of the dispatchers may be invalid (null). Returns true on success and false | 74 // of the dispatchers may be invalid (null). Returns true on success and false |
76 // on failure (if the handle table is full), in which case it leaves | 75 // on failure (if the handle table is full), in which case it leaves |
77 // |handles[...]| untouched (and all dispatchers unadded). | 76 // |handles[...]| untouched (and all dispatchers unadded). |
78 bool AddDispatcherVector(const DispatcherVector& dispatchers, | 77 bool AddDispatcherVector(const DispatcherVector& dispatchers, |
79 MojoHandle* handles); | 78 MojoHandle* handles); |
80 | 79 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 // all the dispatchers for the handles that it is sending (and fail with | 111 // all the dispatchers for the handles that it is sending (and fail with |
113 // |MOJO_RESULT_BUSY| if the attempt fails). At this point, it can release the | 112 // |MOJO_RESULT_BUSY| if the attempt fails). At this point, it can release the |
114 // handle table lock. | 113 // handle table lock. |
115 // | 114 // |
116 // If |Core::Close()| is simultaneously called on that handle, it too checks | 115 // If |Core::Close()| is simultaneously called on that handle, it too checks |
117 // if the handle is marked busy. If it is, it fails (with |MOJO_RESULT_BUSY|). | 116 // if the handle is marked busy. If it is, it fails (with |MOJO_RESULT_BUSY|). |
118 // This prevents |Core::WriteMessage()| from sending a handle that has been | 117 // This prevents |Core::WriteMessage()| from sending a handle that has been |
119 // closed (or learning about this too late). | 118 // closed (or learning about this too late). |
120 struct Entry { | 119 struct Entry { |
121 Entry(); | 120 Entry(); |
122 explicit Entry(const scoped_refptr<Dispatcher>& dispatcher); | 121 explicit Entry(RefPtr<Dispatcher>&& dispatcher); |
123 ~Entry(); | 122 ~Entry(); |
124 | 123 |
125 scoped_refptr<Dispatcher> dispatcher; | 124 RefPtr<Dispatcher> dispatcher; |
126 bool busy; | 125 bool busy; |
127 }; | 126 }; |
128 using HandleToEntryMap = std::unordered_map<MojoHandle, Entry>; | 127 using HandleToEntryMap = std::unordered_map<MojoHandle, Entry>; |
129 | 128 |
130 // Adds the given dispatcher to the handle table, not doing any size checks. | 129 // Adds the given dispatcher to the handle table, not doing any size checks. |
131 MojoHandle AddDispatcherNoSizeCheck( | 130 MojoHandle AddDispatcherNoSizeCheck(RefPtr<Dispatcher>&& dispatcher); |
132 const scoped_refptr<Dispatcher>& dispatcher); | |
133 | 131 |
134 HandleToEntryMap handle_to_entry_map_; | 132 HandleToEntryMap handle_to_entry_map_; |
135 MojoHandle next_handle_; // Invariant: never |MOJO_HANDLE_INVALID|. | 133 MojoHandle next_handle_; // Invariant: never |MOJO_HANDLE_INVALID|. |
136 | 134 |
137 MOJO_DISALLOW_COPY_AND_ASSIGN(HandleTable); | 135 MOJO_DISALLOW_COPY_AND_ASSIGN(HandleTable); |
138 }; | 136 }; |
139 | 137 |
140 } // namespace system | 138 } // namespace system |
141 } // namespace mojo | 139 } // namespace mojo |
142 | 140 |
143 #endif // MOJO_EDK_SYSTEM_HANDLE_TABLE_H_ | 141 #endif // MOJO_EDK_SYSTEM_HANDLE_TABLE_H_ |
OLD | NEW |