Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / mojo / system / dispatcher.h
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 #ifndef MOJO_SYSTEM_DISPATCHER_H_
6 #define MOJO_SYSTEM_DISPATCHER_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <vector>
12
13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/synchronization/lock.h"
16 #include "mojo/public/system/core.h"
17 #include "mojo/system/system_impl_export.h"
18
19 namespace mojo {
20 namespace system {
21
22 class CoreImpl;
23 class Dispatcher;
24 class DispatcherTransport;
25 class LocalMessagePipeEndpoint;
26 class ProxyMessagePipeEndpoint;
27 class Waiter;
28
29 namespace test {
30
31 // Test helper.
32 // TODO(vtl): We need to declare it here so we can friend it. We define it
33 // inline below, but maybe it should be in a test-only file instead.
34 DispatcherTransport DispatcherTryStartTransport(Dispatcher* dispatcher);
35
36 }  // namespace test
37
38 // A |Dispatcher| implements Mojo primitives that are "attached" to a particular
39 // handle. This includes most (all?) primitives except for |MojoWait...()|. This
40 // object is thread-safe, with its state being protected by a single lock
41 // |lock_|, which is also made available to implementation subclasses (via the
42 // |lock()| method).
43 class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
44     public base::RefCountedThreadSafe<Dispatcher> {
45  public:
46   enum Type {
47     kTypeUnknown = 0,
48     kTypeMessagePipe,
49     kTypeDataPipeProducer,
50     kTypeDataPipeConsumer
51   };
52   virtual Type GetType() const = 0;
53
54   // These methods implement the various primitives named |Mojo...()|. These
55   // take |lock_| and handle races with |Close()|. Then they call out to
56   // subclasses' |...ImplNoLock()| methods (still under |lock_|), which actually
57   // implement the primitives.
58   // NOTE(vtl): This puts a big lock around each dispatcher (i.e., handle), and
59   // prevents the various |...ImplNoLock()|s from releasing the lock as soon as
60   // possible. If this becomes an issue, we can rethink this.
61   MojoResult Close();
62
63   // |transports| may be non-null if and only if there are handles to be
64   // written; not that |this| must not be in |transports|. On success, all the
65   // dispatchers in |transports| must have been moved to a closed state; on
66   // failure, they should remain in their original state.
67   MojoResult WriteMessage(const void* bytes,
68                           uint32_t num_bytes,
69                           std::vector<DispatcherTransport>* transports,
70                           MojoWriteMessageFlags flags);
71   // |dispatchers| must be non-null but empty, if |num_dispatchers| is non-null
72   // and nonzero. On success, it will be set to the dispatchers to be received
73   // (and assigned handles) as part of the message.
74   MojoResult ReadMessage(
75       void* bytes,
76       uint32_t* num_bytes,
77       std::vector<scoped_refptr<Dispatcher> >* dispatchers,
78       uint32_t* num_dispatchers,
79       MojoReadMessageFlags flags);
80   MojoResult WriteData(const void* elements,
81                        uint32_t* elements_num_bytes,
82                        MojoWriteDataFlags flags);
83   MojoResult BeginWriteData(void** buffer,
84                             uint32_t* buffer_num_bytes,
85                             MojoWriteDataFlags flags);
86   MojoResult EndWriteData(uint32_t num_bytes_written);
87   MojoResult ReadData(void* elements,
88                       uint32_t* num_bytes,
89                       MojoReadDataFlags flags);
90   MojoResult BeginReadData(const void** buffer,
91                            uint32_t* buffer_num_bytes,
92                            MojoReadDataFlags flags);
93   MojoResult EndReadData(uint32_t num_bytes_read);
94
95   // Adds a waiter to this dispatcher. The waiter will be woken up when this
96   // object changes state to satisfy |flags| with result |wake_result| (which
97   // must be >= 0, i.e., a success status). It will also be woken up when it
98   // becomes impossible for the object to ever satisfy |flags| with a suitable
99   // error status.
100   //
101   // Returns:
102   //  - |MOJO_RESULT_OK| if the waiter was added;
103   //  - |MOJO_RESULT_ALREADY_EXISTS| if |flags| is already satisfied;
104   //  - |MOJO_RESULT_INVALID_ARGUMENT| if the dispatcher has been closed; and
105   //  - |MOJO_RESULT_FAILED_PRECONDITION| if it is not (or no longer) possible
106   //    that |flags| will ever be satisfied.
107   MojoResult AddWaiter(Waiter* waiter,
108                        MojoWaitFlags flags,
109                        MojoResult wake_result);
110   void RemoveWaiter(Waiter* waiter);
111
112   // A dispatcher must be put into a special state in order to be sent across a
113   // message pipe. Outside of tests, only |CoreImplAccess| is allowed to do
114   // this, since there are requirements on the handle table (see below).
115   //
116   // In this special state, only a restricted set of operations is allowed.
117   // These are the ones available as |DispatcherTransport| methods. Other
118   // |Dispatcher| methods must not be called until |DispatcherTransport::End()|
119   // has been called.
120   class CoreImplAccess {
121    private:
122     friend class CoreImpl;
123     // Tests also need this, to avoid needing |CoreImpl|.
124     friend DispatcherTransport test::DispatcherTryStartTransport(Dispatcher*);
125
126     // This must be called under the handle table lock and only if the handle
127     // table entry is not marked busy. The caller must maintain a reference to
128     // |dispatcher| until |DispatcherTransport::End()| is called.
129     static DispatcherTransport TryStartTransport(Dispatcher* dispatcher);
130   };
131
132  protected:
133   Dispatcher();
134
135   friend class base::RefCountedThreadSafe<Dispatcher>;
136   virtual ~Dispatcher();
137
138   // These are to be overridden by subclasses (if necessary). They are called
139   // exactly once -- first |CancelAllWaitersNoLock()|, then |CloseImplNoLock()|,
140   // when the dispatcher is being closed. They are called under |lock_|.
141   virtual void CancelAllWaitersNoLock();
142   virtual void CloseImplNoLock();
143   virtual scoped_refptr<Dispatcher>
144       CreateEquivalentDispatcherAndCloseImplNoLock() = 0;
145
146   // These are to be overridden by subclasses (if necessary). They are never
147   // called after the dispatcher has been closed. They are called under |lock_|.
148   // See the descriptions of the methods without the "ImplNoLock" for more
149   // information.
150   virtual MojoResult WriteMessageImplNoLock(
151       const void* bytes,
152       uint32_t num_bytes,
153       std::vector<DispatcherTransport>* transports,
154       MojoWriteMessageFlags flags);
155   virtual MojoResult ReadMessageImplNoLock(
156       void* bytes,
157       uint32_t* num_bytes,
158       std::vector<scoped_refptr<Dispatcher> >* dispatchers,
159       uint32_t* num_dispatchers,
160       MojoReadMessageFlags flags);
161   virtual MojoResult WriteDataImplNoLock(const void* elements,
162                                          uint32_t* num_bytes,
163                                          MojoWriteDataFlags flags);
164   virtual MojoResult BeginWriteDataImplNoLock(void** buffer,
165                                               uint32_t* buffer_num_bytes,
166                                               MojoWriteDataFlags flags);
167   virtual MojoResult EndWriteDataImplNoLock(uint32_t num_bytes_written);
168   virtual MojoResult ReadDataImplNoLock(void* elements,
169                                         uint32_t* num_bytes,
170                                         MojoReadDataFlags flags);
171   virtual MojoResult BeginReadDataImplNoLock(const void** buffer,
172                                              uint32_t* buffer_num_bytes,
173                                              MojoReadDataFlags flags);
174   virtual MojoResult EndReadDataImplNoLock(uint32_t num_bytes_read);
175   virtual MojoResult AddWaiterImplNoLock(Waiter* waiter,
176                                          MojoWaitFlags flags,
177                                          MojoResult wake_result);
178   virtual void RemoveWaiterImplNoLock(Waiter* waiter);
179
180   // Available to subclasses. (Note: Returns a non-const reference, just like
181   // |base::AutoLock|'s constructor takes a non-const reference.)
182   base::Lock& lock() const { return lock_; }
183
184  private:
185   friend class DispatcherTransport;
186
187   // This should be overridden to return true if/when there's an ongoing
188   // operation (e.g., two-phase read/writes on data pipes) that should prevent a
189   // handle from being sent over a message pipe (with status "busy").
190   virtual bool IsBusyNoLock() const;
191
192   // Closes the dispatcher. This must be done under lock, and unlike |Close()|,
193   // the dispatcher must not be closed already. (This is the "equivalent" of
194   // |CreateEquivalentDispatcherAndCloseNoLock()|, for situations where the
195   // dispatcher must be disposed of instead of "transferred".)
196   void CloseNoLock();
197
198   // Creates an equivalent dispatcher -- representing the same resource as this
199   // dispatcher -- and close (i.e., disable) this dispatcher. I.e., this
200   // dispatcher will look as though it was closed, but the resource it
201   // represents will be assigned to the new dispatcher. This must be called
202   // under the dispatcher's lock.
203   scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseNoLock();
204
205   // This protects the following members as well as any state added by
206   // subclasses.
207   mutable base::Lock lock_;
208   bool is_closed_;
209
210   DISALLOW_COPY_AND_ASSIGN(Dispatcher);
211 };
212
213 // Wrapper around a |Dispatcher| pointer, while it's being processed to be
214 // passed in a message pipe. See the comment about |Dispatcher::CoreImplAccess|
215 // for more details.
216 //
217 // Note: This class is deliberately "thin" -- no more expensive than a
218 // |Dispatcher*|.
219 class MOJO_SYSTEM_IMPL_EXPORT DispatcherTransport {
220  public:
221   DispatcherTransport() : dispatcher_(NULL) {}
222
223   void End();
224
225   Dispatcher::Type GetType() const { return dispatcher_->GetType(); }
226   bool IsBusy() const { return dispatcher_->IsBusyNoLock(); }
227   void Close() { dispatcher_->CloseNoLock(); }
228   scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndClose() {
229     return dispatcher_->CreateEquivalentDispatcherAndCloseNoLock();
230   }
231
232   bool is_valid() const { return !!dispatcher_; }
233
234  protected:
235   Dispatcher* dispatcher() { return dispatcher_; }
236
237  private:
238   friend class Dispatcher::CoreImplAccess;
239
240   explicit DispatcherTransport(Dispatcher* dispatcher)
241       : dispatcher_(dispatcher) {}
242
243   Dispatcher* dispatcher_;
244
245   // Copy and assign allowed.
246 };
247
248 namespace test {
249
250 inline DispatcherTransport DispatcherTryStartTransport(Dispatcher* dispatcher) {
251   return Dispatcher::CoreImplAccess::TryStartTransport(dispatcher);
252 }
253
254 }  // namespace test
255
256 }  // namespace system
257 }  // namespace mojo
258
259 #endif  // MOJO_SYSTEM_DISPATCHER_H_