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 wants to hold onto a dispatcher and later remove it |
darin (slow to review)
2013/11/11 21:22:21
nit: wants -> want, onto -> on to
viettrungluu
2013/11/11 22:40:26
Done.
| |
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 create transfer the "contents" of the | |
darin (slow to review)
2013/11/11 21:22:21
nit: "create transfer"
viettrungluu
2013/11/11 22:40:26
Done.
| |
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; | |
96 | |
darin (slow to review)
2013/11/11 21:22:21
nit: extra new line
viettrungluu
2013/11/11 22:40:26
Done.
| |
64 | 97 |
65 CoreImpl(); | 98 CoreImpl(); |
66 ~CoreImpl(); | 99 ~CoreImpl(); |
67 | 100 |
68 // Looks up the dispatcher for the given handle. Returns null if the handle is | 101 // Looks up the dispatcher for the given handle. Returns null if the handle is |
69 // invalid. | 102 // invalid. |
70 scoped_refptr<Dispatcher> GetDispatcher(MojoHandle handle); | 103 scoped_refptr<Dispatcher> GetDispatcher(MojoHandle handle); |
71 | 104 |
72 // Assigns a new handle for the given dispatcher (which must be valid); | 105 // Assigns a new handle for the given dispatcher (which must be valid); |
73 // returns |MOJO_HANDLE_INVALID| on failure (due to hitting resource limits). | 106 // returns |MOJO_HANDLE_INVALID| on failure (due to hitting resource limits). |
74 // Must be called under |handle_table_lock_|. | 107 // Must be called under |handle_table_lock_|. |
75 MojoHandle AddDispatcherNoLock(scoped_refptr<Dispatcher> dispatcher); | 108 MojoHandle AddDispatcherNoLock(const scoped_refptr<Dispatcher>& dispatcher); |
76 | 109 |
77 // Internal implementation of |Wait()| and |WaitMany()|; doesn't do basic | 110 // Internal implementation of |Wait()| and |WaitMany()|; doesn't do basic |
78 // validation of arguments. | 111 // validation of arguments. |
79 MojoResult WaitManyInternal(const MojoHandle* handles, | 112 MojoResult WaitManyInternal(const MojoHandle* handles, |
80 const MojoWaitFlags* flags, | 113 const MojoWaitFlags* flags, |
81 uint32_t num_handles, | 114 uint32_t num_handles, |
82 MojoDeadline deadline); | 115 MojoDeadline deadline); |
83 | 116 |
84 // --------------------------------------------------------------------------- | 117 // --------------------------------------------------------------------------- |
85 | 118 |
86 static CoreImpl* singleton_; | 119 static CoreImpl* singleton_; |
87 | 120 |
88 // --------------------------------------------------------------------------- | 121 // --------------------------------------------------------------------------- |
89 | 122 |
90 // TODO(vtl): |handle_table_lock_| should be a reader-writer lock (if only we | 123 // TODO(vtl): |handle_table_lock_| should be a reader-writer lock (if only we |
91 // had them). | 124 // had them). |
92 base::Lock handle_table_lock_; // Protects the immediately-following members. | 125 base::Lock handle_table_lock_; // Protects the immediately-following members. |
93 HandleTableMap handle_table_; | 126 HandleTableMap handle_table_; |
94 MojoHandle next_handle_; // Invariant: never |MOJO_HANDLE_INVALID|. | 127 MojoHandle next_handle_; // Invariant: never |MOJO_HANDLE_INVALID|. |
95 | 128 |
96 // --------------------------------------------------------------------------- | 129 // --------------------------------------------------------------------------- |
97 | 130 |
98 DISALLOW_COPY_AND_ASSIGN(CoreImpl); | 131 DISALLOW_COPY_AND_ASSIGN(CoreImpl); |
99 }; | 132 }; |
100 | 133 |
101 } // namespace system | 134 } // namespace system |
102 } // namespace mojo | 135 } // namespace mojo |
103 | 136 |
104 #endif // MOJO_SYSTEM_CORE_IMPL_H_ | 137 #endif // MOJO_SYSTEM_CORE_IMPL_H_ |
OLD | NEW |