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

Side by Side Diff: rlz/lib/financial_ping.cc

Issue 2949263003: Remove call to GetBlockingPool in RLZ (Closed)
Patch Set: rebased Created 3 years, 4 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
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 // Library functions related to the Financial Server ping. 5 // Library functions related to the Financial Server ping.
6 6
7 #include "rlz/lib/financial_ping.h" 7 #include "rlz/lib/financial_ping.h"
8 8
9 #include <stdint.h> 9 #include <stdint.h>
10 10
11 #include <memory> 11 #include <memory>
12 12
13 #include "base/atomicops.h" 13 #include "base/atomicops.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/weak_ptr.h" 16 #include "base/memory/ref_counted.h"
17 #include "base/single_thread_task_runner.h"
18 #include "base/strings/string_util.h" 17 #include "base/strings/string_util.h"
19 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
20 #include "base/synchronization/lock.h"
21 #include "base/synchronization/waitable_event.h"
22 #include "base/task_scheduler/post_task.h"
21 #include "base/threading/thread_task_runner_handle.h" 23 #include "base/threading/thread_task_runner_handle.h"
22 #include "build/build_config.h" 24 #include "build/build_config.h"
23 #include "rlz/lib/assert.h" 25 #include "rlz/lib/assert.h"
24 #include "rlz/lib/lib_values.h" 26 #include "rlz/lib/lib_values.h"
25 #include "rlz/lib/machine_id.h" 27 #include "rlz/lib/machine_id.h"
26 #include "rlz/lib/rlz_lib.h" 28 #include "rlz/lib/rlz_lib.h"
27 #include "rlz/lib/rlz_value_store.h" 29 #include "rlz/lib/rlz_value_store.h"
28 #include "rlz/lib/string_utils.h" 30 #include "rlz/lib/string_utils.h"
29 31
30 #if !defined(OS_WIN) 32 #if !defined(OS_WIN)
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 198
197 bool FinancialPing::SetURLRequestContext( 199 bool FinancialPing::SetURLRequestContext(
198 net::URLRequestContextGetter* context) { 200 net::URLRequestContextGetter* context) {
199 base::subtle::Release_Store( 201 base::subtle::Release_Store(
200 &g_context, reinterpret_cast<AtomicWord>(context)); 202 &g_context, reinterpret_cast<AtomicWord>(context));
201 return true; 203 return true;
202 } 204 }
203 205
204 namespace { 206 namespace {
205 207
208 // A waitable event used to detect when either:
209 //
210 // 1/ the RLZ ping request completes
211 // 2/ the RLZ ping request times out
212 // 3/ browser shutdown begins
213 class RefCountedWaitableEvent
214 : public base::RefCountedThreadSafe<RefCountedWaitableEvent> {
215 public:
216 RefCountedWaitableEvent()
217 : event_(base::WaitableEvent::ResetPolicy::MANUAL,
218 base::WaitableEvent::InitialState::NOT_SIGNALED),
219 response_code_(net::URLFetcher::RESPONSE_CODE_INVALID) {}
220
221 void SignalShutdown() { event_.Signal(); }
222
223 void SignalFetchComplete(int response_code, std::string&& response) {
gab 2017/07/27 18:29:38 I'm all for r-value params but style guide still b
Roger Tawa OOO till Jul 10th 2017/07/28 18:43:06 Thanks, I had not seen that style guideline.
224 base::AutoLock autolock(lock_);
225 response_code_ = response_code;
226 response_ = response;
227 event_.Signal();
228 }
229
230 bool TimedWait(const base::TimeDelta& timeout) {
gab 2017/07/27 18:29:37 Pass TimeDelta by value (see time.h)
Roger Tawa OOO till Jul 10th 2017/07/28 18:43:07 Done.
231 return event_.TimedWait(timeout);
232 }
233
234 int GetResponseCode() {
235 base::AutoLock autolock(lock_);
236 return response_code_;
237 }
238
239 void TakeResponse(std::string* response) {
gab 2017/07/27 18:29:38 I think std::string TakeResponse(); is a simple
Roger Tawa OOO till Jul 10th 2017/07/28 18:43:07 Done.
240 base::AutoLock autolock(lock_);
241 *response = std::move(response_);
242 response_.clear();
gab 2017/07/27 18:29:37 The above std::move() would clear() implicitly I a
Roger Tawa OOO till Jul 10th 2017/07/28 18:43:06 Actually, it does not. After an object is moved,
gab 2017/07/28 19:28:57 Hmmm true, but you only TakeResponse() once per Re
Roger Tawa OOO till Jul 10th 2017/07/28 19:42:17 I'd rather not leave the member variable in an uns
243 }
244
245 private:
246 ~RefCountedWaitableEvent() {}
247 friend class base::RefCountedThreadSafe<RefCountedWaitableEvent>;
248
249 base::WaitableEvent event_;
250 base::Lock lock_;
251 std::string response_;
252 int response_code_;
gab 2017/07/27 18:29:38 For POD types I prefer C++11 inline member initial
Roger Tawa OOO till Jul 10th 2017/07/28 18:43:07 Done.
253 };
254
255 // A fetcher delegate that signals an instance of RefCountedWaitableEvent when
256 // the fetch completes.
206 class FinancialPingUrlFetcherDelegate : public net::URLFetcherDelegate { 257 class FinancialPingUrlFetcherDelegate : public net::URLFetcherDelegate {
207 public: 258 public:
208 FinancialPingUrlFetcherDelegate(const base::Closure& callback) 259 FinancialPingUrlFetcherDelegate(scoped_refptr<RefCountedWaitableEvent> event)
209 : callback_(callback) { 260 : event_(std::move(event)) {}
261
262 void SetFetcher(std::unique_ptr<net::URLFetcher> fetcher) {
263 fetcher_ = std::move(fetcher);
210 } 264 }
211 void OnURLFetchComplete(const net::URLFetcher* source) override;
212 265
213 private: 266 private:
214 base::Closure callback_; 267 void OnURLFetchComplete(const net::URLFetcher* source) override {
268 std::string response;
269 source->GetResponseAsString(&response);
270 event_->SignalFetchComplete(source->GetResponseCode(), std::move(response));
271 base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
272 }
273
274 scoped_refptr<RefCountedWaitableEvent> event_;
275 std::unique_ptr<net::URLFetcher> fetcher_;
215 }; 276 };
216 277
217 void FinancialPingUrlFetcherDelegate::OnURLFetchComplete(
218 const net::URLFetcher* source) {
219 callback_.Run();
220 }
221
222 bool send_financial_ping_interrupted_for_test = false; 278 bool send_financial_ping_interrupted_for_test = false;
223 279
224 } // namespace 280 } // namespace
225 281
226 void ShutdownCheck(base::WeakPtr<base::RunLoop> weak) { 282 void ShutdownCheck(scoped_refptr<RefCountedWaitableEvent> event) {
227 if (!weak.get())
228 return;
229 if (!base::subtle::Acquire_Load(&g_context)) { 283 if (!base::subtle::Acquire_Load(&g_context)) {
230 send_financial_ping_interrupted_for_test = true; 284 send_financial_ping_interrupted_for_test = true;
231 weak->QuitClosure().Run(); 285 event->SignalShutdown();
232 return; 286 return;
233 } 287 }
234 // How frequently the financial ping thread should check 288 // How frequently the financial ping thread should check
235 // the shutdown condition? 289 // the shutdown condition?
236 const base::TimeDelta kInterval = base::TimeDelta::FromMilliseconds(500); 290 const base::TimeDelta kInterval = base::TimeDelta::FromMilliseconds(500);
237 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 291 base::PostDelayedTask(FROM_HERE, base::Bind(&ShutdownCheck, event),
238 FROM_HERE, base::Bind(&ShutdownCheck, weak), kInterval); 292 kInterval);
293 }
294
295 void PingRlzServer(std::string url,
296 scoped_refptr<RefCountedWaitableEvent> event) {
297 // Copy the pointer to stack because g_context may be set to NULL
298 // in different thread. The instance is guaranteed to exist while
299 // the method is running.
300 net::URLRequestContextGetter* context =
301 reinterpret_cast<net::URLRequestContextGetter*>(
302 base::subtle::Acquire_Load(&g_context));
303
304 // Browser shutdown will cause the context to be reset to NULL.
305 // ShutdownCheck will catch this.
306 if (!context)
307 return;
308
309 // Delegate will delete itself when the fetch completes.
310 FinancialPingUrlFetcherDelegate* delegate =
311 new FinancialPingUrlFetcherDelegate(event);
312
313 net::NetworkTrafficAnnotationTag traffic_annotation =
314 net::DefineNetworkTrafficAnnotation("rlz_ping", R"(
315 semantics {
316 sender: "RLZ Ping"
317 description:
318 "Used for measuring the effectiveness of a promotion. See the "
319 "Chrome Privacy Whitepaper for complete details."
320 trigger:
321 "1- At Chromium first run.\n"
322 "2- When Chromium is re-activated by a new promotion.\n"
323 "3- Once a week thereafter as long as Chromium is used.\n"
324 data:
325 "1- Non-unique cohort tag of when Chromium was installed.\n"
326 "2- Unique machine id on desktop platforms.\n"
327 "3- Whether Google is the default omnibox search.\n"
328 "4- Whether google.com is the default home page."
329 destination: GOOGLE_OWNED_SERVICE
330 }
331 policy {
332 cookies_allowed: NO
333 setting: "This feature cannot be disabled in settings."
334 policy_exception_justification: "Not implemented."
335 })");
336 std::unique_ptr<net::URLFetcher> fetcher = net::URLFetcher::Create(
337 GURL(url), net::URLFetcher::GET, delegate, traffic_annotation);
338
339 fetcher->SetLoadFlags(
340 net::LOAD_DISABLE_CACHE | net::LOAD_DO_NOT_SEND_AUTH_DATA |
341 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES);
342
343 // Ensure rlz_lib::SetURLRequestContext() has been called before sending
344 // pings.
345 fetcher->SetRequestContext(context);
346 fetcher->Start();
347
348 // Pass ownership of the fetcher to the delegate. Otherwise the fetch will
349 // be canceled when the URLFetcher object is destroyed.
350 delegate->SetFetcher(std::move(fetcher));
239 } 351 }
240 #endif 352 #endif
241 353
242 bool FinancialPing::PingServer(const char* request, std::string* response) { 354 bool FinancialPing::PingServer(const char* request, std::string* response) {
243 if (!response) 355 if (!response)
244 return false; 356 return false;
245 357
246 response->clear(); 358 response->clear();
247 359
248 #if defined(RLZ_NETWORK_IMPLEMENTATION_WIN_INET) 360 #if defined(RLZ_NETWORK_IMPLEMENTATION_WIN_INET)
gab 2017/07/27 18:29:38 Curious, is this still ever a thing or should that
Roger Tawa OOO till Jul 10th 2017/07/28 18:43:06 Possibly, not sure, but not in this CL as you say.
249 // Initialize WinInet. 361 // Initialize WinInet.
250 InternetHandle inet_handle = InternetOpenA(kFinancialPingUserAgent, 362 InternetHandle inet_handle = InternetOpenA(kFinancialPingUserAgent,
251 INTERNET_OPEN_TYPE_PRECONFIG, 363 INTERNET_OPEN_TYPE_PRECONFIG,
252 NULL, NULL, 0); 364 NULL, NULL, 0);
253 if (!inet_handle) 365 if (!inet_handle)
254 return false; 366 return false;
255 367
256 // Open network connection. 368 // Open network connection.
257 InternetHandle connection_handle = InternetConnectA(inet_handle, 369 InternetHandle connection_handle = InternetConnectA(inet_handle,
258 kFinancialServer, kFinancialPort, "", "", INTERNET_SERVICE_HTTP, 370 kFinancialServer, kFinancialPort, "", "", INTERNET_SERVICE_HTTP,
(...skipping 30 matching lines...) Expand all
289 401
290 DWORD bytes_read = 0; 402 DWORD bytes_read = 0;
291 while (InternetReadFile(http_handle, buffer.get(), kMaxPingResponseLength, 403 while (InternetReadFile(http_handle, buffer.get(), kMaxPingResponseLength,
292 &bytes_read) && bytes_read > 0) { 404 &bytes_read) && bytes_read > 0) {
293 response->append(buffer.get(), bytes_read); 405 response->append(buffer.get(), bytes_read);
294 bytes_read = 0; 406 bytes_read = 0;
295 }; 407 };
296 408
297 return true; 409 return true;
298 #else 410 #else
299 // Copy the pointer to stack because g_context may be set to NULL
300 // in different thread. The instance is guaranteed to exist while
301 // the method is running.
302 net::URLRequestContextGetter* context =
303 reinterpret_cast<net::URLRequestContextGetter*>(
304 base::subtle::Acquire_Load(&g_context));
305
306 // Browser shutdown will cause the context to be reset to NULL.
307 if (!context)
308 return false;
309
310 // Run a blocking event loop to match the win inet implementation.
311 std::unique_ptr<base::MessageLoop> message_loop;
312 // Ensure that we have a MessageLoop.
313 if (!base::MessageLoop::current())
314 message_loop.reset(new base::MessageLoop);
315 base::RunLoop loop;
316 FinancialPingUrlFetcherDelegate delegate(loop.QuitClosure());
317
318 std::string url = base::StringPrintf("http://%s:%d%s", 411 std::string url = base::StringPrintf("http://%s:%d%s",
319 kFinancialServer, kFinancialPort, 412 kFinancialServer, kFinancialPort,
320 request); 413 request);
321 414
322 net::NetworkTrafficAnnotationTag traffic_annotation = 415 // Use a waitable event to cause this function to block, to match the
323 net::DefineNetworkTrafficAnnotation("rlz_ping", R"( 416 // wininet implementation.
324 semantics { 417 auto event = base::MakeRefCounted<RefCountedWaitableEvent>();
325 sender: "RLZ Ping"
326 description:
327 "Used for measuring the effectiveness of a promotion. See the "
328 "Chrome Privacy Whitepaper for complete details."
329 trigger:
330 "1- At Chromium first run.\n"
331 "2- When Chromium is re-activated by a new promotion.\n"
332 "3- Once a week thereafter as long as Chromium is used.\n"
333 data:
334 "1- Non-unique cohort tag of when Chromium was installed.\n"
335 "2- Unique machine id on desktop platforms.\n"
336 "3- Whether Google is the default omnibox search.\n"
337 "4- Whether google.com is the default home page."
338 destination: GOOGLE_OWNED_SERVICE
339 }
340 policy {
341 cookies_allowed: NO
342 setting: "This feature cannot be disabled in settings."
343 policy_exception_justification: "Not implemented."
344 })");
345 std::unique_ptr<net::URLFetcher> fetcher = net::URLFetcher::Create(
346 GURL(url), net::URLFetcher::GET, &delegate, traffic_annotation);
347 418
348 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE | 419 base::PostTask(FROM_HERE, base::Bind(&ShutdownCheck, event));
gab 2017/07/27 18:29:38 PostTaskWithTraits with TaskPriority::BACKGROUND?
Roger Tawa OOO till Jul 10th 2017/07/28 18:43:07 Done.
349 net::LOAD_DO_NOT_SEND_AUTH_DATA |
350 net::LOAD_DO_NOT_SEND_COOKIES |
351 net::LOAD_DO_NOT_SAVE_COOKIES);
352 420
353 // Ensure rlz_lib::SetURLRequestContext() has been called before sending 421 scoped_refptr<base::SequencedTaskRunner> background_runner(
gab 2017/07/27 18:29:38 Add a comment here (or on PingRlzServer() or both)
Roger Tawa OOO till Jul 10th 2017/07/28 18:43:06 Done.
354 // pings. 422 base::CreateSequencedTaskRunnerWithTraits(
355 fetcher->SetRequestContext(context); 423 {base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
424 base::TaskPriority::BACKGROUND}));
425 background_runner->PostTask(FROM_HERE,
426 base::Bind(&PingRlzServer, url, event));
356 427
357 base::WeakPtrFactory<base::RunLoop> weak(&loop); 428 bool is_signaled = event->TimedWait(base::TimeDelta::FromMinutes(5));
358 429 if (!is_signaled || event->GetResponseCode() != 200)
359 const base::TimeDelta kTimeout = base::TimeDelta::FromMinutes(5);
360 base::MessageLoop::ScopedNestableTaskAllower allow_nested(
361 base::MessageLoop::current());
362 base::ThreadTaskRunnerHandle::Get()->PostTask(
363 FROM_HERE, base::Bind(&ShutdownCheck, weak.GetWeakPtr()));
364 base::ThreadTaskRunnerHandle::Get()->PostTask(
365 FROM_HERE,
366 base::Bind(&net::URLFetcher::Start, base::Unretained(fetcher.get())));
367 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
368 FROM_HERE, loop.QuitClosure(), kTimeout);
369
370 loop.Run();
371
372 if (fetcher->GetResponseCode() != 200)
373 return false; 430 return false;
374 431
375 return fetcher->GetResponseAsString(response); 432 event->TakeResponse(response);
433 return true;
376 #endif 434 #endif
377 } 435 }
378 436
379 bool FinancialPing::IsPingTime(Product product, bool no_delay) { 437 bool FinancialPing::IsPingTime(Product product, bool no_delay) {
380 ScopedRlzValueStoreLock lock; 438 ScopedRlzValueStoreLock lock;
381 RlzValueStore* store = lock.GetStore(); 439 RlzValueStore* store = lock.GetStore();
382 if (!store || !store->HasAccess(RlzValueStore::kReadAccess)) 440 if (!store || !store->HasAccess(RlzValueStore::kReadAccess))
383 return false; 441 return false;
384 442
385 int64_t last_ping = 0; 443 int64_t last_ping = 0;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 } 489 }
432 490
433 bool WasSendFinancialPingInterrupted() { 491 bool WasSendFinancialPingInterrupted() {
434 return send_financial_ping_interrupted_for_test; 492 return send_financial_ping_interrupted_for_test;
435 } 493 }
436 494
437 } // namespace test 495 } // namespace test
438 #endif 496 #endif
439 497
440 } // namespace rlz_lib 498 } // namespace rlz_lib
OLDNEW
« components/rlz/rlz_tracker.cc ('K') | « ios/chrome/browser/rlz/rlz_tracker_delegate_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698