// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef GOOGLE_PROTOBUF_STUBS_MUTEX_H_
#define GOOGLE_PROTOBUF_STUBS_MUTEX_H_

#include <mutex>

#ifdef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP

#include <windows.h>

// GetMessage conflicts with GeneratedMessageReflection::GetMessage().
#ifdef GetMessage
#undef GetMessage
#endif

#endif

#include <google/protobuf/stubs/macros.h>

// Define thread-safety annotations for use below, if we are building with
// Clang.
#if defined(__clang__) && !defined(SWIG)
#define GOOGLE_PROTOBUF_ACQUIRE(...) \
  __attribute__((acquire_capability(__VA_ARGS__)))
#define GOOGLE_PROTOBUF_RELEASE(...) \
  __attribute__((release_capability(__VA_ARGS__)))
#define GOOGLE_PROTOBUF_SCOPED_CAPABILITY __attribute__((scoped_lockable))
#define GOOGLE_PROTOBUF_CAPABILITY(x) __attribute__((capability(x)))
#else
#define GOOGLE_PROTOBUF_ACQUIRE(...)
#define GOOGLE_PROTOBUF_RELEASE(...)
#define GOOGLE_PROTOBUF_SCOPED_CAPABILITY
#define GOOGLE_PROTOBUF_CAPABILITY(x)
#endif

#include <google/protobuf/port_def.inc>

// ===================================================================
// emulates google3/base/mutex.h
namespace google {
namespace protobuf {
namespace internal {

#define GOOGLE_PROTOBUF_LINKER_INITIALIZED

#ifdef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP

// This class is a lightweight replacement for std::mutex on Windows platforms.
// std::mutex does not work on Windows XP SP2 with the latest VC++ libraries,
// because it utilizes the Concurrency Runtime that is only supported on Windows
// XP SP3 and above.
class PROTOBUF_EXPORT CriticalSectionLock {
 public:
  CriticalSectionLock() { InitializeCriticalSection(&critical_section_); }
  ~CriticalSectionLock() { DeleteCriticalSection(&critical_section_); }
  void lock() { EnterCriticalSection(&critical_section_); }
  void unlock() { LeaveCriticalSection(&critical_section_); }

 private:
  CRITICAL_SECTION critical_section_;

  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CriticalSectionLock);
};

#endif

// In MSVC std::mutex does not have a constexpr constructor.
// This wrapper makes the constructor constexpr.
template <typename T>
class CallOnceInitializedMutex {
 public:
  constexpr CallOnceInitializedMutex() : flag_{}, buf_{} {}
  ~CallOnceInitializedMutex() { get().~T(); }

  void lock() { get().lock(); }
  void unlock() { get().unlock(); }

 private:
  T& get() {
    std::call_once(flag_, [&] { ::new (static_cast<void*>(&buf_)) T(); });
    return reinterpret_cast<T&>(buf_);
  }

  std::once_flag flag_;
  alignas(T) char buf_[sizeof(T)];
};

// Mutex is a natural type to wrap. As both google and other organization have
// specialized mutexes. gRPC also provides an injection mechanism for custom
// mutexes.
class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex {
 public:
#if defined(__QNX__)
  constexpr WrappedMutex() = default;
#else
  constexpr WrappedMutex() {}
#endif
  void Lock() GOOGLE_PROTOBUF_ACQUIRE() { mu_.lock(); }
  void Unlock() GOOGLE_PROTOBUF_RELEASE() { mu_.unlock(); }
  // Crash if this Mutex is not held exclusively by this thread.
  // May fail to crash when it should; will never crash when it should not.
  void AssertHeld() const {}

 private:
#if defined(GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP)
  CallOnceInitializedMutex<CriticalSectionLock> mu_{};
#elif defined(_WIN32)
  CallOnceInitializedMutex<std::mutex> mu_{};
#else
  std::mutex mu_{};
#endif
};

using Mutex = WrappedMutex;

// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
class GOOGLE_PROTOBUF_SCOPED_CAPABILITY PROTOBUF_EXPORT MutexLock {
 public:
  explicit MutexLock(Mutex* mu) GOOGLE_PROTOBUF_ACQUIRE(mu) : mu_(mu) {
    this->mu_->Lock();
  }
  ~MutexLock() GOOGLE_PROTOBUF_RELEASE() { this->mu_->Unlock(); }

 private:
  Mutex *const mu_;
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLock);
};

// TODO(kenton):  Implement these?  Hard to implement portably.
typedef MutexLock ReaderMutexLock;
typedef MutexLock WriterMutexLock;

// MutexLockMaybe is like MutexLock, but is a no-op when mu is nullptr.
class PROTOBUF_EXPORT MutexLockMaybe {
 public:
  explicit MutexLockMaybe(Mutex *mu) :
    mu_(mu) { if (this->mu_ != nullptr) { this->mu_->Lock(); } }
  ~MutexLockMaybe() { if (this->mu_ != nullptr) { this->mu_->Unlock(); } }
 private:
  Mutex *const mu_;
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe);
};

#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
template<typename T>
class ThreadLocalStorage {
 public:
  ThreadLocalStorage() {
    pthread_key_create(&key_, &ThreadLocalStorage::Delete);
  }
  ~ThreadLocalStorage() {
    pthread_key_delete(key_);
  }
  T* Get() {
    T* result = static_cast<T*>(pthread_getspecific(key_));
    if (result == nullptr) {
      result = new T();
      pthread_setspecific(key_, result);
    }
    return result;
  }
 private:
  static void Delete(void* value) {
    delete static_cast<T*>(value);
  }
  pthread_key_t key_;

  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadLocalStorage);
};
#endif

}  // namespace internal

// We made these internal so that they would show up as such in the docs,
// but we don't want to stick "internal::" in front of them everywhere.
using internal::Mutex;
using internal::MutexLock;
using internal::ReaderMutexLock;
using internal::WriterMutexLock;
using internal::MutexLockMaybe;

}  // namespace protobuf
}  // namespace google

#undef GOOGLE_PROTOBUF_ACQUIRE
#undef GOOGLE_PROTOBUF_RELEASE

#include <google/protobuf/port_undef.inc>

#endif  // GOOGLE_PROTOBUF_STUBS_MUTEX_H_
