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

Side by Side Diff: chrome/renderer/extensions/renderer_extension_bindings.cc

Issue 344044: Clean up extension message port data in the renderer. (Closed)
Patch Set: Created 11 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 #include "chrome/renderer/extensions/renderer_extension_bindings.h" 5 #include "chrome/renderer/extensions/renderer_extension_bindings.h"
6 6
7 #include "app/resource_bundle.h" 7 #include "app/resource_bundle.h"
8 #include "base/basictypes.h" 8 #include "base/basictypes.h"
9 #include "base/values.h" 9 #include "base/values.h"
10 #include "chrome/common/render_messages.h" 10 #include "chrome/common/render_messages.h"
(...skipping 19 matching lines...) Expand all
30 namespace { 30 namespace {
31 31
32 struct ExtensionData { 32 struct ExtensionData {
33 struct PortData { 33 struct PortData {
34 int ref_count; // how many contexts have a handle to this port 34 int ref_count; // how many contexts have a handle to this port
35 bool disconnected; // true if this port was forcefully disconnected 35 bool disconnected; // true if this port was forcefully disconnected
36 PortData() : ref_count(0), disconnected(false) {} 36 PortData() : ref_count(0), disconnected(false) {}
37 }; 37 };
38 std::map<int, PortData> ports; // port ID -> data 38 std::map<int, PortData> ports; // port ID -> data
39 }; 39 };
40 bool HasPortData(int port_id) {
41 return Singleton<ExtensionData>::get()->ports.find(port_id) !=
42 Singleton<ExtensionData>::get()->ports.end();
43 }
40 ExtensionData::PortData& GetPortData(int port_id) { 44 ExtensionData::PortData& GetPortData(int port_id) {
41 return Singleton<ExtensionData>::get()->ports[port_id]; 45 return Singleton<ExtensionData>::get()->ports[port_id];
42 } 46 }
47 void ClearPortData(int port_id) {
48 Singleton<ExtensionData>::get()->ports.erase(port_id);
49 }
43 50
51 const char kPortClosedError[] = "Attempting to use a disconnected port object";
44 const char* kExtensionDeps[] = { EventBindings::kName }; 52 const char* kExtensionDeps[] = { EventBindings::kName };
45 53
46 class ExtensionImpl : public ExtensionBase { 54 class ExtensionImpl : public ExtensionBase {
47 public: 55 public:
48 ExtensionImpl() 56 ExtensionImpl()
49 : ExtensionBase(RendererExtensionBindings::kName, 57 : ExtensionBase(RendererExtensionBindings::kName,
50 GetStringResource<IDR_RENDERER_EXTENSION_BINDINGS_JS>(), 58 GetStringResource<IDR_RENDERER_EXTENSION_BINDINGS_JS>(),
51 arraysize(kExtensionDeps), kExtensionDeps) { 59 arraysize(kExtensionDeps), kExtensionDeps) {
52 } 60 }
53 ~ExtensionImpl() {} 61 ~ExtensionImpl() {}
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 } 100 }
93 101
94 // Sends a message along the given channel. 102 // Sends a message along the given channel.
95 static v8::Handle<v8::Value> PostMessage(const v8::Arguments& args) { 103 static v8::Handle<v8::Value> PostMessage(const v8::Arguments& args) {
96 RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext(); 104 RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext();
97 if (!renderview) 105 if (!renderview)
98 return v8::Undefined(); 106 return v8::Undefined();
99 107
100 if (args.Length() >= 2 && args[0]->IsInt32() && args[1]->IsString()) { 108 if (args.Length() >= 2 && args[0]->IsInt32() && args[1]->IsString()) {
101 int port_id = args[0]->Int32Value(); 109 int port_id = args[0]->Int32Value();
110 if (!HasPortData(port_id)) {
111 return v8::ThrowException(v8::Exception::Error(
112 v8::String::New(kPortClosedError)));
113 }
102 std::string message = *v8::String::Utf8Value(args[1]->ToString()); 114 std::string message = *v8::String::Utf8Value(args[1]->ToString());
103 renderview->Send(new ViewHostMsg_ExtensionPostMessage( 115 renderview->Send(new ViewHostMsg_ExtensionPostMessage(
104 renderview->routing_id(), port_id, message)); 116 renderview->routing_id(), port_id, message));
105 } 117 }
106 return v8::Undefined(); 118 return v8::Undefined();
107 } 119 }
108 120
109 // Forcefully disconnects a port. 121 // Forcefully disconnects a port.
110 static v8::Handle<v8::Value> CloseChannel(const v8::Arguments& args) { 122 static v8::Handle<v8::Value> CloseChannel(const v8::Arguments& args) {
111 if (args.Length() >= 1 && args[0]->IsInt32()) { 123 if (args.Length() >= 1 && args[0]->IsInt32()) {
112 int port_id = args[0]->Int32Value(); 124 int port_id = args[0]->Int32Value();
125 if (!HasPortData(port_id)) {
Aaron Boodman 2009/10/31 19:21:22 Maybe we don't want to throw here? It seems nice t
Matt Perry 2009/11/03 00:39:36 Done.
126 return v8::ThrowException(v8::Exception::Error(
127 v8::String::New(kPortClosedError)));
128 }
113 // Send via the RenderThread because the RenderView might be closing. 129 // Send via the RenderThread because the RenderView might be closing.
114 EventBindings::GetRenderThread()->Send( 130 EventBindings::GetRenderThread()->Send(
115 new ViewHostMsg_ExtensionCloseChannel(port_id)); 131 new ViewHostMsg_ExtensionCloseChannel(port_id));
116 GetPortData(port_id).disconnected = true; 132 ClearPortData(port_id);
117 } 133 }
118 return v8::Undefined(); 134 return v8::Undefined();
119 } 135 }
120 136
121 // A new port has been created for a context. This occurs both when script 137 // A new port has been created for a context. This occurs both when script
122 // opens a connection, and when a connection is opened to this script. 138 // opens a connection, and when a connection is opened to this script.
123 static v8::Handle<v8::Value> PortAddRef(const v8::Arguments& args) { 139 static v8::Handle<v8::Value> PortAddRef(const v8::Arguments& args) {
124 if (args.Length() >= 1 && args[0]->IsInt32()) { 140 if (args.Length() >= 1 && args[0]->IsInt32()) {
125 int port_id = args[0]->Int32Value(); 141 int port_id = args[0]->Int32Value();
126 ++GetPortData(port_id).ref_count; 142 ++GetPortData(port_id).ref_count;
127 } 143 }
128 return v8::Undefined(); 144 return v8::Undefined();
129 } 145 }
130 146
131 // The frame a port lived in has been destroyed. When there are no more 147 // The frame a port lived in has been destroyed. When there are no more
132 // frames with a reference to a given port, we will disconnect it and notify 148 // frames with a reference to a given port, we will disconnect it and notify
133 // the other end of the channel. 149 // the other end of the channel.
134 static v8::Handle<v8::Value> PortRelease(const v8::Arguments& args) { 150 static v8::Handle<v8::Value> PortRelease(const v8::Arguments& args) {
135 if (args.Length() >= 1 && args[0]->IsInt32()) { 151 if (args.Length() >= 1 && args[0]->IsInt32()) {
136 int port_id = args[0]->Int32Value(); 152 int port_id = args[0]->Int32Value();
137 if (!GetPortData(port_id).disconnected && 153 if (HasPortData(port_id) && --GetPortData(port_id).ref_count == 0) {
138 --GetPortData(port_id).ref_count == 0) {
139 // Send via the RenderThread because the RenderView might be closing. 154 // Send via the RenderThread because the RenderView might be closing.
140 EventBindings::GetRenderThread()->Send( 155 EventBindings::GetRenderThread()->Send(
141 new ViewHostMsg_ExtensionCloseChannel(port_id)); 156 new ViewHostMsg_ExtensionCloseChannel(port_id));
157 ClearPortData(port_id);
142 } 158 }
143 } 159 }
144 return v8::Undefined(); 160 return v8::Undefined();
145 } 161 }
146 }; 162 };
147 163
148 // Convert a ListValue to a vector of V8 values. 164 // Convert a ListValue to a vector of V8 values.
149 static std::vector< v8::Handle<v8::Value> > ListValueToV8( 165 static std::vector< v8::Handle<v8::Value> > ListValueToV8(
150 const ListValue& value) { 166 const ListValue& value) {
151 std::vector< v8::Handle<v8::Value> > v8_values; 167 std::vector< v8::Handle<v8::Value> > v8_values;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 return extension; 216 return extension;
201 } 217 }
202 218
203 void RendererExtensionBindings::Invoke(const std::string& function_name, 219 void RendererExtensionBindings::Invoke(const std::string& function_name,
204 const ListValue& args, 220 const ListValue& args,
205 RenderView* renderview) { 221 RenderView* renderview) {
206 v8::HandleScope handle_scope; 222 v8::HandleScope handle_scope;
207 std::vector< v8::Handle<v8::Value> > argv = ListValueToV8(args); 223 std::vector< v8::Handle<v8::Value> > argv = ListValueToV8(args);
208 EventBindings::CallFunction(function_name, argv.size(), &argv[0], renderview); 224 EventBindings::CallFunction(function_name, argv.size(), &argv[0], renderview);
209 } 225 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698