OLD | NEW |
---|---|
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/waitable_event.h" | |
21 #include "base/task_scheduler/post_task.h" | |
21 #include "base/threading/thread_task_runner_handle.h" | 22 #include "base/threading/thread_task_runner_handle.h" |
22 #include "build/build_config.h" | 23 #include "build/build_config.h" |
23 #include "rlz/lib/assert.h" | 24 #include "rlz/lib/assert.h" |
24 #include "rlz/lib/lib_values.h" | 25 #include "rlz/lib/lib_values.h" |
25 #include "rlz/lib/machine_id.h" | 26 #include "rlz/lib/machine_id.h" |
26 #include "rlz/lib/rlz_lib.h" | 27 #include "rlz/lib/rlz_lib.h" |
27 #include "rlz/lib/rlz_value_store.h" | 28 #include "rlz/lib/rlz_value_store.h" |
28 #include "rlz/lib/string_utils.h" | 29 #include "rlz/lib/string_utils.h" |
29 | 30 |
30 #if !defined(OS_WIN) | 31 #if !defined(OS_WIN) |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
196 | 197 |
197 bool FinancialPing::SetURLRequestContext( | 198 bool FinancialPing::SetURLRequestContext( |
198 net::URLRequestContextGetter* context) { | 199 net::URLRequestContextGetter* context) { |
199 base::subtle::Release_Store( | 200 base::subtle::Release_Store( |
200 &g_context, reinterpret_cast<AtomicWord>(context)); | 201 &g_context, reinterpret_cast<AtomicWord>(context)); |
201 return true; | 202 return true; |
202 } | 203 } |
203 | 204 |
204 namespace { | 205 namespace { |
205 | 206 |
207 class RefCountedWaitableEvent | |
208 : public base::RefCountedThreadSafe<RefCountedWaitableEvent> { | |
209 public: | |
210 RefCountedWaitableEvent() | |
211 : event_(base::WaitableEvent::ResetPolicy::MANUAL, | |
212 base::WaitableEvent::InitialState::NOT_SIGNALED) {} | |
213 | |
214 void Signal() { event_.Signal(); } | |
215 | |
216 bool TimedWait(const base::TimeDelta& timeout) { | |
217 return event_.TimedWait(timeout); | |
218 } | |
219 | |
220 private: | |
221 ~RefCountedWaitableEvent() {} | |
222 friend class base::RefCountedThreadSafe<RefCountedWaitableEvent>; | |
223 | |
224 base::WaitableEvent event_; | |
225 }; | |
226 | |
206 class FinancialPingUrlFetcherDelegate : public net::URLFetcherDelegate { | 227 class FinancialPingUrlFetcherDelegate : public net::URLFetcherDelegate { |
207 public: | 228 public: |
208 FinancialPingUrlFetcherDelegate(const base::Closure& callback) | 229 FinancialPingUrlFetcherDelegate(scoped_refptr<RefCountedWaitableEvent> event) |
209 : callback_(callback) { | 230 : event_(event) {} |
gab
2017/07/17 16:44:20
std::move(event)
Roger Tawa OOO till Jul 10th
2017/07/17 19:19:37
This happens exactly once per run of chrome.exe in
gab
2017/07/17 21:05:20
It's just a good habit to have when taking scoped_
| |
231 | |
232 void OnURLFetchComplete(const net::URLFetcher* source) override { | |
gab
2017/07/17 16:44:20
Does this work? url_fetch.h says:
// You may crea
Roger Tawa OOO till Jul 10th
2017/07/17 19:19:36
I think that comment in URLFetcher may no longer b
gab
2017/07/17 21:05:20
Hmmmm, well it's definitely also not running on th
Roger Tawa OOO till Jul 10th
2017/07/21 13:53:42
Got it. The main point is to not block this seque
gab
2017/07/21 22:39:17
True, so long as that doesn't become SequencedTask
| |
233 event_->Signal(); | |
210 } | 234 } |
211 void OnURLFetchComplete(const net::URLFetcher* source) override; | |
212 | 235 |
213 private: | 236 private: |
214 base::Closure callback_; | 237 scoped_refptr<RefCountedWaitableEvent> event_; |
215 }; | 238 }; |
216 | 239 |
217 void FinancialPingUrlFetcherDelegate::OnURLFetchComplete( | |
218 const net::URLFetcher* source) { | |
219 callback_.Run(); | |
220 } | |
221 | |
222 bool send_financial_ping_interrupted_for_test = false; | 240 bool send_financial_ping_interrupted_for_test = false; |
223 | 241 |
224 } // namespace | 242 } // namespace |
225 | 243 |
226 void ShutdownCheck(base::WeakPtr<base::RunLoop> weak) { | 244 void ShutdownCheck(scoped_refptr<RefCountedWaitableEvent> event) { |
227 if (!weak.get()) | |
228 return; | |
229 if (!base::subtle::Acquire_Load(&g_context)) { | 245 if (!base::subtle::Acquire_Load(&g_context)) { |
230 send_financial_ping_interrupted_for_test = true; | 246 send_financial_ping_interrupted_for_test = true; |
231 weak->QuitClosure().Run(); | 247 event->Signal(); |
232 return; | 248 return; |
233 } | 249 } |
234 // How frequently the financial ping thread should check | 250 // How frequently the financial ping thread should check |
235 // the shutdown condition? | 251 // the shutdown condition? |
236 const base::TimeDelta kInterval = base::TimeDelta::FromMilliseconds(500); | 252 const base::TimeDelta kInterval = base::TimeDelta::FromMilliseconds(500); |
237 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 253 base::PostDelayedTask(FROM_HERE, base::Bind(&ShutdownCheck, event), |
238 FROM_HERE, base::Bind(&ShutdownCheck, weak), kInterval); | 254 kInterval); |
239 } | 255 } |
240 #endif | 256 #endif |
241 | 257 |
242 bool FinancialPing::PingServer(const char* request, std::string* response) { | 258 bool FinancialPing::PingServer(const char* request, std::string* response) { |
243 if (!response) | 259 if (!response) |
244 return false; | 260 return false; |
245 | 261 |
246 response->clear(); | 262 response->clear(); |
247 | 263 |
248 #if defined(RLZ_NETWORK_IMPLEMENTATION_WIN_INET) | 264 #if defined(RLZ_NETWORK_IMPLEMENTATION_WIN_INET) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
300 // in different thread. The instance is guaranteed to exist while | 316 // in different thread. The instance is guaranteed to exist while |
301 // the method is running. | 317 // the method is running. |
302 net::URLRequestContextGetter* context = | 318 net::URLRequestContextGetter* context = |
303 reinterpret_cast<net::URLRequestContextGetter*>( | 319 reinterpret_cast<net::URLRequestContextGetter*>( |
304 base::subtle::Acquire_Load(&g_context)); | 320 base::subtle::Acquire_Load(&g_context)); |
305 | 321 |
306 // Browser shutdown will cause the context to be reset to NULL. | 322 // Browser shutdown will cause the context to be reset to NULL. |
307 if (!context) | 323 if (!context) |
308 return false; | 324 return false; |
309 | 325 |
310 // Run a blocking event loop to match the win inet implementation. | 326 auto event = base::MakeRefCounted<RefCountedWaitableEvent>(); |
gab
2017/07/17 16:44:20
Should we keep the comment to say that this is "bl
Roger Tawa OOO till Jul 10th
2017/07/17 19:19:36
Done.
| |
311 std::unique_ptr<base::MessageLoop> message_loop; | 327 FinancialPingUrlFetcherDelegate delegate(event); |
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 | 328 |
318 std::string url = base::StringPrintf("http://%s:%d%s", | 329 std::string url = base::StringPrintf("http://%s:%d%s", |
319 kFinancialServer, kFinancialPort, | 330 kFinancialServer, kFinancialPort, |
320 request); | 331 request); |
321 | 332 |
322 net::NetworkTrafficAnnotationTag traffic_annotation = | 333 net::NetworkTrafficAnnotationTag traffic_annotation = |
323 net::DefineNetworkTrafficAnnotation("rlz_ping", R"( | 334 net::DefineNetworkTrafficAnnotation("rlz_ping", R"( |
324 semantics { | 335 semantics { |
325 sender: "RLZ Ping" | 336 sender: "RLZ Ping" |
326 description: | 337 description: |
(...skipping 20 matching lines...) Expand all Loading... | |
347 | 358 |
348 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE | | 359 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE | |
349 net::LOAD_DO_NOT_SEND_AUTH_DATA | | 360 net::LOAD_DO_NOT_SEND_AUTH_DATA | |
350 net::LOAD_DO_NOT_SEND_COOKIES | | 361 net::LOAD_DO_NOT_SEND_COOKIES | |
351 net::LOAD_DO_NOT_SAVE_COOKIES); | 362 net::LOAD_DO_NOT_SAVE_COOKIES); |
352 | 363 |
353 // Ensure rlz_lib::SetURLRequestContext() has been called before sending | 364 // Ensure rlz_lib::SetURLRequestContext() has been called before sending |
354 // pings. | 365 // pings. |
355 fetcher->SetRequestContext(context); | 366 fetcher->SetRequestContext(context); |
356 | 367 |
357 base::WeakPtrFactory<base::RunLoop> weak(&loop); | 368 base::PostTask(FROM_HERE, base::Bind(&ShutdownCheck, event)); |
369 base::PostTask(FROM_HERE, base::Bind(&net::URLFetcher::Start, | |
gab
2017/07/17 16:44:20
net::URLFetcher::Start() seems to just PostTask it
Roger Tawa OOO till Jul 10th
2017/07/17 19:19:36
No, see comment above.
gab
2017/07/17 21:05:20
If the fetcher replies on another sequence, isn't
Roger Tawa OOO till Jul 10th
2017/07/21 13:53:42
Correct, this was racy and still is. That's OK th
gab
2017/07/21 22:39:17
It's okay that this may fail and will be retried b
| |
370 base::Unretained(fetcher.get()))); | |
358 | 371 |
359 const base::TimeDelta kTimeout = base::TimeDelta::FromMinutes(5); | 372 event->TimedWait(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 | 373 |
372 if (fetcher->GetResponseCode() != 200) | 374 if (fetcher->GetResponseCode() != 200) |
373 return false; | 375 return false; |
374 | 376 |
375 return fetcher->GetResponseAsString(response); | 377 return fetcher->GetResponseAsString(response); |
376 #endif | 378 #endif |
377 } | 379 } |
378 | 380 |
379 bool FinancialPing::IsPingTime(Product product, bool no_delay) { | 381 bool FinancialPing::IsPingTime(Product product, bool no_delay) { |
380 ScopedRlzValueStoreLock lock; | 382 ScopedRlzValueStoreLock lock; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
431 } | 433 } |
432 | 434 |
433 bool WasSendFinancialPingInterrupted() { | 435 bool WasSendFinancialPingInterrupted() { |
434 return send_financial_ping_interrupted_for_test; | 436 return send_financial_ping_interrupted_for_test; |
435 } | 437 } |
436 | 438 |
437 } // namespace test | 439 } // namespace test |
438 #endif | 440 #endif |
439 | 441 |
440 } // namespace rlz_lib | 442 } // namespace rlz_lib |
OLD | NEW |