1cd139dc7SShuo Chen// excerpts from http://code.google.com/p/muduo/
2cd139dc7SShuo Chen//
3cd139dc7SShuo Chen// Use of this source code is governed by a BSD-style license
4cd139dc7SShuo Chen// that can be found in the License file.
5cd139dc7SShuo Chen//
6cd139dc7SShuo Chen// Author: Shuo Chen (giantchen at gmail dot com)
7cd139dc7SShuo Chen
8cd139dc7SShuo Chen#ifndef MUDUO_BASE_MUTEX_H
9cd139dc7SShuo Chen#define MUDUO_BASE_MUTEX_H
10cd139dc7SShuo Chen
115f8e07deSShuo Chen#include "Thread.h"
125f8e07deSShuo Chen
13cd139dc7SShuo Chen#include <boost/noncopyable.hpp>
145f8e07deSShuo Chen#include <assert.h>
15cd139dc7SShuo Chen#include <pthread.h>
16cd139dc7SShuo Chen
17cd139dc7SShuo Chennamespace muduo
18cd139dc7SShuo Chen{
19cd139dc7SShuo Chen
20cd139dc7SShuo Chenclass MutexLock : boost::noncopyable
21cd139dc7SShuo Chen{
22cd139dc7SShuo Chen public:
23cd139dc7SShuo Chen  MutexLock()
245f8e07deSShuo Chen    : holder_(0)
25cd139dc7SShuo Chen  {
26cd139dc7SShuo Chen    pthread_mutex_init(&mutex_, NULL);
27cd139dc7SShuo Chen  }
28cd139dc7SShuo Chen
29cd139dc7SShuo Chen  ~MutexLock()
30cd139dc7SShuo Chen  {
315f8e07deSShuo Chen    assert(holder_ == 0);
32cd139dc7SShuo Chen    pthread_mutex_destroy(&mutex_);
33cd139dc7SShuo Chen  }
34cd139dc7SShuo Chen
355f8e07deSShuo Chen  bool isLockedByThisThread()
365f8e07deSShuo Chen  {
375f8e07deSShuo Chen    return holder_ == CurrentThread::tid();
385f8e07deSShuo Chen  }
395f8e07deSShuo Chen
405f8e07deSShuo Chen  void assertLocked()
415f8e07deSShuo Chen  {
425f8e07deSShuo Chen    assert(isLockedByThisThread());
435f8e07deSShuo Chen  }
445f8e07deSShuo Chen
455f8e07deSShuo Chen  // internal usage
465f8e07deSShuo Chen
47cd139dc7SShuo Chen  void lock()
48cd139dc7SShuo Chen  {
49cd139dc7SShuo Chen    pthread_mutex_lock(&mutex_);
505f8e07deSShuo Chen    holder_ = CurrentThread::tid();
51cd139dc7SShuo Chen  }
52cd139dc7SShuo Chen
53cd139dc7SShuo Chen  void unlock()
54cd139dc7SShuo Chen  {
555f8e07deSShuo Chen    holder_ = 0;
56cd139dc7SShuo Chen    pthread_mutex_unlock(&mutex_);
57cd139dc7SShuo Chen  }
58cd139dc7SShuo Chen
59cd139dc7SShuo Chen  pthread_mutex_t* getPthreadMutex() /* non-const */
60cd139dc7SShuo Chen  {
61cd139dc7SShuo Chen    return &mutex_;
62cd139dc7SShuo Chen  }
63cd139dc7SShuo Chen
64cd139dc7SShuo Chen private:
65cd139dc7SShuo Chen
66cd139dc7SShuo Chen  pthread_mutex_t mutex_;
675f8e07deSShuo Chen  pid_t holder_;
68cd139dc7SShuo Chen};
69cd139dc7SShuo Chen
70cd139dc7SShuo Chenclass MutexLockGuard : boost::noncopyable
71cd139dc7SShuo Chen{
72cd139dc7SShuo Chen public:
73cd139dc7SShuo Chen  explicit MutexLockGuard(MutexLock& mutex) : mutex_(mutex)
74cd139dc7SShuo Chen  {
75cd139dc7SShuo Chen    mutex_.lock();
76cd139dc7SShuo Chen  }
77cd139dc7SShuo Chen
78cd139dc7SShuo Chen  ~MutexLockGuard()
79cd139dc7SShuo Chen  {
80cd139dc7SShuo Chen    mutex_.unlock();
81cd139dc7SShuo Chen  }
82cd139dc7SShuo Chen
83cd139dc7SShuo Chen private:
84cd139dc7SShuo Chen
85cd139dc7SShuo Chen  MutexLock& mutex_;
86cd139dc7SShuo Chen};
87cd139dc7SShuo Chen
88cd139dc7SShuo Chen}
89cd139dc7SShuo Chen
90cd139dc7SShuo Chen// Prevent misuse like:
91cd139dc7SShuo Chen// MutexLockGuard(mutex_);
92cd139dc7SShuo Chen// A tempory object doesn't hold the lock for long!
93cd139dc7SShuo Chen#define MutexLockGuard(x) error "Missing guard object name"
94cd139dc7SShuo Chen
95cd139dc7SShuo Chen#endif  // MUDUO_BASE_MUTEX_H
96