| 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 |