Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / mojo / system / dispatcher.cc
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
10 namespace mojo {
11 namespace system {
12
13 // Dispatcher ------------------------------------------------------------------
14
15 // static
16 DispatcherTransport Dispatcher::CoreImplAccess::TryStartTransport(
17     Dispatcher* dispatcher) {
18   DCHECK(dispatcher);
19
20   if (!dispatcher->lock_.Try())
21     return DispatcherTransport();
22
23   // We shouldn't race with things that close dispatchers, since closing can
24   // only take place either under |handle_table_lock_| or when the handle is
25   // marked as busy.
26   DCHECK(!dispatcher->is_closed_);
27
28   return DispatcherTransport(dispatcher);
29 }
30
31 MojoResult Dispatcher::Close() {
32   base::AutoLock locker(lock_);
33   if (is_closed_)
34     return MOJO_RESULT_INVALID_ARGUMENT;
35
36   CloseNoLock();
37   return MOJO_RESULT_OK;
38 }
39
40 MojoResult Dispatcher::WriteMessage(
41     const void* bytes,
42     uint32_t num_bytes,
43     std::vector<DispatcherTransport>* transports,
44     MojoWriteMessageFlags flags) {
45   DCHECK(!transports || (transports->size() > 0 &&
46                          transports->size() < kMaxMessageNumHandles));
47
48   base::AutoLock locker(lock_);
49   if (is_closed_)
50     return MOJO_RESULT_INVALID_ARGUMENT;
51
52   return WriteMessageImplNoLock(bytes, num_bytes, transports, flags);
53 }
54
55 MojoResult Dispatcher::ReadMessage(
56     void* bytes,
57     uint32_t* num_bytes,
58     std::vector<scoped_refptr<Dispatcher> >* dispatchers,
59     uint32_t* num_dispatchers,
60     MojoReadMessageFlags flags) {
61   DCHECK(!num_dispatchers || *num_dispatchers == 0 ||
62          (dispatchers && dispatchers->empty()));
63
64   base::AutoLock locker(lock_);
65   if (is_closed_)
66     return MOJO_RESULT_INVALID_ARGUMENT;
67
68   return ReadMessageImplNoLock(bytes, num_bytes, dispatchers, num_dispatchers,
69                                flags);
70 }
71
72 MojoResult Dispatcher::WriteData(const void* elements,
73                                  uint32_t* num_bytes,
74                                  MojoWriteDataFlags flags) {
75   base::AutoLock locker(lock_);
76   if (is_closed_)
77     return MOJO_RESULT_INVALID_ARGUMENT;
78
79   return WriteDataImplNoLock(elements, num_bytes, flags);
80 }
81
82 MojoResult Dispatcher::BeginWriteData(void** buffer,
83                                       uint32_t* buffer_num_bytes,
84                                       MojoWriteDataFlags flags) {
85   base::AutoLock locker(lock_);
86   if (is_closed_)
87     return MOJO_RESULT_INVALID_ARGUMENT;
88
89   return BeginWriteDataImplNoLock(buffer, buffer_num_bytes, flags);
90 }
91
92 MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) {
93   base::AutoLock locker(lock_);
94   if (is_closed_)
95     return MOJO_RESULT_INVALID_ARGUMENT;
96
97   return EndWriteDataImplNoLock(num_bytes_written);
98 }
99
100 MojoResult Dispatcher::ReadData(void* elements,
101                                 uint32_t* num_bytes,
102                                 MojoReadDataFlags flags) {
103   base::AutoLock locker(lock_);
104   if (is_closed_)
105     return MOJO_RESULT_INVALID_ARGUMENT;
106
107   return ReadDataImplNoLock(elements, num_bytes, flags);
108 }
109
110 MojoResult Dispatcher::BeginReadData(const void** buffer,
111                                      uint32_t* buffer_num_bytes,
112                                      MojoReadDataFlags flags) {
113   base::AutoLock locker(lock_);
114   if (is_closed_)
115     return MOJO_RESULT_INVALID_ARGUMENT;
116
117   return BeginReadDataImplNoLock(buffer, buffer_num_bytes, flags);
118 }
119
120 MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) {
121   base::AutoLock locker(lock_);
122   if (is_closed_)
123     return MOJO_RESULT_INVALID_ARGUMENT;
124
125   return EndReadDataImplNoLock(num_bytes_read);
126 }
127
128 MojoResult Dispatcher::AddWaiter(Waiter* waiter,
129                                  MojoWaitFlags flags,
130                                  MojoResult wake_result) {
131   DCHECK_GE(wake_result, 0);
132
133   base::AutoLock locker(lock_);
134   if (is_closed_)
135     return MOJO_RESULT_INVALID_ARGUMENT;
136
137   return AddWaiterImplNoLock(waiter, flags, wake_result);
138 }
139
140 void Dispatcher::RemoveWaiter(Waiter* waiter) {
141   base::AutoLock locker(lock_);
142   if (is_closed_)
143     return;
144   RemoveWaiterImplNoLock(waiter);
145 }
146
147 Dispatcher::Dispatcher()
148     : is_closed_(false) {
149 }
150
151 Dispatcher::~Dispatcher() {
152   // Make sure that |Close()| was called.
153   DCHECK(is_closed_);
154 }
155
156 void Dispatcher::CancelAllWaitersNoLock() {
157   lock_.AssertAcquired();
158   DCHECK(is_closed_);
159   // By default, waiting isn't supported. Only dispatchers that can be waited on
160   // will do something nontrivial.
161 }
162
163 void Dispatcher::CloseImplNoLock() {
164   lock_.AssertAcquired();
165   DCHECK(is_closed_);
166   // This may not need to do anything. Dispatchers should override this to do
167   // any actual close-time cleanup necessary.
168 }
169
170 MojoResult Dispatcher::WriteMessageImplNoLock(
171     const void* /*bytes*/,
172     uint32_t /*num_bytes*/,
173     std::vector<DispatcherTransport>* /*transports*/,
174     MojoWriteMessageFlags /*flags*/) {
175   lock_.AssertAcquired();
176   DCHECK(!is_closed_);
177   // By default, not supported. Only needed for message pipe dispatchers.
178   return MOJO_RESULT_INVALID_ARGUMENT;
179 }
180
181 MojoResult Dispatcher::ReadMessageImplNoLock(
182     void* /*bytes*/,
183     uint32_t* /*num_bytes*/,
184     std::vector<scoped_refptr<Dispatcher> >* /*dispatchers*/,
185     uint32_t* /*num_dispatchers*/,
186     MojoReadMessageFlags /*flags*/) {
187   lock_.AssertAcquired();
188   DCHECK(!is_closed_);
189   // By default, not supported. Only needed for message pipe dispatchers.
190   return MOJO_RESULT_INVALID_ARGUMENT;
191 }
192
193 MojoResult Dispatcher::WriteDataImplNoLock(const void* /*elements*/,
194                                            uint32_t* /*num_bytes*/,
195                                            MojoWriteDataFlags /*flags*/) {
196   lock_.AssertAcquired();
197   DCHECK(!is_closed_);
198   // By default, not supported. Only needed for data pipe dispatchers.
199   return MOJO_RESULT_INVALID_ARGUMENT;
200 }
201
202 MojoResult Dispatcher::BeginWriteDataImplNoLock(void** /*buffer*/,
203                                                 uint32_t* /*buffer_num_bytes*/,
204                                                 MojoWriteDataFlags /*flags*/) {
205   lock_.AssertAcquired();
206   DCHECK(!is_closed_);
207   // By default, not supported. Only needed for data pipe dispatchers.
208   return MOJO_RESULT_INVALID_ARGUMENT;
209 }
210
211 MojoResult Dispatcher::EndWriteDataImplNoLock(uint32_t /*num_bytes_written*/) {
212   lock_.AssertAcquired();
213   DCHECK(!is_closed_);
214   // By default, not supported. Only needed for data pipe dispatchers.
215   return MOJO_RESULT_INVALID_ARGUMENT;
216 }
217
218 MojoResult Dispatcher::ReadDataImplNoLock(void* /*elements*/,
219                                           uint32_t* /*num_bytes*/,
220                                           MojoReadDataFlags /*flags*/) {
221   lock_.AssertAcquired();
222   DCHECK(!is_closed_);
223   // By default, not supported. Only needed for data pipe dispatchers.
224   return MOJO_RESULT_INVALID_ARGUMENT;
225 }
226
227 MojoResult Dispatcher::BeginReadDataImplNoLock(const void** /*buffer*/,
228                                                uint32_t* /*buffer_num_bytes*/,
229                                                MojoReadDataFlags /*flags*/) {
230   lock_.AssertAcquired();
231   DCHECK(!is_closed_);
232   // By default, not supported. Only needed for data pipe dispatchers.
233   return MOJO_RESULT_INVALID_ARGUMENT;
234 }
235
236 MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) {
237   lock_.AssertAcquired();
238   DCHECK(!is_closed_);
239   // By default, not supported. Only needed for data pipe dispatchers.
240   return MOJO_RESULT_INVALID_ARGUMENT;
241 }
242
243 MojoResult Dispatcher::AddWaiterImplNoLock(Waiter* /*waiter*/,
244                                            MojoWaitFlags /*flags*/,
245                                            MojoResult /*wake_result*/) {
246   lock_.AssertAcquired();
247   DCHECK(!is_closed_);
248   // By default, waiting isn't supported. Only dispatchers that can be waited on
249   // will do something nontrivial.
250   return MOJO_RESULT_FAILED_PRECONDITION;
251 }
252
253 void Dispatcher::RemoveWaiterImplNoLock(Waiter* /*waiter*/) {
254   lock_.AssertAcquired();
255   DCHECK(!is_closed_);
256   // By default, waiting isn't supported. Only dispatchers that can be waited on
257   // will do something nontrivial.
258 }
259
260 bool Dispatcher::IsBusyNoLock() const {
261   lock_.AssertAcquired();
262   DCHECK(!is_closed_);
263   // Most dispatchers support only "atomic" operations, so they are never busy
264   // (in this sense).
265   return false;
266 }
267
268 void Dispatcher::CloseNoLock() {
269   lock_.AssertAcquired();
270   DCHECK(!is_closed_);
271
272   is_closed_ = true;
273   CancelAllWaitersNoLock();
274   CloseImplNoLock();
275 }
276
277 scoped_refptr<Dispatcher>
278 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() {
279   lock_.AssertAcquired();
280   DCHECK(!is_closed_);
281
282   is_closed_ = true;
283   CancelAllWaitersNoLock();
284   return CreateEquivalentDispatcherAndCloseImplNoLock();
285 }
286
287 // DispatcherTransport ---------------------------------------------------------
288
289 void DispatcherTransport::End() {
290   DCHECK(dispatcher_);
291   dispatcher_->lock_.Release();
292   dispatcher_ = NULL;
293 }
294
295 }  // namespace system
296 }  // namespace mojo