// 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.

#ifndef PPAPI_UTILITY_THREAD_SAFE_THREAD_TRAITS_H_
#define PPAPI_UTILITY_THREAD_SAFE_THREAD_TRAITS_H_

#include "ppapi/cpp/logging.h"
#include "ppapi/cpp/module.h"
#include "ppapi/utility/threading/lock.h"

/// @file
/// Defines the traits structures for thread-safety of a completion callback
/// factory. We provide thread-safe and non-thread-safe version. The thread-safe
/// version is always correct (if you follow the thread usage rules of the
/// callback factory), but if you know your object will only be used on one
/// thread, you can uses the non-thread-safe version.
///
/// The traits defines three nested classes to perform reference counting,
/// locks, and scoped locking.

namespace pp {

/// The thread-safe version of thread traits. Using this class as the "traits"
/// template argument to a completion callback factory will make it "somewhat
/// thread-friendly." It will allow you to create completion callbacks from
/// background threads and post them to another thread to run.
///
/// Care still must be taken to ensure that the completion callbacks are
/// executed on the same thread that the factory is destroyed on to avoid a
/// race on destruction.
///
/// Implementation note: this uses a lock instead of atomic add instructions.
/// The number of platforms we need to support right now makes atomic
/// operations unwieldy for this case that we don't actually use that often.
/// As a further optimization, we can add support for this later.
class ThreadSafeThreadTraits {
 public:
  class RefCount {
   public:
    /// Default constructor. In debug mode, this checks that the object is being
    /// created on the main thread.
    RefCount() : ref_(0) {
    }

    /// AddRef() increments the reference counter.
    ///
    /// @return An int32_t with the incremented reference counter.
    int32_t AddRef() {
      AutoLock lock(lock_);
      return ++ref_;
    }

    /// Release() decrements the reference counter.
    ///
    /// @return An int32_t with the decremeneted reference counter.
    int32_t Release() {
      AutoLock lock(lock_);
      PP_DCHECK(ref_ > 0);
      return --ref_;
    }

   private:
    Lock lock_;
    int32_t ref_;
  };

  typedef pp::Lock Lock;
  typedef pp::AutoLock AutoLock;
};

/// The non-thread-safe version of thread traits. Using this class as the
/// "traits" template argument to a completion callback factory will make it
/// not thread-safe but with potential extra performance.
class NonThreadSafeThreadTraits {
 public:
  /// A simple reference counter that is not thread-safe.
  ///
  /// <strong>Note:</strong> in Debug mode, it checks that it is either called
  /// on the main thread, or always called on another thread.
  class RefCount {
   public:
    /// Default constructor. In debug mode, this checks that the object is being
    /// created on the main thread.
    RefCount() : ref_(0) {
#ifndef NDEBUG
      is_main_thread_ = Module::Get()->core()->IsMainThread();
#endif
    }

    /// Destructor.
    ~RefCount() {
      PP_DCHECK(is_main_thread_ == Module::Get()->core()->IsMainThread());
    }

    /// AddRef() increments the reference counter.
    ///
    /// @return An int32_t with the incremented reference counter.
    int32_t AddRef() {
      PP_DCHECK(is_main_thread_ == Module::Get()->core()->IsMainThread());
      return ++ref_;
    }

    /// Release() decrements the reference counter.
    ///
    /// @return An int32_t with the decremeneted reference counter.
    int32_t Release() {
      PP_DCHECK(is_main_thread_ == Module::Get()->core()->IsMainThread());
      return --ref_;
    }

   private:
    int32_t ref_;
#ifndef NDEBUG
    bool is_main_thread_;
#endif
  };

  /// A simple object that acts like a lock but does nothing.
  ///
  /// <strong>Note:</strong> in Debug mode, it checks that it is either
  /// called on the main thread, or always called on another thread. It also
  /// asserts that the caller does not recursively lock.
  class Lock {
   public:
    Lock() {
#ifndef NDEBUG
      is_main_thread_ = Module::Get()->core()->IsMainThread();
      lock_held_ = false;
#endif
    }

    ~Lock() {
      PP_DCHECK(is_main_thread_ == Module::Get()->core()->IsMainThread());
    }

    /// Acquires the fake "lock". This does nothing except perform checks in
    /// debug mode.
    void Acquire() {
#ifndef NDEBUG
      PP_DCHECK(!lock_held_);
      lock_held_ = true;
#endif
    }

    /// Releases the fake "lock". This does nothing except perform checks in
    /// debug mode.
    void Release() {
#ifndef NDEBUG
      PP_DCHECK(lock_held_);
      lock_held_ = false;
#endif
    }

   private:
#ifndef NDEBUG
    bool is_main_thread_;
    bool lock_held_;
#endif
  };

  class AutoLock {
   public:
    explicit AutoLock(Lock& lock) : lock_(lock) {
      lock_.Acquire();
    }
    ~AutoLock() {
      lock_.Release();
    }

   private:
    Lock& lock_;
  };
};

}  // namespace pp

#endif  // PPAPI_UTILITY_THREAD_SAFE_THREAD_TRAITS_H_
