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
Close()13 MojoResult 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
WriteMessage(const void * bytes,uint32_t num_bytes,const std::vector<Dispatcher * > * dispatchers,MojoWriteMessageFlags flags)23 MojoResult 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
ReadMessage(void * bytes,uint32_t * num_bytes,std::vector<scoped_refptr<Dispatcher>> * dispatchers,uint32_t * num_dispatchers,MojoReadMessageFlags flags)37 MojoResult 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
WriteData(const void * elements,uint32_t * num_elements,MojoWriteDataFlags flags)54 MojoResult 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
BeginWriteData(void ** buffer,uint32_t * buffer_num_elements,MojoWriteDataFlags flags)64 MojoResult 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
EndWriteData(uint32_t num_elements_written)74 MojoResult 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
ReadData(void * elements,uint32_t * num_elements,MojoReadDataFlags flags)82 MojoResult 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
BeginReadData(const void ** buffer,uint32_t * buffer_num_elements,MojoReadDataFlags flags)92 MojoResult 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
EndReadData(uint32_t num_elements_read)102 MojoResult 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
AddWaiter(Waiter * waiter,MojoWaitFlags flags,MojoResult wake_result)110 MojoResult 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
RemoveWaiter(Waiter * waiter)122 void Dispatcher::RemoveWaiter(Waiter* waiter) {
123 base::AutoLock locker(lock_);
124 if (is_closed_)
125 return;
126 RemoveWaiterImplNoLock(waiter);
127 }
128
129 scoped_refptr<Dispatcher>
CreateEquivalentDispatcherAndCloseNoLock()130 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() {
131 lock_.AssertAcquired();
132 DCHECK(!is_closed_);
133
134 is_closed_ = true;
135 CancelAllWaitersNoLock();
136 return CreateEquivalentDispatcherAndCloseImplNoLock();
137 }
138
Dispatcher()139 Dispatcher::Dispatcher()
140 : is_closed_(false) {
141 }
142
~Dispatcher()143 Dispatcher::~Dispatcher() {
144 // Make sure that |Close()| was called.
145 DCHECK(is_closed_);
146 }
147
CancelAllWaitersNoLock()148 void 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
CloseImplNoLock()155 MojoResult 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
WriteMessageImplNoLock(const void * bytes,uint32_t num_bytes,const std::vector<Dispatcher * > * dispatchers,MojoWriteMessageFlags flags)163 MojoResult 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
ReadMessageImplNoLock(void *,uint32_t *,std::vector<scoped_refptr<Dispatcher>> *,uint32_t *,MojoReadMessageFlags)174 MojoResult 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
WriteDataImplNoLock(const void *,uint32_t *,MojoWriteDataFlags)186 MojoResult 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
BeginWriteDataImplNoLock(void **,uint32_t *,MojoWriteDataFlags)195 MojoResult 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
EndWriteDataImplNoLock(uint32_t)205 MojoResult 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
ReadDataImplNoLock(void *,uint32_t *,MojoReadDataFlags)213 MojoResult 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
BeginReadDataImplNoLock(const void **,uint32_t *,MojoReadDataFlags)222 MojoResult 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
EndReadDataImplNoLock(uint32_t)232 MojoResult 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
AddWaiterImplNoLock(Waiter *,MojoWaitFlags,MojoResult)239 MojoResult 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
RemoveWaiterImplNoLock(Waiter *)249 void 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