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 3// found in the LICENSE file. 4 5#include "mojo/system/dispatcher.h" 6 7#include "base/logging.h" 8#include "mojo/system/constants.h" 9 10namespace mojo { 11namespace system { 12 13MojoResult Dispatcher::Close() { 14 base::AutoLock locker(lock_); 15 if (is_closed_) 16 return MOJO_RESULT_INVALID_ARGUMENT; 17 18 is_closed_ = true; 19 CancelAllWaitersNoLock(); 20 return CloseImplNoLock(); 21} 22 23MojoResult Dispatcher::WriteMessage(const void* bytes, 24 uint32_t num_bytes, 25 const std::vector<Dispatcher*>* dispatchers, 26 MojoWriteMessageFlags flags) { 27 DCHECK(!dispatchers || (dispatchers->size() > 0 && 28 dispatchers->size() < kMaxMessageNumHandles)); 29 30 base::AutoLock locker(lock_); 31 if (is_closed_) 32 return MOJO_RESULT_INVALID_ARGUMENT; 33 34 return WriteMessageImplNoLock(bytes, num_bytes, dispatchers, flags); 35} 36 37MojoResult Dispatcher::ReadMessage( 38 void* bytes, 39 uint32_t* num_bytes, 40 std::vector<scoped_refptr<Dispatcher> >* dispatchers, 41 uint32_t* num_dispatchers, 42 MojoReadMessageFlags flags) { 43 DCHECK(!num_dispatchers || *num_dispatchers == 0 || 44 (dispatchers && dispatchers->empty())); 45 46 base::AutoLock locker(lock_); 47 if (is_closed_) 48 return MOJO_RESULT_INVALID_ARGUMENT; 49 50 return ReadMessageImplNoLock(bytes, num_bytes, dispatchers, num_dispatchers, 51 flags); 52} 53 54MojoResult Dispatcher::WriteData(const void* elements, 55 uint32_t* num_elements, 56 MojoWriteDataFlags flags) { 57 base::AutoLock locker(lock_); 58 if (is_closed_) 59 return MOJO_RESULT_INVALID_ARGUMENT; 60 61 return WriteDataImplNoLock(elements, num_elements, flags); 62} 63 64MojoResult Dispatcher::BeginWriteData(void** buffer, 65 uint32_t* buffer_num_elements, 66 MojoWriteDataFlags flags) { 67 base::AutoLock locker(lock_); 68 if (is_closed_) 69 return MOJO_RESULT_INVALID_ARGUMENT; 70 71 return BeginWriteDataImplNoLock(buffer, buffer_num_elements, flags); 72} 73 74MojoResult Dispatcher::EndWriteData(uint32_t num_elements_written) { 75 base::AutoLock locker(lock_); 76 if (is_closed_) 77 return MOJO_RESULT_INVALID_ARGUMENT; 78 79 return EndWriteDataImplNoLock(num_elements_written); 80} 81 82MojoResult Dispatcher::ReadData(void* elements, 83 uint32_t* num_elements, 84 MojoReadDataFlags flags) { 85 base::AutoLock locker(lock_); 86 if (is_closed_) 87 return MOJO_RESULT_INVALID_ARGUMENT; 88 89 return ReadDataImplNoLock(elements, num_elements, flags); 90} 91 92MojoResult Dispatcher::BeginReadData(const void** buffer, 93 uint32_t* buffer_num_elements, 94 MojoReadDataFlags flags) { 95 base::AutoLock locker(lock_); 96 if (is_closed_) 97 return MOJO_RESULT_INVALID_ARGUMENT; 98 99 return BeginReadDataImplNoLock(buffer, buffer_num_elements, flags); 100} 101 102MojoResult Dispatcher::EndReadData(uint32_t num_elements_read) { 103 base::AutoLock locker(lock_); 104 if (is_closed_) 105 return MOJO_RESULT_INVALID_ARGUMENT; 106 107 return EndReadDataImplNoLock(num_elements_read); 108} 109 110MojoResult Dispatcher::AddWaiter(Waiter* waiter, 111 MojoWaitFlags flags, 112 MojoResult wake_result) { 113 DCHECK_GE(wake_result, 0); 114 115 base::AutoLock locker(lock_); 116 if (is_closed_) 117 return MOJO_RESULT_INVALID_ARGUMENT; 118 119 return AddWaiterImplNoLock(waiter, flags, wake_result); 120} 121 122void Dispatcher::RemoveWaiter(Waiter* waiter) { 123 base::AutoLock locker(lock_); 124 if (is_closed_) 125 return; 126 RemoveWaiterImplNoLock(waiter); 127} 128 129scoped_refptr<Dispatcher> 130Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() { 131 lock_.AssertAcquired(); 132 DCHECK(!is_closed_); 133 134 is_closed_ = true; 135 CancelAllWaitersNoLock(); 136 return CreateEquivalentDispatcherAndCloseImplNoLock(); 137} 138 139Dispatcher::Dispatcher() 140 : is_closed_(false) { 141} 142 143Dispatcher::~Dispatcher() { 144 // Make sure that |Close()| was called. 145 DCHECK(is_closed_); 146} 147 148void Dispatcher::CancelAllWaitersNoLock() { 149 lock_.AssertAcquired(); 150 DCHECK(is_closed_); 151 // By default, waiting isn't supported. Only dispatchers that can be waited on 152 // will do something nontrivial. 153} 154 155MojoResult Dispatcher::CloseImplNoLock() { 156 lock_.AssertAcquired(); 157 DCHECK(is_closed_); 158 // This may not need to do anything. Dispatchers should override this to do 159 // any actual close-time cleanup necessary. 160 return MOJO_RESULT_OK; 161} 162 163MojoResult Dispatcher::WriteMessageImplNoLock( 164 const void* bytes, 165 uint32_t num_bytes, 166 const std::vector<Dispatcher*>* dispatchers, 167 MojoWriteMessageFlags flags) { 168 lock_.AssertAcquired(); 169 DCHECK(!is_closed_); 170 // By default, not supported. Only needed for message pipe dispatchers. 171 return MOJO_RESULT_INVALID_ARGUMENT; 172} 173 174MojoResult Dispatcher::ReadMessageImplNoLock( 175 void* /*bytes*/, 176 uint32_t* /*num_bytes*/, 177 std::vector<scoped_refptr<Dispatcher> >* /*dispatchers*/, 178 uint32_t* /*num_dispatchers*/, 179 MojoReadMessageFlags /*flags*/) { 180 lock_.AssertAcquired(); 181 DCHECK(!is_closed_); 182 // By default, not supported. Only needed for message pipe dispatchers. 183 return MOJO_RESULT_INVALID_ARGUMENT; 184} 185 186MojoResult Dispatcher::WriteDataImplNoLock(const void* /*elements*/, 187 uint32_t* /*num_elements*/, 188 MojoWriteDataFlags /*flags*/) { 189 lock_.AssertAcquired(); 190 DCHECK(!is_closed_); 191 // By default, not supported. Only needed for data pipe dispatchers. 192 return MOJO_RESULT_INVALID_ARGUMENT; 193} 194 195MojoResult Dispatcher::BeginWriteDataImplNoLock( 196 void** /*buffer*/, 197 uint32_t* /*buffer_num_elements*/, 198 MojoWriteDataFlags /*flags*/) { 199 lock_.AssertAcquired(); 200 DCHECK(!is_closed_); 201 // By default, not supported. Only needed for data pipe dispatchers. 202 return MOJO_RESULT_INVALID_ARGUMENT; 203} 204 205MojoResult Dispatcher::EndWriteDataImplNoLock( 206 uint32_t /*num_elements_written*/) { 207 lock_.AssertAcquired(); 208 DCHECK(!is_closed_); 209 // By default, not supported. Only needed for data pipe dispatchers. 210 return MOJO_RESULT_INVALID_ARGUMENT; 211} 212 213MojoResult Dispatcher::ReadDataImplNoLock(void* /*elements*/, 214 uint32_t* /*num_elements*/, 215 MojoReadDataFlags /*flags*/) { 216 lock_.AssertAcquired(); 217 DCHECK(!is_closed_); 218 // By default, not supported. Only needed for data pipe dispatchers. 219 return MOJO_RESULT_INVALID_ARGUMENT; 220} 221 222MojoResult Dispatcher::BeginReadDataImplNoLock( 223 const void** /*buffer*/, 224 uint32_t* /*buffer_num_elements*/, 225 MojoReadDataFlags /*flags*/) { 226 lock_.AssertAcquired(); 227 DCHECK(!is_closed_); 228 // By default, not supported. Only needed for data pipe dispatchers. 229 return MOJO_RESULT_INVALID_ARGUMENT; 230} 231 232MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_elements_read*/) { 233 lock_.AssertAcquired(); 234 DCHECK(!is_closed_); 235 // By default, not supported. Only needed for data pipe dispatchers. 236 return MOJO_RESULT_INVALID_ARGUMENT; 237} 238 239MojoResult Dispatcher::AddWaiterImplNoLock(Waiter* /*waiter*/, 240 MojoWaitFlags /*flags*/, 241 MojoResult /*wake_result*/) { 242 lock_.AssertAcquired(); 243 DCHECK(!is_closed_); 244 // By default, waiting isn't supported. Only dispatchers that can be waited on 245 // will do something nontrivial. 246 return MOJO_RESULT_FAILED_PRECONDITION; 247} 248 249void Dispatcher::RemoveWaiterImplNoLock(Waiter* /*waiter*/) { 250 lock_.AssertAcquired(); 251 DCHECK(!is_closed_); 252 // By default, waiting isn't supported. Only dispatchers that can be waited on 253 // will do something nontrivial. 254} 255 256} // namespace system 257} // namespace mojo 258