Chromium Code Reviews| 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 |