Subversion Repositories SmartDukaan

Rev

Rev 30 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
30 ashish 1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one
3
 * or more contributor license agreements. See the NOTICE file
4
 * distributed with this work for additional information
5
 * regarding copyright ownership. The ASF licenses this file
6
 * to you under the Apache License, Version 2.0 (the
7
 * "License"); you may not use this file except in compliance
8
 * with the License. You may obtain a copy of the License at
9
 *
10
 *   http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied. See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19
 
20
#include "Mutex.h"
21
 
22
#include <assert.h>
23
#include <pthread.h>
24
 
25
using boost::shared_ptr;
26
 
27
namespace apache { namespace thrift { namespace concurrency {
28
 
29
/**
30
 * Implementation of Mutex class using POSIX mutex
31
 *
32
 * @version $Id:$
33
 */
34
class Mutex::impl {
35
 public:
36
  impl(Initializer init) : initialized_(false) {
37
    init(&pthread_mutex_);
38
    initialized_ = true;
39
  }
40
 
41
  ~impl() {
42
    if (initialized_) {
43
      initialized_ = false;
44
      int ret = pthread_mutex_destroy(&pthread_mutex_);
45
      assert(ret == 0);
46
    }
47
  }
48
 
49
  void lock() const { pthread_mutex_lock(&pthread_mutex_); }
50
 
51
  bool trylock() const { return (0 == pthread_mutex_trylock(&pthread_mutex_)); }
52
 
53
  void unlock() const { pthread_mutex_unlock(&pthread_mutex_); }
54
 
55
 private:
56
  mutable pthread_mutex_t pthread_mutex_;
57
  mutable bool initialized_;
58
};
59
 
60
Mutex::Mutex(Initializer init) : impl_(new Mutex::impl(init)) {}
61
 
62
void Mutex::lock() const { impl_->lock(); }
63
 
64
bool Mutex::trylock() const { return impl_->trylock(); }
65
 
66
void Mutex::unlock() const { impl_->unlock(); }
67
 
68
void Mutex::DEFAULT_INITIALIZER(void* arg) {
69
  pthread_mutex_t* pthread_mutex = (pthread_mutex_t*)arg;
70
  int ret = pthread_mutex_init(pthread_mutex, NULL);
71
  assert(ret == 0);
72
}
73
 
74
static void init_with_kind(pthread_mutex_t* mutex, int kind) {
75
  pthread_mutexattr_t mutexattr;
76
  int ret = pthread_mutexattr_init(&mutexattr);
77
  assert(ret == 0);
78
 
79
  // Apparently, this can fail.  Should we really be aborting?
80
  ret = pthread_mutexattr_settype(&mutexattr, kind);
81
  assert(ret == 0);
82
 
83
  ret = pthread_mutex_init(mutex, &mutexattr);
84
  assert(ret == 0);
85
 
86
  ret = pthread_mutexattr_destroy(&mutexattr);
87
  assert(ret == 0);
88
}
89
 
90
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
91
void Mutex::ADAPTIVE_INITIALIZER(void* arg) {
92
  // From mysql source: mysys/my_thr_init.c
93
  // Set mutex type to "fast" a.k.a "adaptive"
94
  //
95
  // In this case the thread may steal the mutex from some other thread
96
  // that is waiting for the same mutex. This will save us some
97
  // context switches but may cause a thread to 'starve forever' while
98
  // waiting for the mutex (not likely if the code within the mutex is
99
  // short).
100
  init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_ADAPTIVE_NP);
101
}
102
#endif
103
 
104
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
105
void Mutex::RECURSIVE_INITIALIZER(void* arg) {
106
  init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_RECURSIVE_NP);
107
}
108
#endif
109
 
110
 
111
/**
112
 * Implementation of ReadWriteMutex class using POSIX rw lock
113
 *
114
 * @version $Id:$
115
 */
116
class ReadWriteMutex::impl {
117
public:
118
  impl() : initialized_(false) {
119
    int ret = pthread_rwlock_init(&rw_lock_, NULL);
120
    assert(ret == 0);
121
    initialized_ = true;
122
  }
123
 
124
  ~impl() {
125
    if(initialized_) {
126
      initialized_ = false;
127
      int ret = pthread_rwlock_destroy(&rw_lock_);
128
      assert(ret == 0);
129
    }
130
  }
131
 
132
  void acquireRead() const { pthread_rwlock_rdlock(&rw_lock_); }
133
 
134
  void acquireWrite() const { pthread_rwlock_wrlock(&rw_lock_); }
135
 
136
  bool attemptRead() const { return pthread_rwlock_tryrdlock(&rw_lock_); }
137
 
138
  bool attemptWrite() const { return pthread_rwlock_trywrlock(&rw_lock_); }
139
 
140
  void release() const { pthread_rwlock_unlock(&rw_lock_); }
141
 
142
private:
143
  mutable pthread_rwlock_t rw_lock_;
144
  mutable bool initialized_;
145
};
146
 
147
ReadWriteMutex::ReadWriteMutex() : impl_(new ReadWriteMutex::impl()) {}
148
 
149
void ReadWriteMutex::acquireRead() const { impl_->acquireRead(); }
150
 
151
void ReadWriteMutex::acquireWrite() const { impl_->acquireWrite(); }
152
 
153
bool ReadWriteMutex::attemptRead() const { return impl_->attemptRead(); }
154
 
155
bool ReadWriteMutex::attemptWrite() const { return impl_->attemptWrite(); }
156
 
157
void ReadWriteMutex::release() const { impl_->release(); }
158
 
159
}}} // apache::thrift::concurrency
160