// 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 {
#if defined(STARBOARD)
  starboard::ScopedSpinLock lock(&members_lock_);
#else   // defined(STARBOARD)
  AutoLock auto_lock(lock_);
#endif  // defined(STARBOARD)
  if (!core_)
    core_ = std::make_unique<Core>();
  return core_->CalledOnValidSequence();
}

void SequenceCheckerImpl::DetachFromSequence() {
#if defined(STARBOARD)
  starboard::ScopedSpinLock lock(&members_lock_);
#else   // defined(STARBOARD)
  AutoLock auto_lock(lock_);
#endif  // defined(STARBOARD)
  core_.reset();
}

}  // namespace base
