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

Side by Side Diff: components/translate/content/browser/data_file_browser_cld_data_provider.cc

Issue 2034413003: Delete the non-static CLD data source logic. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase to latest master Created 4 years, 6 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
OLDNEW
(Empty)
1 // Copyright 2014 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 // NOT DEAD CODE!
6 // This code isn't dead, even if it isn't currently being used. Please refer to:
7 // https://www.chromium.org/developers/how-tos/compact-language-detector-cld-dat a-source-configuration
8
9 #include "components/translate/content/browser/data_file_browser_cld_data_provid er.h"
10
11 #include "base/files/file.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/lazy_instance.h"
15 #include "base/logging.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/synchronization/lock.h"
18 #include "base/task_runner.h"
19 #include "components/translate/content/common/cld_data_source.h"
20 #include "components/translate/content/common/data_file_cld_data_provider_messag es.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/render_frame_host.h"
23 #include "content/public/browser/render_process_host.h"
24 #include "content/public/browser/web_contents.h"
25 #include "ipc/ipc_message.h"
26 #include "ipc/ipc_message_macros.h"
27 #include "ipc/ipc_platform_file.h"
28
29 namespace {
30 // The data file, cached as long as the process stays alive.
31 // We also track the offset at which the data starts, and its length.
32 base::LazyInstance<base::FilePath> g_cached_filepath; // guarded by g_file_lock
33 base::File* g_cached_file = NULL; // guarded by g_file_lock_
34 uint64_t g_cached_data_offset = 0; // guarded by g_file_lock_
35 uint64_t g_cached_data_length = 0; // guarded by g_file_lock_
36
37 // Guards g_cached_filepath
38 base::LazyInstance<base::Lock> g_file_lock_;
39 } // namespace
40
41 namespace translate {
42
43 void SetCldDataFilePath(const base::FilePath& path) {
44 VLOG(1) << "Setting CLD data file path to: " << path.value();
45 base::AutoLock lock(g_file_lock_.Get());
46 if (g_cached_filepath.Get() == path)
47 return; // no change necessary
48 g_cached_filepath.Get() = path;
49 // For sanity, clean these other values up just in case.
50 g_cached_file = NULL;
51 g_cached_data_length = 0;
52 g_cached_data_offset = 0;
53 }
54
55 base::FilePath GetCldDataFilePath() {
56 base::AutoLock lock(g_file_lock_.Get());
57 if (g_cached_filepath.Get().empty()) {
58 g_cached_filepath.Get() =
59 translate::CldDataSource::Get()->GetCldDataFilePath();
60 }
61 return g_cached_filepath.Get();
62 }
63
64 DataFileBrowserCldDataProvider::DataFileBrowserCldDataProvider(
65 content::WebContents* web_contents)
66 : web_contents_(web_contents), weak_pointer_factory_() {
67 }
68
69 DataFileBrowserCldDataProvider::~DataFileBrowserCldDataProvider() {
70 // web_contents_ outlives this object
71 }
72
73 bool DataFileBrowserCldDataProvider::OnMessageReceived(
74 const IPC::Message& message) {
75 bool handled = true;
76 IPC_BEGIN_MESSAGE_MAP(DataFileBrowserCldDataProvider, message)
77 IPC_MESSAGE_HANDLER(ChromeFrameHostMsg_NeedCldDataFile, OnCldDataRequest)
78 IPC_MESSAGE_UNHANDLED(handled = false)
79 IPC_END_MESSAGE_MAP()
80 return handled;
81 }
82
83 void DataFileBrowserCldDataProvider::OnCldDataRequest() {
84 // Quickly try to read g_cached_file. If valid, the file handle is
85 // cached and can be used immediately. Else, queue the caching task to the
86 // blocking pool.
87 VLOG(1) << "Received request for CLD data file.";
88 base::File* handle = NULL;
89 uint64_t data_offset = 0;
90 uint64_t data_length = 0;
91 {
92 base::AutoLock lock(g_file_lock_.Get());
93 handle = g_cached_file;
94 data_offset = g_cached_data_offset;
95 data_length = g_cached_data_length;
96 }
97
98 if (handle && handle->IsValid()) {
99 // Cached data available. Respond to the request.
100 VLOG(1) << "CLD data file is already cached, replying immediately.";
101 SendCldDataResponseInternal(handle, data_offset, data_length);
102 return;
103 }
104
105 if (weak_pointer_factory_.get() == NULL) {
106 weak_pointer_factory_.reset(
107 new base::WeakPtrFactory<DataFileBrowserCldDataProvider>(this));
108 weak_pointer_factory_.get()->GetWeakPtr().get();
109 }
110
111 // Else, we don't have the data file yet. Queue a caching attempt.
112 // The caching attempt happens in the blocking pool because it may involve
113 // arbitrary filesystem access.
114 // After the caching attempt is made, we call MaybeSendCLDDataAvailable
115 // to pass the file handle to the renderer. This only results in an IPC
116 // message if the caching attempt was successful.
117 VLOG(1) << "CLD data file not yet cached, deferring lookup";
118 content::BrowserThread::PostBlockingPoolTaskAndReply(
119 FROM_HERE,
120 base::Bind(&DataFileBrowserCldDataProvider::OnCldDataRequestInternal),
121 base::Bind(&DataFileBrowserCldDataProvider::SendCldDataResponse,
122 weak_pointer_factory_.get()->GetWeakPtr()));
123 }
124
125 void DataFileBrowserCldDataProvider::SendCldDataResponse() {
126 base::File* handle = NULL;
127 uint64_t data_offset = 0;
128 uint64_t data_length = 0;
129 {
130 base::AutoLock lock(g_file_lock_.Get());
131 handle = g_cached_file;
132 data_offset = g_cached_data_offset;
133 data_length = g_cached_data_length;
134 }
135
136 if (handle && handle->IsValid())
137 SendCldDataResponseInternal(handle, data_offset, data_length);
138 }
139
140 void DataFileBrowserCldDataProvider::SendCldDataResponseInternal(
141 const base::File* handle,
142 const uint64_t data_offset,
143 const uint64_t data_length) {
144 VLOG(1) << "Sending CLD data file response.";
145
146 content::RenderFrameHost* render_frame_host =
147 web_contents_->GetMainFrame();
148 if (render_frame_host == NULL) {
149 // Render frame destroyed, no need to bother.
150 VLOG(1) << "Lost render frame host, giving up";
151 return;
152 }
153
154 content::RenderProcessHost* render_process_host =
155 render_frame_host->GetProcess();
156 if (render_process_host == NULL) {
157 // Render process destroyed, render frame not yet dead. No need to bother.
158 VLOG(1) << "Lost render process, giving up";
159 return;
160 }
161
162 // Data available, respond to the request.
163 IPC::PlatformFileForTransit ipc_platform_file =
164 IPC::GetPlatformFileForTransit(handle->GetPlatformFile(), false);
165
166 // In general, sending a response from within the code path that is processing
167 // a request is discouraged because there is potential for deadlock (if the
168 // methods are sent synchronously) or loops (if the response can trigger a
169 // new request). Neither of these concerns is relevant in this code, so
170 // sending the response from within the code path of the request handler is
171 // safe.
172 render_frame_host->Send(
173 new ChromeFrameMsg_CldDataFileAvailable(render_frame_host->GetRoutingID(),
174 ipc_platform_file,
175 data_offset,
176 data_length));
177 }
178
179 void DataFileBrowserCldDataProvider::OnCldDataRequestInternal() {
180 // Because this function involves arbitrary file system access, it must run
181 // on the blocking pool.
182 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
183 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
184 VLOG(1) << "CLD data file caching attempt starting.";
185
186 {
187 base::AutoLock lock(g_file_lock_.Get());
188 if (g_cached_file) {
189 VLOG(1) << "CLD data file is already cached, aborting caching attempt";
190 return; // Already done, duplicate request
191 }
192 }
193
194 const base::FilePath path = GetCldDataFilePath();
195 if (path.empty()) {
196 VLOG(1) << "CLD data file does not yet have a known location.";
197 return;
198 }
199
200 // If the file exists, we can send an IPC-safe construct back to the
201 // renderer process immediately; otherwise, nothing to do here.
202 if (!base::PathExists(path)) {
203 VLOG(1) << "CLD data file does not exist.";
204 return;
205 }
206
207 // Attempt to open the file for reading.
208 std::unique_ptr<base::File> file(
209 new base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ));
210 if (!file->IsValid()) {
211 LOG(WARNING) << "CLD data file exists but cannot be opened";
212 return;
213 }
214
215 base::File::Info file_info;
216 if (!file->GetInfo(&file_info)) {
217 LOG(WARNING) << "CLD data file exists but cannot be inspected";
218 return;
219 }
220
221 // For now, our offset and length are simply 0 and the length of the file,
222 // respectively. If we later decide to include the CLD2 data file inside of
223 // a larger binary context, these params can be twiddled appropriately.
224 const uint64_t data_offset = 0;
225 const uint64_t data_length = file_info.size;
226
227 {
228 base::AutoLock lock(g_file_lock_.Get());
229 if (g_cached_file) {
230 // Idempotence: Racing another request on the blocking pool, abort.
231 VLOG(1) << "Another thread finished caching first, aborting.";
232 } else {
233 // Else, this request has taken care of it all. Cache all info.
234 VLOG(1) << "Caching CLD data file information.";
235 g_cached_file = file.release();
236 g_cached_data_offset = data_offset;
237 g_cached_data_length = data_length;
238 }
239 }
240 }
241
242 } // namespace translate
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698