Index: base/threading/thread_task_runner_handle.cc |
diff --git a/base/threading/thread_task_runner_handle.cc b/base/threading/thread_task_runner_handle.cc |
index 190e18ffc68557c64f81f5b766a952c37d3c34a7..ab2243a646116153b48464365b904b5dab7879b5 100644 |
--- a/base/threading/thread_task_runner_handle.cc |
+++ b/base/threading/thread_task_runner_handle.cc |
@@ -8,6 +8,7 @@ |
#include "base/lazy_instance.h" |
#include "base/logging.h" |
+#include "base/memory/ptr_util.h" |
#include "base/threading/sequenced_task_runner_handle.h" |
#include "base/threading/thread_local.h" |
@@ -15,14 +16,16 @@ namespace base { |
namespace { |
-base::LazyInstance<base::ThreadLocalPointer<ThreadTaskRunnerHandle>>::Leaky |
- lazy_tls_ptr = LAZY_INSTANCE_INITIALIZER; |
+base::LazyInstance<base::ThreadLocalPointer< |
+ const ThreadTaskRunnerHandle::NestedForTesting>>::Leaky lazy_tls_ptr = |
+ LAZY_INSTANCE_INITIALIZER; |
} // namespace |
// static |
scoped_refptr<SingleThreadTaskRunner> ThreadTaskRunnerHandle::Get() { |
- ThreadTaskRunnerHandle* current = lazy_tls_ptr.Pointer()->Get(); |
+ const ThreadTaskRunnerHandle::NestedForTesting* current = |
+ lazy_tls_ptr.Pointer()->Get(); |
DCHECK(current); |
return current->task_runner_; |
} |
@@ -33,19 +36,31 @@ bool ThreadTaskRunnerHandle::IsSet() { |
} |
ThreadTaskRunnerHandle::ThreadTaskRunnerHandle( |
- scoped_refptr<SingleThreadTaskRunner> task_runner) |
- : task_runner_(std::move(task_runner)) { |
- DCHECK(task_runner_->BelongsToCurrentThread()); |
+ scoped_refptr<SingleThreadTaskRunner> task_runner) { |
// No SequencedTaskRunnerHandle (which includes ThreadTaskRunnerHandles) |
- // should already be set for this thread. |
+ // should already be set for this thread. Nesting isn't allowed outside of |
+ // tests (ref. NestedForTesting). |
DCHECK(!SequencedTaskRunnerHandle::IsSet()); |
+ |
+ // After checking that nesting wasn't used outside of tests above, use |
+ // NestedForTesting for the assignement logic. |
+ handle_ = MakeUnique<NestedForTesting>(std::move(task_runner)); |
+} |
+ |
+ThreadTaskRunnerHandle::~ThreadTaskRunnerHandle() = default; |
+ |
+ThreadTaskRunnerHandle::NestedForTesting::NestedForTesting( |
+ scoped_refptr<SingleThreadTaskRunner> task_runner) |
+ : task_runner_(std::move(task_runner)), |
+ previous_handle_(lazy_tls_ptr.Pointer()->Get()) { |
+ DCHECK(task_runner_->BelongsToCurrentThread()); |
lazy_tls_ptr.Pointer()->Set(this); |
} |
-ThreadTaskRunnerHandle::~ThreadTaskRunnerHandle() { |
+ThreadTaskRunnerHandle::NestedForTesting::~NestedForTesting() { |
DCHECK(task_runner_->BelongsToCurrentThread()); |
DCHECK_EQ(lazy_tls_ptr.Pointer()->Get(), this); |
- lazy_tls_ptr.Pointer()->Set(nullptr); |
+ lazy_tls_ptr.Pointer()->Set(previous_handle_); |
} |
} // namespace base |