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

Side by Side Diff: chrome/browser/extensions/user_script_master.cc

Issue 282393002: Getting rid of raw pointers to SharedMemory in UserScriptMaster (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 7 months 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 | « chrome/browser/extensions/user_script_master.h ('k') | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/browser/extensions/user_script_master.h" 5 #include "chrome/browser/extensions/user_script_master.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
10 #include "base/file_util.h" 11 #include "base/file_util.h"
11 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
12 #include "base/version.h" 13 #include "base/version.h"
13 #include "chrome/browser/chrome_notification_types.h" 14 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/extensions/extension_service.h" 15 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/extensions/extension_util.h" 16 #include "chrome/browser/extensions/extension_util.h"
16 #include "chrome/browser/extensions/image_loader.h" 17 #include "chrome/browser/extensions/image_loader.h"
17 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/common/extensions/api/i18n/default_locale_handler.h" 19 #include "chrome/common/extensions/api/i18n/default_locale_handler.h"
19 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h" 20 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 this->extensions_info_ = extensions_info; 160 this->extensions_info_ = extensions_info;
160 BrowserThread::PostTask( 161 BrowserThread::PostTask(
161 BrowserThread::FILE, FROM_HERE, 162 BrowserThread::FILE, FROM_HERE,
162 base::Bind( 163 base::Bind(
163 &UserScriptMaster::ScriptReloader::RunLoad, this, user_scripts)); 164 &UserScriptMaster::ScriptReloader::RunLoad, this, user_scripts));
164 } 165 }
165 166
166 UserScriptMaster::ScriptReloader::~ScriptReloader() {} 167 UserScriptMaster::ScriptReloader::~ScriptReloader() {}
167 168
168 void UserScriptMaster::ScriptReloader::NotifyMaster( 169 void UserScriptMaster::ScriptReloader::NotifyMaster(
169 base::SharedMemory* memory) { 170 scoped_ptr<base::SharedMemory> memory) {
170 // The master went away, so these new scripts aren't useful anymore. 171 // The master could go away
171 if (!master_) 172 if (master_)
172 delete memory; 173 master_->NewScriptsAvailable(memory.Pass());
173 else
174 master_->NewScriptsAvailable(memory);
175 174
176 // Drop our self-reference. 175 // Drop our self-reference.
177 // Balances StartLoad(). 176 // Balances StartLoad().
178 Release(); 177 Release();
179 } 178 }
180 179
181 static void VerifyContent(ContentVerifier* verifier, 180 static void VerifyContent(ContentVerifier* verifier,
182 const std::string& extension_id, 181 const std::string& extension_id,
183 const base::FilePath& extension_root, 182 const base::FilePath& extension_root,
184 const base::FilePath& relative_path, 183 const base::FilePath& relative_path,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 return NULL; 276 return NULL;
278 } 277 }
279 278
280 return file_util::LoadMessageBundleSubstitutionMap( 279 return file_util::LoadMessageBundleSubstitutionMap(
281 extensions_info_[extension_id].first, 280 extensions_info_[extension_id].first,
282 extension_id, 281 extension_id,
283 extensions_info_[extension_id].second); 282 extensions_info_[extension_id].second);
284 } 283 }
285 284
286 // Pickle user scripts and return pointer to the shared memory. 285 // Pickle user scripts and return pointer to the shared memory.
287 static base::SharedMemory* Serialize(const UserScriptList& scripts) { 286 static scoped_ptr<base::SharedMemory> Serialize(const UserScriptList& scripts) {
288 Pickle pickle; 287 Pickle pickle;
289 pickle.WriteUInt64(scripts.size()); 288 pickle.WriteUInt64(scripts.size());
290 for (size_t i = 0; i < scripts.size(); i++) { 289 for (size_t i = 0; i < scripts.size(); i++) {
291 const UserScript& script = scripts[i]; 290 const UserScript& script = scripts[i];
292 // TODO(aa): This can be replaced by sending content script metadata to 291 // TODO(aa): This can be replaced by sending content script metadata to
293 // renderers along with other extension data in ExtensionMsg_Loaded. 292 // renderers along with other extension data in ExtensionMsg_Loaded.
294 // See crbug.com/70516. 293 // See crbug.com/70516.
295 script.Pickle(&pickle); 294 script.Pickle(&pickle);
296 // Write scripts as 'data' so that we can read it out in the slave without 295 // Write scripts as 'data' so that we can read it out in the slave without
297 // allocating a new string. 296 // allocating a new string.
298 for (size_t j = 0; j < script.js_scripts().size(); j++) { 297 for (size_t j = 0; j < script.js_scripts().size(); j++) {
299 base::StringPiece contents = script.js_scripts()[j].GetContent(); 298 base::StringPiece contents = script.js_scripts()[j].GetContent();
300 pickle.WriteData(contents.data(), contents.length()); 299 pickle.WriteData(contents.data(), contents.length());
301 } 300 }
302 for (size_t j = 0; j < script.css_scripts().size(); j++) { 301 for (size_t j = 0; j < script.css_scripts().size(); j++) {
303 base::StringPiece contents = script.css_scripts()[j].GetContent(); 302 base::StringPiece contents = script.css_scripts()[j].GetContent();
304 pickle.WriteData(contents.data(), contents.length()); 303 pickle.WriteData(contents.data(), contents.length());
305 } 304 }
306 } 305 }
307 306
308 // Create the shared memory object. 307 // Create the shared memory object.
309 base::SharedMemory shared_memory; 308 base::SharedMemory shared_memory;
310 309
311 base::SharedMemoryCreateOptions options; 310 base::SharedMemoryCreateOptions options;
312 options.size = pickle.size(); 311 options.size = pickle.size();
313 options.share_read_only = true; 312 options.share_read_only = true;
314 if (!shared_memory.Create(options)) 313 if (!shared_memory.Create(options))
315 return NULL; 314 return scoped_ptr<base::SharedMemory>();
316 315
317 if (!shared_memory.Map(pickle.size())) 316 if (!shared_memory.Map(pickle.size()))
318 return NULL; 317 return scoped_ptr<base::SharedMemory>();
319 318
320 // Copy the pickle to shared memory. 319 // Copy the pickle to shared memory.
321 memcpy(shared_memory.memory(), pickle.data(), pickle.size()); 320 memcpy(shared_memory.memory(), pickle.data(), pickle.size());
322 321
323 base::SharedMemoryHandle readonly_handle; 322 base::SharedMemoryHandle readonly_handle;
324 if (!shared_memory.ShareReadOnlyToProcess(base::GetCurrentProcessHandle(), 323 if (!shared_memory.ShareReadOnlyToProcess(base::GetCurrentProcessHandle(),
325 &readonly_handle)) 324 &readonly_handle))
326 return NULL; 325 return scoped_ptr<base::SharedMemory>();
327 326
328 return new base::SharedMemory(readonly_handle, /*read_only=*/true); 327 return make_scoped_ptr(new base::SharedMemory(readonly_handle,
328 /*read_only=*/true));
329 } 329 }
330 330
331 // This method will be called on the file thread. 331 // This method will be called on the file thread.
332 void UserScriptMaster::ScriptReloader::RunLoad( 332 void UserScriptMaster::ScriptReloader::RunLoad(
333 const UserScriptList& user_scripts) { 333 const UserScriptList& user_scripts) {
334 LoadUserScripts(const_cast<UserScriptList*>(&user_scripts)); 334 LoadUserScripts(const_cast<UserScriptList*>(&user_scripts));
335 335
336 // Scripts now contains list of up-to-date scripts. Load the content in the 336 // Scripts now contains list of up-to-date scripts. Load the content in the
337 // shared memory and let the master know it's ready. We need to post the task 337 // shared memory and let the master know it's ready. We need to post the task
338 // back even if no scripts ware found to balance the AddRef/Release calls. 338 // back even if no scripts ware found to balance the AddRef/Release calls.
339 BrowserThread::PostTask( 339 BrowserThread::PostTask(
340 master_thread_id_, FROM_HERE, 340 master_thread_id_, FROM_HERE,
341 base::Bind( 341 base::Bind(&ScriptReloader::NotifyMaster, this,
Jeffrey Yasskin 2014/05/17 00:50:33 Generally use `git cl format` to format your chang
342 &ScriptReloader::NotifyMaster, this, Serialize(user_scripts))); 342 base::Passed(Serialize(user_scripts))));
343 } 343 }
344 344
345 UserScriptMaster::UserScriptMaster(Profile* profile) 345 UserScriptMaster::UserScriptMaster(Profile* profile)
346 : extensions_service_ready_(false), 346 : extensions_service_ready_(false),
347 pending_load_(false), 347 pending_load_(false),
348 profile_(profile), 348 profile_(profile),
349 extension_registry_observer_(this) { 349 extension_registry_observer_(this) {
350 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); 350 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
351 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, 351 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
352 content::Source<Profile>(profile_)); 352 content::Source<Profile>(profile_));
353 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, 353 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
354 content::NotificationService::AllBrowserContextsAndSources()); 354 content::NotificationService::AllBrowserContextsAndSources());
355 } 355 }
356 356
357 UserScriptMaster::~UserScriptMaster() { 357 UserScriptMaster::~UserScriptMaster() {
358 if (script_reloader_.get()) 358 if (script_reloader_.get())
359 script_reloader_->DisownMaster(); 359 script_reloader_->DisownMaster();
360 } 360 }
361 361
362 void UserScriptMaster::NewScriptsAvailable(base::SharedMemory* handle) { 362 void UserScriptMaster::NewScriptsAvailable(
363 // Ensure handle is deleted or released. 363 scoped_ptr<base::SharedMemory> handle) {
364 scoped_ptr<base::SharedMemory> handle_deleter(handle);
365 364
366 if (pending_load_) { 365 if (pending_load_) {
367 // While we were loading, there were further changes. Don't bother 366 // While we were loading, there were further changes. Don't bother
368 // notifying about these scripts and instead just immediately reload. 367 // notifying about these scripts and instead just immediately reload.
369 pending_load_ = false; 368 pending_load_ = false;
370 StartLoad(); 369 StartLoad();
371 } else { 370 } else {
372 // We're no longer loading. 371 // We're no longer loading.
373 script_reloader_ = NULL; 372 script_reloader_ = NULL;
374 373
375 if (handle == NULL) { 374 if (handle == NULL) {
376 // This can happen if we run out of file descriptors. In that case, we 375 // This can happen if we run out of file descriptors. In that case, we
377 // have a choice between silently omitting all user scripts for new tabs, 376 // have a choice between silently omitting all user scripts for new tabs,
378 // by nulling out shared_memory_, or only silently omitting new ones by 377 // by nulling out shared_memory_, or only silently omitting new ones by
379 // leaving the existing object in place. The second seems less bad, even 378 // leaving the existing object in place. The second seems less bad, even
380 // though it removes the possibility that freeing the shared memory block 379 // though it removes the possibility that freeing the shared memory block
381 // would open up enough FDs for long enough for a retry to succeed. 380 // would open up enough FDs for long enough for a retry to succeed.
382 381
383 // Pretend the extension change didn't happen. 382 // Pretend the extension change didn't happen.
384 return; 383 return;
385 } 384 }
386 385
387 // We've got scripts ready to go. 386 // We've got scripts ready to go.
388 shared_memory_.swap(handle_deleter); 387 shared_memory_.swap(handle);
Jeffrey Yasskin 2014/05/17 00:50:33 Since we're not using |handle| anymore, it's a bit
389 388
390 for (content::RenderProcessHost::iterator i( 389 for (content::RenderProcessHost::iterator i(
391 content::RenderProcessHost::AllHostsIterator()); 390 content::RenderProcessHost::AllHostsIterator());
392 !i.IsAtEnd(); i.Advance()) { 391 !i.IsAtEnd(); i.Advance()) {
393 SendUpdate(i.GetCurrentValue(), handle); 392 SendUpdate(i.GetCurrentValue(), shared_memory_.get());
394 } 393 }
395 394
396 content::NotificationService::current()->Notify( 395 content::NotificationService::current()->Notify(
397 chrome::NOTIFICATION_USER_SCRIPTS_UPDATED, 396 chrome::NOTIFICATION_USER_SCRIPTS_UPDATED,
398 content::Source<Profile>(profile_), 397 content::Source<Profile>(profile_),
399 content::Details<base::SharedMemory>(handle)); 398 content::Details<base::SharedMemory>(shared_memory_.get()));
400 } 399 }
401 } 400 }
402 401
403 ContentVerifier* UserScriptMaster::content_verifier() { 402 ContentVerifier* UserScriptMaster::content_verifier() {
404 ExtensionSystem* system = ExtensionSystem::Get(profile_); 403 ExtensionSystem* system = ExtensionSystem::Get(profile_);
405 return system->content_verifier(); 404 return system->content_verifier();
406 } 405 }
407 406
408 void UserScriptMaster::OnExtensionLoaded( 407 void UserScriptMaster::OnExtensionLoaded(
409 content::BrowserContext* browser_context, 408 content::BrowserContext* browser_context,
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 509
511 base::SharedMemoryHandle handle_for_process; 510 base::SharedMemoryHandle handle_for_process;
512 if (!shared_memory->ShareToProcess(handle, &handle_for_process)) 511 if (!shared_memory->ShareToProcess(handle, &handle_for_process))
513 return; // This can legitimately fail if the renderer asserts at startup. 512 return; // This can legitimately fail if the renderer asserts at startup.
514 513
515 if (base::SharedMemory::IsHandleValid(handle_for_process)) 514 if (base::SharedMemory::IsHandleValid(handle_for_process))
516 process->Send(new ExtensionMsg_UpdateUserScripts(handle_for_process)); 515 process->Send(new ExtensionMsg_UpdateUserScripts(handle_for_process));
517 } 516 }
518 517
519 } // namespace extensions 518 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/user_script_master.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698