OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef PPAPI_PROXY_SERIALIZED_VAR_H_ | 5 #ifndef PPAPI_PROXY_SERIALIZED_VAR_H_ |
6 #define PPAPI_PROXY_SERIALIZED_VAR_H_ | 6 #define PPAPI_PROXY_SERIALIZED_VAR_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 21 matching lines...) Expand all Loading... |
32 // no useful public methods). Instead, instantiate one of the helper classes | 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. | 33 // below which are conveniently named for each use case to prevent screwups. |
34 // | 34 // |
35 // Design background | 35 // Design background |
36 // ----------------- | 36 // ----------------- |
37 // This is sadly super complicated. The IPC system needs a consistent type to | 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 | 38 // use for sending and receiving vars (this is a SerializedVar). But there are |
39 // different combinations of reference counting for sending and receiving | 39 // different combinations of reference counting for sending and receiving |
40 // objects and for dealing with strings | 40 // objects and for dealing with strings |
41 // | 41 // |
42 // This makes SerializedVar complicate and easy to mess up. To make it | 42 // This makes SerializedVar complicated and easy to mess up. To make it |
43 // reasonable to use all functions are protected and there are a use-specific | 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 | 44 // classes that encapsulate exactly one type of use in a way that typically |
45 // won't compile if you do the wrong thing. | 45 // won't compile if you do the wrong thing. |
46 // | 46 // |
47 // The IPC system is designed to pass things around and will make copies in | 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. | 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 | 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 | 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 | 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. | 52 // that the actual data will get cleaned up on shutdown. |
53 // | 53 // |
54 // Constness | 54 // Constness |
55 // --------- | 55 // --------- |
56 // SerializedVar basically doesn't support const. Everything is mutable and | 56 // SerializedVar basically doesn't support const. Everything is mutable and |
57 // most functions are declared const. This unfortunateness is because of the | 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 | 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 | 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. | 60 // want to modify that to convert strings and do refcounting. |
61 // | 61 // |
62 // The helper classes used for accessing the SerializedVar have more reasonable | 62 // The helper classes used for accessing the SerializedVar have more reasonable |
63 // behavior and will enforce that you don't do stupid things. | 63 // behavior and will enforce that you don't do stupid things. |
64 class SerializedVar { | 64 class SerializedVar { |
65 public: | 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(); | 66 SerializedVar(); |
78 ~SerializedVar(); | 67 ~SerializedVar(); |
79 | 68 |
80 // Backend implementation for IPC::ParamTraits<SerializedVar>. | 69 // Backend implementation for IPC::ParamTraits<SerializedVar>. |
81 void WriteToMessage(IPC::Message* m) const { | 70 void WriteToMessage(IPC::Message* m) const { |
82 inner_->WriteToMessage(m); | 71 inner_->WriteToMessage(m); |
83 } | 72 } |
84 bool ReadFromMessage(const IPC::Message* m, void** iter) { | 73 bool ReadFromMessage(const IPC::Message* m, void** iter) { |
85 return inner_->ReadFromMessage(m, iter); | 74 return inner_->ReadFromMessage(m, iter); |
86 } | 75 } |
87 | 76 |
88 protected: | 77 protected: |
89 friend class SerializedVarReceiveInput; | 78 friend class SerializedVarReceiveInput; |
90 friend class SerializedVarReturnValue; | 79 friend class SerializedVarReturnValue; |
91 friend class SerializedVarOutParam; | 80 friend class SerializedVarOutParam; |
92 friend class SerializedVarSendInput; | 81 friend class SerializedVarSendInput; |
| 82 friend class SerializedVarTestConstructor; |
93 friend class SerializedVarVectorReceiveInput; | 83 friend class SerializedVarVectorReceiveInput; |
94 | 84 |
95 class Inner : public base::RefCounted<Inner> { | 85 class Inner : public base::RefCounted<Inner> { |
96 public: | 86 public: |
97 Inner(); | 87 Inner(); |
98 Inner(VarSerializationRules* serialization_rules); | 88 Inner(VarSerializationRules* serialization_rules); |
99 Inner(VarSerializationRules* serialization_rules, const PP_Var& var); | 89 Inner(VarSerializationRules* serialization_rules, const PP_Var& var); |
100 ~Inner(); | 90 ~Inner(); |
101 | 91 |
102 VarSerializationRules* serialization_rules() { | 92 VarSerializationRules* serialization_rules() { |
103 return serialization_rules_; | 93 return serialization_rules_; |
104 } | 94 } |
105 void set_serialization_rules(VarSerializationRules* serialization_rules) { | 95 void set_serialization_rules(VarSerializationRules* serialization_rules) { |
106 serialization_rules_ = serialization_rules; | 96 serialization_rules_ = serialization_rules; |
107 } | 97 } |
108 | 98 |
109 void set_cleanup_mode(CleanupMode cm) { cleanup_mode_ = cm; } | |
110 | |
111 // See outer class's declarations above. | 99 // See outer class's declarations above. |
112 PP_Var GetVar() const; | 100 PP_Var GetVar() const; |
113 PP_Var GetIncompleteVar() const; | 101 PP_Var GetIncompleteVar() const; |
114 void SetVar(PP_Var var); | 102 void SetVar(PP_Var var); |
115 const std::string& GetString() const; | 103 const std::string& GetString() const; |
116 std::string* GetStringPtr(); | 104 std::string* GetStringPtr(); |
117 | 105 |
118 void WriteToMessage(IPC::Message* m) const; | 106 void WriteToMessage(IPC::Message* m) const; |
119 bool ReadFromMessage(const IPC::Message* m, void** iter); | 107 bool ReadFromMessage(const IPC::Message* m, void** iter); |
120 | 108 |
| 109 // Sets the cleanup mode. See the CleanupMode enum below. These functions |
| 110 // are not just a simple setter in order to require that the appropriate |
| 111 // data is set along with the corresponding mode. |
| 112 void SetCleanupModeToEndSendPassRef(Dispatcher* dispatcher); |
| 113 void SetCleanupModeToEndReceiveCallerOwned(); |
| 114 |
121 private: | 115 private: |
| 116 enum CleanupMode { |
| 117 // The serialized var won't do anything special in the destructor |
| 118 // (default). |
| 119 CLEANUP_NONE, |
| 120 |
| 121 // The serialized var will call EndSendPassRef in the destructor. |
| 122 END_SEND_PASS_REF, |
| 123 |
| 124 // The serialized var will call EndReceiveCallerOwned in the destructor. |
| 125 END_RECEIVE_CALLER_OWNED |
| 126 }; |
| 127 |
122 // Rules for serializing and deserializing vars for this process type. | 128 // 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 | 129 // 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. | 130 // sending, or before converting back to a PP_Var when receiving. |
125 VarSerializationRules* serialization_rules_; | 131 VarSerializationRules* serialization_rules_; |
126 | 132 |
127 // If this is set to VARTYPE_STRING and the 'value.id' is 0, then the | 133 // 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 | 134 // 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 | 135 // called Deserialize with a valid Dispatcher yet, which is how we can |
130 // convert the serialized string value to a PP_Var string ID. | 136 // convert the serialized string value to a PP_Var string ID. |
131 // | 137 // |
132 // This var may not be complete until the serialization rules are set when | 138 // 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 | 139 // 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. | 140 // a string ID. Before this, the as_id will be 0 for VARTYPE_STRING. |
135 PP_Var var_; | 141 PP_Var var_; |
136 | 142 |
137 // Holds the literal string value to/from IPC. This will be valid of the | 143 // Holds the literal string value to/from IPC. This will be valid of the |
138 // var_ is VARTYPE_STRING. | 144 // var_ is VARTYPE_STRING. |
139 std::string string_value_; | 145 std::string string_value_; |
140 | 146 |
141 CleanupMode cleanup_mode_; | 147 CleanupMode cleanup_mode_; |
142 | 148 |
| 149 // The dispatcher saved for the call to EndSendPassRef for the cleanup. |
| 150 // This is only valid when cleanup_mode == END_SEND_PASS_REF. |
| 151 Dispatcher* dispatcher_for_end_send_pass_ref_; |
| 152 |
143 #ifndef NDEBUG | 153 #ifndef NDEBUG |
144 // When being sent or received over IPC, we should only be serialized or | 154 // When being sent or received over IPC, we should only be serialized or |
145 // deserialized once. These flags help us assert this is true. | 155 // deserialized once. These flags help us assert this is true. |
146 mutable bool has_been_serialized_; | 156 mutable bool has_been_serialized_; |
147 mutable bool has_been_deserialized_; | 157 mutable bool has_been_deserialized_; |
148 #endif | 158 #endif |
149 | 159 |
150 DISALLOW_COPY_AND_ASSIGN(Inner); | 160 DISALLOW_COPY_AND_ASSIGN(Inner); |
151 }; | 161 }; |
152 | 162 |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 // returned var pointer before this class goes out of scope. The var's | 381 // returned var pointer before this class goes out of scope. The var's |
372 // initial value will be VARTYPE_UNDEFINED. | 382 // initial value will be VARTYPE_UNDEFINED. |
373 PP_Var* OutParam(Dispatcher* dispatcher); | 383 PP_Var* OutParam(Dispatcher* dispatcher); |
374 | 384 |
375 private: | 385 private: |
376 SerializedVar* serialized_; | 386 SerializedVar* serialized_; |
377 | 387 |
378 // This is the value actually written by the code and returned by OutParam. | 388 // This is the value actually written by the code and returned by OutParam. |
379 // We'll write this into serialized_ in our destructor. | 389 // We'll write this into serialized_ in our destructor. |
380 PP_Var writable_var_; | 390 PP_Var writable_var_; |
| 391 |
| 392 Dispatcher* dispatcher_; |
381 }; | 393 }; |
382 | 394 |
383 // For returning an array of PP_Vars to the other side and transferring | 395 // For returning an array of PP_Vars to the other side and transferring |
384 // ownership. | 396 // ownership. |
385 // | 397 // |
386 class SerializedVarVectorOutParam { | 398 class SerializedVarVectorOutParam { |
387 public: | 399 public: |
388 SerializedVarVectorOutParam(std::vector<SerializedVar>* serialized); | 400 SerializedVarVectorOutParam(std::vector<SerializedVar>* serialized); |
389 ~SerializedVarVectorOutParam(); | 401 ~SerializedVarVectorOutParam(); |
390 | 402 |
391 uint32_t* CountOutParam() { return &count_; } | 403 uint32_t* CountOutParam() { return &count_; } |
392 PP_Var** ArrayOutParam(Dispatcher* dispatcher); | 404 PP_Var** ArrayOutParam(Dispatcher* dispatcher); |
393 | 405 |
394 private: | 406 private: |
395 Dispatcher* dispatcher_; | 407 Dispatcher* dispatcher_; |
396 std::vector<SerializedVar>* serialized_; | 408 std::vector<SerializedVar>* serialized_; |
397 | 409 |
398 uint32_t count_; | 410 uint32_t count_; |
399 PP_Var* array_; | 411 PP_Var* array_; |
400 }; | 412 }; |
401 | 413 |
| 414 // For tests that just want to construct a SerializedVar for giving it to one |
| 415 // of the other classes. |
| 416 class SerializedVarTestConstructor : public SerializedVar { |
| 417 public: |
| 418 // For POD-types and objects. |
| 419 explicit SerializedVarTestConstructor(const PP_Var& pod_var); |
| 420 |
| 421 // For strings. |
| 422 explicit SerializedVarTestConstructor(const std::string& str); |
| 423 }; |
| 424 |
| 425 // For tests that want to read what's in a SerializedVar. |
| 426 class SerializedVarTestReader : public SerializedVar { |
| 427 public: |
| 428 explicit SerializedVarTestReader(const SerializedVar& var); |
| 429 |
| 430 // The "incomplete" var is the one sent over the wire. Strings and object |
| 431 // IDs have not yet been converted, so this is the thing that tests will |
| 432 // actually want to check. |
| 433 PP_Var GetIncompleteVar() const { return inner_->GetIncompleteVar(); } |
| 434 |
| 435 const std::string& GetString() const { return inner_->GetString(); } |
| 436 }; |
| 437 |
402 } // namespace proxy | 438 } // namespace proxy |
403 } // namespace pp | 439 } // namespace pp |
404 | 440 |
405 #endif // PPAPI_PROXY_SERIALIZED_VAR_H_ | 441 #endif // PPAPI_PROXY_SERIALIZED_VAR_H_ |
406 | 442 |
OLD | NEW |