Index: base/task_scheduler/scheduler_worker.cc |
diff --git a/base/task_scheduler/scheduler_worker.cc b/base/task_scheduler/scheduler_worker.cc |
index 1d6cfee84775207f3338e3b21316d4e8ec0794ad..a7791c8d75d7e6a7afa4fcf7089e342fadeda0bf 100644 |
--- a/base/task_scheduler/scheduler_worker.cc |
+++ b/base/task_scheduler/scheduler_worker.cc |
@@ -108,6 +108,12 @@ class SchedulerWorker::Thread : public PlatformThread::Delegate { |
"This thread was detached and woken up at the same time."; |
} |
+ void TakeOwnershipOfSchedulerWorker(std::unique_ptr<SchedulerWorker> worker) { |
+ // If this check fails, we'll crash on a random thread instead. |
+ CHECK(outer_ == worker.get()); |
fdoray
2017/02/08 17:59:01
DCHECK_EQ
robliao
2017/02/10 00:04:04
This CHECK is intentional. I'd prefer to crash rig
|
+ owning_worker_ = std::move(worker); |
fdoray
2017/02/08 17:59:01
WakeUp();
Otherwise, the thread may sleep forever
robliao
2017/02/11 02:13:34
Done.
|
+ } |
+ |
void Join() { PlatformThread::Join(thread_handle_); } |
void WakeUp() { wake_up_event_.Signal(); } |
@@ -184,6 +190,9 @@ class SchedulerWorker::Thread : public PlatformThread::Delegate { |
// |outer_->priority_hint_|. |
ThreadPriority current_thread_priority_; |
+ // Holds the owning worker for destruction at the end of detachment. |
+ std::unique_ptr<SchedulerWorker> owning_worker_; |
+ |
DISALLOW_COPY_AND_ASSIGN(Thread); |
}; |
@@ -215,6 +224,18 @@ SchedulerWorker::~SchedulerWorker() { |
DCHECK(!thread_); |
} |
+// static |
+void SchedulerWorker::DestroyAfterDetachment( |
+ std::unique_ptr<SchedulerWorker> worker) { |
+ DCHECK(worker); |
+ AutoSchedulerLock auto_lock(worker->thread_lock_); |
+ if (worker->thread_) { |
+ SchedulerWorker* raw_worker_pointer = worker.get(); |
+ raw_worker_pointer->thread_->TakeOwnershipOfSchedulerWorker( |
+ std::move(worker)); |
+ } |
+} |
+ |
void SchedulerWorker::WakeUp() { |
AutoSchedulerLock auto_lock(thread_lock_); |