// Copyright (c) 2006- Facebook
// Distributed under the Thrift Software License
//
// See accompanying file LICENSE or visit the Thrift site at:
// http://developers.facebook.com/thrift/

#include "Mutex.h"

#include <assert.h>
#include <pthread.h>

using boost::shared_ptr;

namespace facebook { namespace thrift { namespace concurrency {

/**
 * Implementation of Mutex class using POSIX mutex
 *
 * @author marc
 * @version $Id:$
 */
class Mutex::impl {
 public:
  impl(Initializer init) : initialized_(false) {
    init(&pthread_mutex_);
    initialized_ = true;
  }

  ~impl() {
    if (initialized_) {
      initialized_ = false;
      int ret = pthread_mutex_destroy(&pthread_mutex_);
      assert(ret == 0);
    }
  }

  void lock() const { pthread_mutex_lock(&pthread_mutex_); }

  bool trylock() const { return (0 == pthread_mutex_trylock(&pthread_mutex_)); }

  void unlock() const { pthread_mutex_unlock(&pthread_mutex_); }

 private:
  mutable pthread_mutex_t pthread_mutex_;
  mutable bool initialized_;
};

Mutex::Mutex(Initializer init) : impl_(new Mutex::impl(init)) {}

void Mutex::lock() const { impl_->lock(); }

bool Mutex::trylock() const { return impl_->trylock(); }

void Mutex::unlock() const { impl_->unlock(); }

void Mutex::DEFAULT_INITIALIZER(void* arg) {
  pthread_mutex_t* pthread_mutex = (pthread_mutex_t*)arg;
  int ret = pthread_mutex_init(pthread_mutex, NULL);
  assert(ret == 0);
}

static void init_with_kind(pthread_mutex_t* mutex, int kind) {
  pthread_mutexattr_t mutexattr;
  int ret = pthread_mutexattr_init(&mutexattr);
  assert(ret == 0);

  // Apparently, this can fail.  Should we really be aborting?
  ret = pthread_mutexattr_settype(&mutexattr, kind);
  assert(ret == 0);

  ret = pthread_mutex_init(mutex, &mutexattr);
  assert(ret == 0);

  ret = pthread_mutexattr_destroy(&mutexattr);
  assert(ret == 0);
}

#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
void Mutex::ADAPTIVE_INITIALIZER(void* arg) {
  // From mysql source: mysys/my_thr_init.c
  // Set mutex type to "fast" a.k.a "adaptive"
  //
  // In this case the thread may steal the mutex from some other thread
  // that is waiting for the same mutex. This will save us some
  // context switches but may cause a thread to 'starve forever' while
  // waiting for the mutex (not likely if the code within the mutex is
  // short).
  init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_ADAPTIVE_NP);
}
#endif

#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
void Mutex::RECURSIVE_INITIALIZER(void* arg) {
  init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_RECURSIVE_NP);
}
#endif


/**
 * Implementation of ReadWriteMutex class using POSIX rw lock
 *
 * @author boz
 * @version $Id:$
 */
class ReadWriteMutex::impl {
public:
  impl() : initialized_(false) {
    int ret = pthread_rwlock_init(&rw_lock_, NULL);
    assert(ret == 0);
    initialized_ = true;
  }

  ~impl() {
    if(initialized_) {
      initialized_ = false;
      int ret = pthread_rwlock_destroy(&rw_lock_);
      assert(ret == 0);
    }
  }

  void acquireRead() const { pthread_rwlock_rdlock(&rw_lock_); }

  void acquireWrite() const { pthread_rwlock_wrlock(&rw_lock_); }

  bool attemptRead() const { return pthread_rwlock_tryrdlock(&rw_lock_); }

  bool attemptWrite() const { return pthread_rwlock_trywrlock(&rw_lock_); }

  void release() const { pthread_rwlock_unlock(&rw_lock_); }

private:
  mutable pthread_rwlock_t rw_lock_;
  mutable bool initialized_;
};

ReadWriteMutex::ReadWriteMutex() : impl_(new ReadWriteMutex::impl()) {}

void ReadWriteMutex::acquireRead() const { impl_->acquireRead(); }

void ReadWriteMutex::acquireWrite() const { impl_->acquireWrite(); }

bool ReadWriteMutex::attemptRead() const { return impl_->attemptRead(); }

bool ReadWriteMutex::attemptWrite() const { return impl_->attemptWrite(); }

void ReadWriteMutex::release() const { impl_->release(); }

}}} // facebook::thrift::concurrency

