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

Side by Side Diff: content/child/scheduler/task_queue_manager.cc

Issue 1072473002: Speculative patch: Make it safe to delete the TQM inside a Task (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 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 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 "content/child/scheduler/task_queue_manager.h" 5 #include "content/child/scheduler/task_queue_manager.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <set> 8 #include <set>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner, 457 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner,
458 TaskQueueSelector* selector, 458 TaskQueueSelector* selector,
459 const char* disabled_by_default_tracing_category) 459 const char* disabled_by_default_tracing_category)
460 : main_task_runner_(main_task_runner), 460 : main_task_runner_(main_task_runner),
461 selector_(selector), 461 selector_(selector),
462 pending_dowork_count_(0), 462 pending_dowork_count_(0),
463 work_batch_size_(1), 463 work_batch_size_(1),
464 time_source_(nullptr), 464 time_source_(nullptr),
465 disabled_by_default_tracing_category_( 465 disabled_by_default_tracing_category_(
466 disabled_by_default_tracing_category), 466 disabled_by_default_tracing_category),
467 deletion_sentinel_(new DeletionSentinel()),
467 weak_factory_(this) { 468 weak_factory_(this) {
468 DCHECK(main_task_runner->RunsTasksOnCurrentThread()); 469 DCHECK(main_task_runner->RunsTasksOnCurrentThread());
469 TRACE_EVENT_OBJECT_CREATED_WITH_ID(disabled_by_default_tracing_category, 470 TRACE_EVENT_OBJECT_CREATED_WITH_ID(disabled_by_default_tracing_category,
470 "TaskQueueManager", this); 471 "TaskQueueManager", this);
471 472
472 task_queue_manager_weak_ptr_ = weak_factory_.GetWeakPtr(); 473 task_queue_manager_weak_ptr_ = weak_factory_.GetWeakPtr();
473 for (size_t i = 0; i < task_queue_count; i++) { 474 for (size_t i = 0; i < task_queue_count; i++) {
474 scoped_refptr<internal::TaskQueue> queue(make_scoped_refptr( 475 scoped_refptr<internal::TaskQueue> queue(make_scoped_refptr(
475 new internal::TaskQueue(this, disabled_by_default_tracing_category))); 476 new internal::TaskQueue(this, disabled_by_default_tracing_category)));
476 queues_.push_back(queue); 477 queues_.push_back(queue);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 } 570 }
570 pending_dowork_count_++; 571 pending_dowork_count_++;
571 } 572 }
572 573
573 main_task_runner_->PostTask( 574 main_task_runner_->PostTask(
574 FROM_HERE, Bind(&TaskQueueManager::DoWork, task_queue_manager_weak_ptr_, 575 FROM_HERE, Bind(&TaskQueueManager::DoWork, task_queue_manager_weak_ptr_,
575 on_main_thread)); 576 on_main_thread));
576 } 577 }
577 578
578 void TaskQueueManager::DoWork(bool posted_from_main_thread) { 579 void TaskQueueManager::DoWork(bool posted_from_main_thread) {
580 scoped_refptr<DeletionSentinel> protect(deletion_sentinel_);
581
579 if (posted_from_main_thread) { 582 if (posted_from_main_thread) {
580 pending_dowork_count_--; 583 pending_dowork_count_--;
581 DCHECK_GE(pending_dowork_count_, 0); 584 DCHECK_GE(pending_dowork_count_, 0);
582 } 585 }
583 DCHECK(main_thread_checker_.CalledOnValidThread()); 586 DCHECK(main_thread_checker_.CalledOnValidThread());
584 587
585 // Pass nullptr to UpdateWorkQueues here to prevent waking up a 588 // Pass nullptr to UpdateWorkQueues here to prevent waking up a
586 // pump-after-wakeup queue. 589 // pump-after-wakeup queue.
587 if (!UpdateWorkQueues(nullptr)) 590 if (!UpdateWorkQueues(nullptr))
588 return; 591 return;
589 592
590 base::PendingTask previous_task((tracked_objects::Location()), 593 base::PendingTask previous_task((tracked_objects::Location()),
591 (base::Closure())); 594 (base::Closure()));
592 for (int i = 0; i < work_batch_size_; i++) { 595 for (int i = 0; i < work_batch_size_; i++) {
593 size_t queue_index; 596 size_t queue_index;
594 if (!SelectWorkQueueToService(&queue_index)) 597 if (!SelectWorkQueueToService(&queue_index))
595 return; 598 return;
596 // Note that this function won't post another call to DoWork if one is 599 // Note that this function won't post another call to DoWork if one is
597 // already pending, so it is safe to call it in a loop. 600 // already pending, so it is safe to call it in a loop.
598 MaybePostDoWorkOnMainRunner(); 601 MaybePostDoWorkOnMainRunner();
599 ProcessTaskFromWorkQueue(queue_index, i > 0, &previous_task); 602 ProcessTaskFromWorkQueue(queue_index, i > 0, &previous_task);
600 603
604 // Detect if the TaskQueueManager got deleted during the
Sami 2015/04/08 14:24:04 This should probably be moved to within ProcessTas
alex clarke (OOO till 29th) 2015/04/08 14:33:05 Done.
605 // ProcessTaskFromWorkQueue call.
606 if (protect->HasOneRef())
607 return;
608
601 if (!UpdateWorkQueues(&previous_task)) 609 if (!UpdateWorkQueues(&previous_task))
602 return; 610 return;
603 } 611 }
604 } 612 }
605 613
606 bool TaskQueueManager::SelectWorkQueueToService(size_t* out_queue_index) { 614 bool TaskQueueManager::SelectWorkQueueToService(size_t* out_queue_index) {
607 bool should_run = selector_->SelectWorkQueueToService(out_queue_index); 615 bool should_run = selector_->SelectWorkQueueToService(out_queue_index);
608 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( 616 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
609 disabled_by_default_tracing_category_, "TaskQueueManager", this, 617 disabled_by_default_tracing_category_, "TaskQueueManager", this,
610 AsValueWithSelectorResult(should_run, *out_queue_index)); 618 AsValueWithSelectorResult(should_run, *out_queue_index));
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 state->EndArray(); 713 state->EndArray();
706 state->BeginDictionary("selector"); 714 state->BeginDictionary("selector");
707 selector_->AsValueInto(state.get()); 715 selector_->AsValueInto(state.get());
708 state->EndDictionary(); 716 state->EndDictionary();
709 if (should_run) 717 if (should_run)
710 state->SetInteger("selected_queue", selected_queue); 718 state->SetInteger("selected_queue", selected_queue);
711 return state; 719 return state;
712 } 720 }
713 721
714 } // namespace content 722 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698