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

Side by Side Diff: chrome/browser/ui/webui/chrome_url_data_manager.cc

Issue 12049052: Move core url data manager classes to content. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: review comments Created 7 years, 11 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
6
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/lazy_instance.h"
11 #include "base/memory/ref_counted_memory.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop.h"
14 #include "base/string_util.h"
15 #include "base/synchronization/lock.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/webui/chrome_url_data_manager_factory.h"
18 #include "chrome/browser/ui/webui/chrome_url_data_manager_backend.h"
19 #include "chrome/browser/ui/webui/chrome_web_ui_data_source.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/url_data_source.h"
22
23 using content::BrowserThread;
24
25 static base::LazyInstance<base::Lock>::Leaky
26 g_delete_lock = LAZY_INSTANCE_INITIALIZER;
27
28 // static
29 ChromeURLDataManager::URLDataSources* ChromeURLDataManager::data_sources_ =
30 NULL;
31
32 // Invoked on the IO thread to do the actual adding of the DataSource.
33 static void AddDataSourceOnIOThread(
34 const base::Callback<ChromeURLDataManagerBackend*(void)>& backend,
35 scoped_refptr<URLDataSourceImpl> data_source) {
36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
37 backend.Run()->AddDataSource(data_source.get());
38 }
39
40 ChromeURLDataManager::ChromeURLDataManager(
41 const base::Callback<ChromeURLDataManagerBackend*(void)>& backend)
42 : backend_(backend) {
43 }
44
45 ChromeURLDataManager::~ChromeURLDataManager() {
46 }
47
48 void ChromeURLDataManager::AddDataSource(URLDataSourceImpl* source) {
49 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
50 BrowserThread::PostTask(
51 BrowserThread::IO, FROM_HERE,
52 base::Bind(&AddDataSourceOnIOThread,
53 backend_, make_scoped_refptr(source)));
54 }
55
56 // static
57 void ChromeURLDataManager::DeleteDataSources() {
58 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
59 URLDataSources sources;
60 {
61 base::AutoLock lock(g_delete_lock.Get());
62 if (!data_sources_)
63 return;
64 data_sources_->swap(sources);
65 }
66 for (size_t i = 0; i < sources.size(); ++i)
67 delete sources[i];
68 }
69
70 // static
71 void ChromeURLDataManager::DeleteDataSource(
72 const URLDataSourceImpl* data_source) {
73 // Invoked when a DataSource is no longer referenced and needs to be deleted.
74 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
75 // We're on the UI thread, delete right away.
76 delete data_source;
77 return;
78 }
79
80 // We're not on the UI thread, add the DataSource to the list of DataSources
81 // to delete.
82 bool schedule_delete = false;
83 {
84 base::AutoLock lock(g_delete_lock.Get());
85 if (!data_sources_)
86 data_sources_ = new URLDataSources();
87 schedule_delete = data_sources_->empty();
88 data_sources_->push_back(data_source);
89 }
90 if (schedule_delete) {
91 // Schedule a task to delete the DataSource back on the UI thread.
92 BrowserThread::PostTask(
93 BrowserThread::UI, FROM_HERE,
94 base::Bind(&ChromeURLDataManager::DeleteDataSources));
95 }
96 }
97
98 // static
99 void ChromeURLDataManager::AddDataSource(
100 Profile* profile,
101 content::URLDataSource* source) {
102 ChromeURLDataManagerFactory::GetForProfile(profile)->AddDataSource(
103 new URLDataSourceImpl(source->GetSource(), source));
104 }
105
106 // static
107 void ChromeURLDataManager::AddWebUIDataSource(
108 Profile* profile,
109 content::WebUIDataSource* source) {
110 ChromeWebUIDataSource* impl = static_cast<ChromeWebUIDataSource*>(source);
111 ChromeURLDataManagerFactory::GetForProfile(profile)->AddDataSource(impl);
112 }
113
114 // static
115 bool ChromeURLDataManager::IsScheduledForDeletion(
116 const URLDataSourceImpl* data_source) {
117 base::AutoLock lock(g_delete_lock.Get());
118 if (!data_sources_)
119 return false;
120 return std::find(data_sources_->begin(), data_sources_->end(), data_source) !=
121 data_sources_->end();
122 }
123
124 URLDataSourceImpl::URLDataSourceImpl(const std::string& source_name,
125 content::URLDataSource* source)
126 : source_name_(source_name),
127 backend_(NULL),
128 source_(source) {
129 }
130
131 URLDataSourceImpl::~URLDataSourceImpl() {
132 }
133
134 void URLDataSourceImpl::SendResponse(
135 int request_id,
136 base::RefCountedMemory* bytes) {
137 // Take a ref-pointer on entry so byte->Release() will always get called.
138 scoped_refptr<base::RefCountedMemory> bytes_ptr(bytes);
139 if (ChromeURLDataManager::IsScheduledForDeletion(this)) {
140 // We're scheduled for deletion. Servicing the request would result in
141 // this->AddRef being invoked, even though the ref count is 0 and 'this' is
142 // about to be deleted. If the AddRef were allowed through, when 'this' is
143 // released it would be deleted again.
144 //
145 // This scenario occurs with DataSources that make history requests. Such
146 // DataSources do a history query in |StartDataRequest| and the request is
147 // live until the object is deleted (history requests don't up the ref
148 // count). This means it's entirely possible for the DataSource to invoke
149 // |SendResponse| between the time when there are no more refs and the time
150 // when the object is deleted.
151 return;
152 }
153 BrowserThread::PostTask(
154 BrowserThread::IO, FROM_HERE,
155 base::Bind(&URLDataSourceImpl::SendResponseOnIOThread, this, request_id,
156 bytes_ptr));
157 }
158
159 void URLDataSourceImpl::SendResponseOnIOThread(
160 int request_id,
161 scoped_refptr<base::RefCountedMemory> bytes) {
162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
163 if (backend_)
164 backend_->DataAvailable(request_id, bytes);
165 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/webui/chrome_url_data_manager.h ('k') | chrome/browser/ui/webui/chrome_url_data_manager_backend.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698