Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(678)

Side by Side Diff: ppapi/proxy/serialized_var.h

Issue 4096008: Var serialization-related proxy stuff. This allows vars to be sent over IPC... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/proxy/plugin_var_serialization_rules.cc ('k') | ppapi/proxy/serialized_var.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2010 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 PPAPI_PROXY_SERIALIZED_VAR_H_
6 #define PPAPI_PROXY_SERIALIZED_VAR_H_
7
8 #include <string>
9 #include <vector>
10
11 #include "base/basictypes.h"
12 #include "base/ref_counted.h"
13 #include "ppapi/c/pp_var.h"
14
15 namespace IPC {
16 class Message;
17 }
18
19 namespace pp {
20 namespace proxy {
21
22 class Dispatcher;
23 class VarSerializationRules;
24
25 // This class encapsulates a var so that we can serialize and deserialize it
26 // The problem is that for strings, serialization and deserialization requires
27 // knowledge from outside about how to get at or create a string. So this
28 // object groups the var with a dispatcher so that string values can be set or
29 // gotten.
30 //
31 // Declare IPC messages as using this type, but don't use it directly (it has
32 // no useful public methods). Instead, instantiate one of the helper classes
33 // below which are conveniently named for each use case to prevent screwups.
34 //
35 // Design background
36 // -----------------
37 // This is sadly super complicated. The IPC system needs a consistent type to
38 // use for sending and receiving vars (this is a SerializedVar). But there are
39 // different combinations of reference counting for sending and receiving
40 // objects and for dealing with strings
41 //
42 // This makes SerializedVar complicate and easy to mess up. To make it
43 // reasonable to use all functions are protected and there are a use-specific
44 // classes that encapsulate exactly one type of use in a way that typically
45 // won't compile if you do the wrong thing.
46 //
47 // The IPC system is designed to pass things around and will make copies in
48 // some cases, so our system must be designed so that this stuff will work.
49 // This is challenging when the SerializedVar must to some cleanup after the
50 // message is sent. To work around this, we create an inner class using a
51 // linked_ptr so all copies of a SerializedVar can share and we can guarantee
52 // that the actual data will get cleaned up on shutdown.
53 //
54 // Constness
55 // ---------
56 // SerializedVar basically doesn't support const. Everything is mutable and
57 // most functions are declared const. This unfortunateness is because of the
58 // way the IPC system works. When deserializing, it will have a const
59 // SerializedVar in a Tuple and this will be given to the function. We kind of
60 // want to modify that to convert strings and do refcounting.
61 //
62 // The helper classes used for accessing the SerializedVar have more reasonable
63 // behavior and will enforce that you don't do stupid things.
64 class SerializedVar {
65 public:
66 enum CleanupMode {
67 // The serialized var won't do anything special in the destructor (default).
68 CLEANUP_NONE,
69
70 // The serialized var will call EndSendPassRef in the destructor.
71 END_SEND_PASS_REF,
72
73 // The serialized var will call EndReceiveCallerOwned in the destructor.
74 END_RECEIVE_CALLER_OWNED
75 };
76
77 SerializedVar();
78 ~SerializedVar();
79
80 // Backend implementation for IPC::ParamTraits<SerializedVar>.
81 void WriteToMessage(IPC::Message* m) const {
82 inner_->WriteToMessage(m);
83 }
84 bool ReadFromMessage(const IPC::Message* m, void** iter) {
85 return inner_->ReadFromMessage(m, iter);
86 }
87
88 protected:
89 friend class SerializedVarReceiveInput;
90 friend class SerializedVarReturnValue;
91 friend class SerializedVarOutParam;
92 friend class SerializedVarSendInput;
93 friend class SerializedVarVectorReceiveInput;
94
95 class Inner : public base::RefCounted<Inner> {
96 public:
97 Inner();
98 Inner(VarSerializationRules* serialization_rules);
99 Inner(VarSerializationRules* serialization_rules, const PP_Var& var);
100 ~Inner();
101
102 VarSerializationRules* serialization_rules() {
103 return serialization_rules_;
104 }
105 void set_serialization_rules(VarSerializationRules* serialization_rules) {
106 serialization_rules_ = serialization_rules;
107 }
108
109 void set_cleanup_mode(CleanupMode cm) { cleanup_mode_ = cm; }
110
111 // See outer class's declarations above.
112 PP_Var GetVar() const;
113 PP_Var GetIncompleteVar() const;
114 void SetVar(PP_Var var);
115 const std::string& GetString() const;
116 std::string* GetStringPtr();
117
118 void WriteToMessage(IPC::Message* m) const;
119 bool ReadFromMessage(const IPC::Message* m, void** iter);
120
121 private:
122 // Rules for serializing and deserializing vars for this process type.
123 // This may be NULL, but must be set before trying to serialize to IPC when
124 // sending, or before converting back to a PP_Var when receiving.
125 VarSerializationRules* serialization_rules_;
126
127 // If this is set to VARTYPE_STRING and the 'value.id' is 0, then the
128 // string_value_ contains the string. This means that the caller hasn't
129 // called Deserialize with a valid Dispatcher yet, which is how we can
130 // convert the serialized string value to a PP_Var string ID.
131 //
132 // This var may not be complete until the serialization rules are set when
133 // reading from IPC since we'll need that to convert the string_value to
134 // a string ID. Before this, the as_id will be 0 for VARTYPE_STRING.
135 PP_Var var_;
136
137 // Holds the literal string value to/from IPC. This will be valid of the
138 // var_ is VARTYPE_STRING.
139 std::string string_value_;
140
141 CleanupMode cleanup_mode_;
142
143 #ifndef NDEBUG
144 // When being sent or received over IPC, we should only be serialized or
145 // deserialized once. These flags help us assert this is true.
146 mutable bool has_been_serialized_;
147 mutable bool has_been_deserialized_;
148 #endif
149
150 DISALLOW_COPY_AND_ASSIGN(Inner);
151 };
152
153 SerializedVar(VarSerializationRules* serialization_rules);
154 SerializedVar(VarSerializationRules* serialization, const PP_Var& var);
155
156 mutable scoped_refptr<Inner> inner_;
157 };
158
159 // Helpers for message sending side --------------------------------------------
160
161 // For sending a value to the remote side.
162 //
163 // Example for API:
164 // void MyFunction(PP_Var)
165 // IPC message:
166 // IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
167 // Sender would be:
168 // void MyFunctionProxy(PP_Var param) {
169 // Send(new MyFunctionMsg(SerializedVarSendInput(param));
170 // }
171 class SerializedVarSendInput : public SerializedVar {
172 public:
173 SerializedVarSendInput(Dispatcher* dispatcher, const PP_Var& var);
174
175 // Helper function for serializing a vector of input vars for serialization.
176 static void ConvertVector(Dispatcher* dispatcher,
177 const PP_Var* input,
178 size_t input_count,
179 std::vector<SerializedVar>* output);
180
181 private:
182 // Disallow the empty constructor, but keep the default copy constructor
183 // which is required to send the object to the IPC system.
184 SerializedVarSendInput();
185 };
186
187 // For the calling side of a function returning a var. The sending side uses
188 // SerializedVarReturnValue.
189 //
190 // Example for API:
191 // PP_Var MyFunction()
192 // IPC message:
193 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
194 // Message handler would be:
195 // PP_Var MyFunctionProxy() {
196 // ReceiveSerializedVarReturnValue result;
197 // Send(new MyFunctionMsg(&result));
198 // return result.Return(dispatcher());
199 // }
200 class ReceiveSerializedVarReturnValue : public SerializedVar {
201 public:
202 // Note that we can't set the dispatcher in the constructor because the
203 // data will be overridden when the return value is set.
204 ReceiveSerializedVarReturnValue();
205
206 PP_Var Return(Dispatcher* dispatcher);
207
208 private:
209 DISALLOW_COPY_AND_ASSIGN(ReceiveSerializedVarReturnValue);
210 };
211
212 // Example for API:
213 // "void MyFunction(PP_Var* exception);"
214 // IPC message:
215 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
216 // Message handler would be:
217 // void OnMsgMyFunction(PP_Var* exception) {
218 // ReceiveSerializedException se(dispatcher(), exception)
219 // Send(new PpapiHostMsg_Foo(&se));
220 // }
221 class ReceiveSerializedException : public SerializedVar {
222 public:
223 ReceiveSerializedException(Dispatcher* dispatcher, PP_Var* exception);
224 ~ReceiveSerializedException();
225
226 // Returns true if the exception passed in the constructor is set. Check
227 // this before actually issuing the IPC.
228 bool IsThrown() const;
229
230 private:
231 // The input/output exception we're wrapping. May be NULL.
232 PP_Var* exception_;
233
234 DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedException);
235 };
236
237 // Helper class for when we're returning a vector of Vars. When it goes out
238 // of scope it will automatically convert the vector filled by the IPC layer
239 // into the array specified by the constructor params.
240 //
241 // Example for API:
242 // "void MyFunction(uint32_t* count, PP_Var** vars);"
243 // IPC message:
244 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, std::vector<SerializedVar>);
245 // Proxy function:
246 // void MyFunction(uint32_t* count, PP_Var** vars) {
247 // ReceiveSerializedVarVectorOutParam vect(dispatcher, count, vars);
248 // Send(new MyMsg(vect.OutParam()));
249 // }
250 class ReceiveSerializedVarVectorOutParam {
251 public:
252 ReceiveSerializedVarVectorOutParam(Dispatcher* dispatcher,
253 uint32_t* output_count,
254 PP_Var** output);
255 ~ReceiveSerializedVarVectorOutParam();
256
257 std::vector<SerializedVar>* OutParam();
258
259 private:
260 Dispatcher* dispatcher_;
261 uint32_t* output_count_;
262 PP_Var** output_;
263
264 std::vector<SerializedVar> vector_;
265
266 DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedVarVectorOutParam);
267 };
268
269 // Helpers for message receiving side ------------------------------------------
270
271 // For receiving a value from the remote side.
272 //
273 // Example for API:
274 // void MyFunction(PP_Var)
275 // IPC message:
276 // IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
277 // Message handler would be:
278 // void OnMsgMyFunction(SerializedVarReceiveInput param) {
279 // MyFunction(param.Get());
280 // }
281 class SerializedVarReceiveInput {
282 public:
283 // We rely on the implicit constructor here since the IPC layer will call
284 // us with a SerializedVar. Pass this object by value, the copy constructor
285 // will pass along the pointer (as cheap as passing a pointer arg).
286 SerializedVarReceiveInput(const SerializedVar& serialized);
287 ~SerializedVarReceiveInput();
288
289 PP_Var Get(Dispatcher* dispatcher);
290
291 private:
292 const SerializedVar& serialized_;
293
294 // Since the SerializedVar is const, we can't set its dispatcher (which is
295 // OK since we don't need to). But since we need it for our own uses, we
296 // track it here. Will be NULL before Get() is called.
297 Dispatcher* dispatcher_;
298 PP_Var var_;
299 };
300
301 // For receiving an input vector of vars from the remote side.
302 //
303 // Example:
304 // OnMsgMyFunction(SerializedVarVectorReceiveInput vector) {
305 // uint32_t size;
306 // PP_Var* array = vector.Get(dispatcher, &size);
307 // MyFunction(size, array);
308 // }
309 class SerializedVarVectorReceiveInput {
310 public:
311 SerializedVarVectorReceiveInput(const std::vector<SerializedVar>& serialized);
312 ~SerializedVarVectorReceiveInput();
313
314 // Only call Get() once. It will return a pointer to the converted array and
315 // place the array size in the out param. Will return NULL when the array is
316 // empty.
317 PP_Var* Get(Dispatcher* dispatcher, uint32_t* array_size);
318
319 private:
320 const std::vector<SerializedVar>& serialized_;
321
322 // Filled by Get().
323 std::vector<PP_Var> deserialized_;
324 };
325
326 // For the receiving side of a function returning a var. The calling side uses
327 // ReceiveSerializedVarReturnValue.
328 //
329 // Example for API:
330 // PP_Var MyFunction()
331 // IPC message:
332 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
333 // Message handler would be:
334 // void OnMsgMyFunction(SerializedVarReturnValue result) {
335 // result.Return(dispatcher(), MyFunction());
336 // }
337 class SerializedVarReturnValue {
338 public:
339 // We rely on the implicit constructor here since the IPC layer will call
340 // us with a SerializedVar*. Pass this object by value, the copy constructor
341 // will pass along the pointer (as cheap as passing a pointer arg).
342 SerializedVarReturnValue(SerializedVar* serialized);
343
344 void Return(Dispatcher* dispatcher, const PP_Var& var);
345
346 private:
347 SerializedVar* serialized_;
348 };
349
350 // For writing an out param to the remote side.
351 //
352 // Example for API:
353 // "void MyFunction(PP_Var* out);"
354 // IPC message:
355 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
356 // Message handler would be:
357 // void OnMsgMyFunction(SerializedVarOutParam out_param) {
358 // MyFunction(out_param.OutParam(dispatcher()));
359 // }
360 class SerializedVarOutParam {
361 public:
362 // We rely on the implicit constructor here since the IPC layer will call
363 // us with a SerializedVar*. Pass this object by value, the copy constructor
364 // will pass along the pointer (as cheap as passing a pointer arg).
365 SerializedVarOutParam(SerializedVar* serialized);
366 ~SerializedVarOutParam();
367
368 // Call this function only once. The caller should write its result to the
369 // returned var pointer before this class goes out of scope. The var's
370 // initial value will be VARTYPE_UNDEFINED.
371 PP_Var* OutParam(Dispatcher* dispatcher);
372
373 private:
374 SerializedVar* serialized_;
375
376 // This is the value actually written by the code and returned by OutParam.
377 // We'll write this into serialized_ in our destructor.
378 PP_Var writable_var_;
379 };
380
381 // For returning an array of PP_Vars to the other side and transferring
382 // ownership.
383 //
384 class SerializedVarVectorOutParam {
385 public:
386 SerializedVarVectorOutParam(std::vector<SerializedVar>* serialized);
387 ~SerializedVarVectorOutParam();
388
389 uint32_t* CountOutParam() { return &count_; }
390 PP_Var** ArrayOutParam(Dispatcher* dispatcher);
391
392 private:
393 Dispatcher* dispatcher_;
394 std::vector<SerializedVar>* serialized_;
395
396 uint32_t count_;
397 PP_Var* array_;
398 };
399
400 } // namespace proxy
401 } // namespace pp
402
403 #endif // PPAPI_PROXY_SERIALIZED_VAR_H_
404
OLDNEW
« no previous file with comments | « ppapi/proxy/plugin_var_serialization_rules.cc ('k') | ppapi/proxy/serialized_var.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698