OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_SYSTEM_CORE_IMPL_H_ | 5 #ifndef MOJO_SYSTEM_CORE_IMPL_H_ |
6 #define MOJO_SYSTEM_CORE_IMPL_H_ | 6 #define MOJO_SYSTEM_CORE_IMPL_H_ |
7 | 7 |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 MojoWriteMessageFlags flags); | 52 MojoWriteMessageFlags flags); |
53 | 53 |
54 MojoResult ReadMessage(MojoHandle handle, | 54 MojoResult ReadMessage(MojoHandle handle, |
55 void* bytes, uint32_t* num_bytes, | 55 void* bytes, uint32_t* num_bytes, |
56 MojoHandle* handles, uint32_t* num_handles, | 56 MojoHandle* handles, uint32_t* num_handles, |
57 MojoReadMessageFlags flags); | 57 MojoReadMessageFlags flags); |
58 | 58 |
59 private: | 59 private: |
60 friend class test::CoreTestBase; | 60 friend class test::CoreTestBase; |
61 | 61 |
62 typedef base::hash_map<MojoHandle, scoped_refptr<Dispatcher> > | 62 // The |busy| member is used only to deal with functions (in particular |
63 HandleTableMap; | 63 // |WriteMessage()|) that want to hold on to a dispatcher and later remove it |
| 64 // from the handle table, without holding on to the handle table lock. |
| 65 // |
| 66 // For example, if |WriteMessage()| is called with a handle to be sent, (under |
| 67 // the handle table lock) it must first check that that handle is not busy (if |
| 68 // it is busy, then it fails with |MOJO_RESULT_BUSY|) and then marks it as |
| 69 // busy. To avoid deadlock, it should also try to acquire the locks for all |
| 70 // the dispatchers for the handles that it is sending (and fail with |
| 71 // |MOJO_RESULT_BUSY| if the attempt fails). At this point, it can release the |
| 72 // handle table lock. |
| 73 // |
| 74 // If |Close()| is simultaneously called on that handle, it too checks if the |
| 75 // handle is marked busy. If it is, it fails (with |MOJO_RESULT_BUSY|). This |
| 76 // prevents |WriteMessage()| from sending a handle that has been closed (or |
| 77 // learning about this too late). |
| 78 // |
| 79 // TODO(vtl): Move this implementation note. |
| 80 // To properly cancel waiters and avoid other races, |WriteMessage()| does not |
| 81 // transfer dispatchers from one handle to another, even when sending a |
| 82 // message in-process. Instead, it must transfer the "contents" of the |
| 83 // dispatcher to a new dispatcher, and then close the old dispatcher. If this |
| 84 // isn't done, in the in-process case, calls on the old handle may complete |
| 85 // after the the message has been received and a new handle created (and |
| 86 // possibly even after calls have been made on the new handle). |
| 87 struct HandleTableEntry { |
| 88 HandleTableEntry(); |
| 89 explicit HandleTableEntry(const scoped_refptr<Dispatcher>& dispatcher); |
| 90 ~HandleTableEntry(); |
| 91 |
| 92 scoped_refptr<Dispatcher> dispatcher; |
| 93 bool busy; |
| 94 }; |
| 95 typedef base::hash_map<MojoHandle, HandleTableEntry> HandleTableMap; |
64 | 96 |
65 CoreImpl(); | 97 CoreImpl(); |
66 ~CoreImpl(); | 98 ~CoreImpl(); |
67 | 99 |
68 // Looks up the dispatcher for the given handle. Returns null if the handle is | 100 // Looks up the dispatcher for the given handle. Returns null if the handle is |
69 // invalid. | 101 // invalid. |
70 scoped_refptr<Dispatcher> GetDispatcher(MojoHandle handle); | 102 scoped_refptr<Dispatcher> GetDispatcher(MojoHandle handle); |
71 | 103 |
72 // Assigns a new handle for the given dispatcher (which must be valid); | 104 // Assigns a new handle for the given dispatcher (which must be valid); |
73 // returns |MOJO_HANDLE_INVALID| on failure (due to hitting resource limits). | 105 // returns |MOJO_HANDLE_INVALID| on failure (due to hitting resource limits). |
74 // Must be called under |handle_table_lock_|. | 106 // Must be called under |handle_table_lock_|. |
75 MojoHandle AddDispatcherNoLock(scoped_refptr<Dispatcher> dispatcher); | 107 MojoHandle AddDispatcherNoLock(const scoped_refptr<Dispatcher>& dispatcher); |
76 | 108 |
77 // Internal implementation of |Wait()| and |WaitMany()|; doesn't do basic | 109 // Internal implementation of |Wait()| and |WaitMany()|; doesn't do basic |
78 // validation of arguments. | 110 // validation of arguments. |
79 MojoResult WaitManyInternal(const MojoHandle* handles, | 111 MojoResult WaitManyInternal(const MojoHandle* handles, |
80 const MojoWaitFlags* flags, | 112 const MojoWaitFlags* flags, |
81 uint32_t num_handles, | 113 uint32_t num_handles, |
82 MojoDeadline deadline); | 114 MojoDeadline deadline); |
83 | 115 |
84 // --------------------------------------------------------------------------- | 116 // --------------------------------------------------------------------------- |
85 | 117 |
86 static CoreImpl* singleton_; | 118 static CoreImpl* singleton_; |
87 | 119 |
88 // --------------------------------------------------------------------------- | 120 // --------------------------------------------------------------------------- |
89 | 121 |
90 // TODO(vtl): |handle_table_lock_| should be a reader-writer lock (if only we | 122 // TODO(vtl): |handle_table_lock_| should be a reader-writer lock (if only we |
91 // had them). | 123 // had them). |
92 base::Lock handle_table_lock_; // Protects the immediately-following members. | 124 base::Lock handle_table_lock_; // Protects the immediately-following members. |
93 HandleTableMap handle_table_; | 125 HandleTableMap handle_table_; |
94 MojoHandle next_handle_; // Invariant: never |MOJO_HANDLE_INVALID|. | 126 MojoHandle next_handle_; // Invariant: never |MOJO_HANDLE_INVALID|. |
95 | 127 |
96 // --------------------------------------------------------------------------- | 128 // --------------------------------------------------------------------------- |
97 | 129 |
98 DISALLOW_COPY_AND_ASSIGN(CoreImpl); | 130 DISALLOW_COPY_AND_ASSIGN(CoreImpl); |
99 }; | 131 }; |
100 | 132 |
101 } // namespace system | 133 } // namespace system |
102 } // namespace mojo | 134 } // namespace mojo |
103 | 135 |
104 #endif // MOJO_SYSTEM_CORE_IMPL_H_ | 136 #endif // MOJO_SYSTEM_CORE_IMPL_H_ |
OLD | NEW |