| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "base/sequence_checker_impl.h" | 
 |  | 
 | #include "base/logging.h" | 
 | #include "base/memory/ptr_util.h" | 
 | #include "base/sequence_token.h" | 
 | #include "base/threading/thread_checker_impl.h" | 
 |  | 
 | namespace base { | 
 |  | 
 | class SequenceCheckerImpl::Core { | 
 |  public: | 
 |   Core() : sequence_token_(SequenceToken::GetForCurrentThread()) {} | 
 |  | 
 |   ~Core() = default; | 
 |  | 
 |   bool CalledOnValidSequence() const { | 
 |     if (sequence_token_.IsValid()) | 
 |       return sequence_token_ == SequenceToken::GetForCurrentThread(); | 
 |  | 
 |     // SequenceChecker behaves as a ThreadChecker when it is not bound to a | 
 |     // valid sequence token. | 
 |     return thread_checker_.CalledOnValidThread(); | 
 |   } | 
 |  | 
 |  private: | 
 |   SequenceToken sequence_token_; | 
 |  | 
 |   // Used when |sequence_token_| is invalid. | 
 |   ThreadCheckerImpl thread_checker_; | 
 | }; | 
 |  | 
 | SequenceCheckerImpl::SequenceCheckerImpl() : core_(std::make_unique<Core>()) {} | 
 | SequenceCheckerImpl::~SequenceCheckerImpl() = default; | 
 |  | 
 | bool SequenceCheckerImpl::CalledOnValidSequence() const { | 
 |   AutoLock auto_lock(lock_); | 
 |   if (!core_) | 
 |     core_ = std::make_unique<Core>(); | 
 |   return core_->CalledOnValidSequence(); | 
 | } | 
 |  | 
 | void SequenceCheckerImpl::DetachFromSequence() { | 
 |   AutoLock auto_lock(lock_); | 
 |   core_.reset(); | 
 | } | 
 |  | 
 | }  // namespace base |