OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 "ios/web/web_thread_impl.h" | 5 #include "ios/web/web_thread_impl.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/atomicops.h" | 10 #include "base/atomicops.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 } | 42 } |
43 | 43 |
44 // An implementation of SingleThreadTaskRunner to be used in conjunction | 44 // An implementation of SingleThreadTaskRunner to be used in conjunction |
45 // with WebThread. | 45 // with WebThread. |
46 class WebThreadTaskRunner : public base::SingleThreadTaskRunner { | 46 class WebThreadTaskRunner : public base::SingleThreadTaskRunner { |
47 public: | 47 public: |
48 explicit WebThreadTaskRunner(WebThread::ID identifier) : id_(identifier) {} | 48 explicit WebThreadTaskRunner(WebThread::ID identifier) : id_(identifier) {} |
49 | 49 |
50 // SingleThreadTaskRunner implementation. | 50 // SingleThreadTaskRunner implementation. |
51 bool PostDelayedTask(const tracked_objects::Location& from_here, | 51 bool PostDelayedTask(const tracked_objects::Location& from_here, |
52 base::Closure task, | 52 base::OnceClosure task, |
53 base::TimeDelta delay) override { | 53 base::TimeDelta delay) override { |
54 return WebThread::PostDelayedTask(id_, from_here, std::move(task), delay); | 54 return WebThread::PostDelayedTask(id_, from_here, std::move(task), delay); |
55 } | 55 } |
56 | 56 |
57 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, | 57 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
58 base::Closure task, | 58 base::OnceClosure task, |
59 base::TimeDelta delay) override { | 59 base::TimeDelta delay) override { |
60 return WebThread::PostNonNestableDelayedTask(id_, from_here, | 60 return WebThread::PostNonNestableDelayedTask(id_, from_here, |
61 std::move(task), delay); | 61 std::move(task), delay); |
62 } | 62 } |
63 | 63 |
64 bool RunsTasksOnCurrentThread() const override { | 64 bool RunsTasksOnCurrentThread() const override { |
65 return WebThread::CurrentlyOn(id_); | 65 return WebThread::CurrentlyOn(id_); |
66 } | 66 } |
67 | 67 |
68 protected: | 68 protected: |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 for (int i = identifier_ + 1; i < ID_COUNT; ++i) { | 284 for (int i = identifier_ + 1; i < ID_COUNT; ++i) { |
285 DCHECK(!globals.threads[i]) | 285 DCHECK(!globals.threads[i]) |
286 << "Threads must be listed in the reverse order that they die"; | 286 << "Threads must be listed in the reverse order that they die"; |
287 } | 287 } |
288 #endif | 288 #endif |
289 } | 289 } |
290 | 290 |
291 // static | 291 // static |
292 bool WebThreadImpl::PostTaskHelper(WebThread::ID identifier, | 292 bool WebThreadImpl::PostTaskHelper(WebThread::ID identifier, |
293 const tracked_objects::Location& from_here, | 293 const tracked_objects::Location& from_here, |
294 base::Closure task, | 294 base::OnceClosure task, |
295 base::TimeDelta delay, | 295 base::TimeDelta delay, |
296 bool nestable) { | 296 bool nestable) { |
297 DCHECK(identifier >= 0 && identifier < ID_COUNT); | 297 DCHECK(identifier >= 0 && identifier < ID_COUNT); |
298 // Optimization: to avoid unnecessary locks, we listed the ID enumeration in | 298 // Optimization: to avoid unnecessary locks, we listed the ID enumeration in |
299 // order of lifetime. So no need to lock if we know that the target thread | 299 // order of lifetime. So no need to lock if we know that the target thread |
300 // outlives current thread. | 300 // outlives current thread. |
301 // Note: since the array is so small, ok to loop instead of creating a map, | 301 // Note: since the array is so small, ok to loop instead of creating a map, |
302 // which would require a lock because std::map isn't thread safe, defeating | 302 // which would require a lock because std::map isn't thread safe, defeating |
303 // the whole purpose of this optimization. | 303 // the whole purpose of this optimization. |
304 WebThread::ID current_thread = ID_COUNT; | 304 WebThread::ID current_thread = ID_COUNT; |
(...skipping 19 matching lines...) Expand all Loading... |
324 } | 324 } |
325 | 325 |
326 if (!target_thread_outlives_current) | 326 if (!target_thread_outlives_current) |
327 globals.lock.Release(); | 327 globals.lock.Release(); |
328 | 328 |
329 return !!message_loop; | 329 return !!message_loop; |
330 } | 330 } |
331 | 331 |
332 // static | 332 // static |
333 bool WebThread::PostBlockingPoolTask(const tracked_objects::Location& from_here, | 333 bool WebThread::PostBlockingPoolTask(const tracked_objects::Location& from_here, |
334 base::Closure task) { | 334 base::OnceClosure task) { |
335 return g_globals.Get().blocking_pool->PostWorkerTask(from_here, | 335 return g_globals.Get().blocking_pool->PostWorkerTask(from_here, |
336 std::move(task)); | 336 std::move(task)); |
337 } | 337 } |
338 | 338 |
339 // static | 339 // static |
340 bool WebThread::PostBlockingPoolTaskAndReply( | 340 bool WebThread::PostBlockingPoolTaskAndReply( |
341 const tracked_objects::Location& from_here, | 341 const tracked_objects::Location& from_here, |
342 base::Closure task, | 342 base::OnceClosure task, |
343 base::Closure reply) { | 343 base::OnceClosure reply) { |
344 return g_globals.Get().blocking_pool->PostTaskAndReply( | 344 return g_globals.Get().blocking_pool->PostTaskAndReply( |
345 from_here, std::move(task), std::move(reply)); | 345 from_here, std::move(task), std::move(reply)); |
346 } | 346 } |
347 | 347 |
348 // static | 348 // static |
349 bool WebThread::PostBlockingPoolSequencedTask( | 349 bool WebThread::PostBlockingPoolSequencedTask( |
350 const std::string& sequence_token_name, | 350 const std::string& sequence_token_name, |
351 const tracked_objects::Location& from_here, | 351 const tracked_objects::Location& from_here, |
352 base::Closure task) { | 352 base::OnceClosure task) { |
353 return g_globals.Get().blocking_pool->PostNamedSequencedWorkerTask( | 353 return g_globals.Get().blocking_pool->PostNamedSequencedWorkerTask( |
354 sequence_token_name, from_here, std::move(task)); | 354 sequence_token_name, from_here, std::move(task)); |
355 } | 355 } |
356 | 356 |
357 // static | 357 // static |
358 base::SequencedWorkerPool* WebThread::GetBlockingPool() { | 358 base::SequencedWorkerPool* WebThread::GetBlockingPool() { |
359 return g_globals.Get().blocking_pool.get(); | 359 return g_globals.Get().blocking_pool.get(); |
360 } | 360 } |
361 | 361 |
362 // static | 362 // static |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 WebThreadGlobals& globals = g_globals.Get(); | 402 WebThreadGlobals& globals = g_globals.Get(); |
403 base::AutoLock lock(globals.lock); | 403 base::AutoLock lock(globals.lock); |
404 DCHECK(identifier >= 0 && identifier < ID_COUNT); | 404 DCHECK(identifier >= 0 && identifier < ID_COUNT); |
405 return globals.threads[identifier] && | 405 return globals.threads[identifier] && |
406 globals.threads[identifier]->message_loop(); | 406 globals.threads[identifier]->message_loop(); |
407 } | 407 } |
408 | 408 |
409 // static | 409 // static |
410 bool WebThread::PostTask(ID identifier, | 410 bool WebThread::PostTask(ID identifier, |
411 const tracked_objects::Location& from_here, | 411 const tracked_objects::Location& from_here, |
412 base::Closure task) { | 412 base::OnceClosure task) { |
413 return WebThreadImpl::PostTaskHelper(identifier, from_here, std::move(task), | 413 return WebThreadImpl::PostTaskHelper(identifier, from_here, std::move(task), |
414 base::TimeDelta(), true); | 414 base::TimeDelta(), true); |
415 } | 415 } |
416 | 416 |
417 // static | 417 // static |
418 bool WebThread::PostDelayedTask(ID identifier, | 418 bool WebThread::PostDelayedTask(ID identifier, |
419 const tracked_objects::Location& from_here, | 419 const tracked_objects::Location& from_here, |
420 base::Closure task, | 420 base::OnceClosure task, |
421 base::TimeDelta delay) { | 421 base::TimeDelta delay) { |
422 return WebThreadImpl::PostTaskHelper(identifier, from_here, std::move(task), | 422 return WebThreadImpl::PostTaskHelper(identifier, from_here, std::move(task), |
423 delay, true); | 423 delay, true); |
424 } | 424 } |
425 | 425 |
426 // static | 426 // static |
427 bool WebThread::PostNonNestableTask(ID identifier, | 427 bool WebThread::PostNonNestableTask(ID identifier, |
428 const tracked_objects::Location& from_here, | 428 const tracked_objects::Location& from_here, |
429 base::Closure task) { | 429 base::OnceClosure task) { |
430 return WebThreadImpl::PostTaskHelper(identifier, from_here, std::move(task), | 430 return WebThreadImpl::PostTaskHelper(identifier, from_here, std::move(task), |
431 base::TimeDelta(), false); | 431 base::TimeDelta(), false); |
432 } | 432 } |
433 | 433 |
434 // static | 434 // static |
435 bool WebThread::PostNonNestableDelayedTask( | 435 bool WebThread::PostNonNestableDelayedTask( |
436 ID identifier, | 436 ID identifier, |
437 const tracked_objects::Location& from_here, | 437 const tracked_objects::Location& from_here, |
438 base::Closure task, | 438 base::OnceClosure task, |
439 base::TimeDelta delay) { | 439 base::TimeDelta delay) { |
440 return WebThreadImpl::PostTaskHelper(identifier, from_here, std::move(task), | 440 return WebThreadImpl::PostTaskHelper(identifier, from_here, std::move(task), |
441 delay, false); | 441 delay, false); |
442 } | 442 } |
443 | 443 |
444 // static | 444 // static |
445 bool WebThread::PostTaskAndReply(ID identifier, | 445 bool WebThread::PostTaskAndReply(ID identifier, |
446 const tracked_objects::Location& from_here, | 446 const tracked_objects::Location& from_here, |
447 base::Closure task, | 447 base::OnceClosure task, |
448 base::Closure reply) { | 448 base::OnceClosure reply) { |
449 return GetTaskRunnerForThread(identifier) | 449 return GetTaskRunnerForThread(identifier) |
450 ->PostTaskAndReply(from_here, std::move(task), std::move(reply)); | 450 ->PostTaskAndReply(from_here, std::move(task), std::move(reply)); |
451 } | 451 } |
452 | 452 |
453 // static | 453 // static |
454 bool WebThread::GetCurrentThreadIdentifier(ID* identifier) { | 454 bool WebThread::GetCurrentThreadIdentifier(ID* identifier) { |
455 if (g_globals == nullptr) | 455 if (g_globals == nullptr) |
456 return false; | 456 return false; |
457 | 457 |
458 base::MessageLoop* cur_message_loop = base::MessageLoop::current(); | 458 base::MessageLoop* cur_message_loop = base::MessageLoop::current(); |
(...skipping 22 matching lines...) Expand all Loading... |
481 AtomicWord* storage = | 481 AtomicWord* storage = |
482 reinterpret_cast<AtomicWord*>(&globals.thread_delegates[identifier]); | 482 reinterpret_cast<AtomicWord*>(&globals.thread_delegates[identifier]); |
483 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( | 483 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( |
484 storage, reinterpret_cast<AtomicWord>(delegate)); | 484 storage, reinterpret_cast<AtomicWord>(delegate)); |
485 | 485 |
486 // This catches registration when previously registered. | 486 // This catches registration when previously registered. |
487 DCHECK(!delegate || !old_pointer); | 487 DCHECK(!delegate || !old_pointer); |
488 } | 488 } |
489 | 489 |
490 } // namespace web | 490 } // namespace web |
OLD | NEW |