diff --git a/boost/thread/pthread/shared_mutex.hpp b/boost/thread/pthread/shared_mutex.hpp
index 458d6c8..2a7b983 100644
a
|
b
|
|
24 | 24 | |
25 | 25 | #include <boost/config/abi_prefix.hpp> |
26 | 26 | |
| 27 | #if defined BOOST_THREAD_USE_PTHREAD_RWLOCKS |
| 28 | #include <stdexcept> |
| 29 | #include <pthread.h> |
| 30 | #endif |
| 31 | |
27 | 32 | namespace boost |
28 | 33 | { |
29 | 34 | class shared_mutex |
… |
… |
namespace boost
|
162 | 167 | boost::condition_variable exclusive_cond; |
163 | 168 | boost::condition_variable upgrade_cond; |
164 | 169 | |
| 170 | #if defined BOOST_THREAD_PTHREAD_USE_RWLOCKS |
| 171 | pthread_rwlock_t rw_lock; |
| 172 | #endif |
| 173 | |
165 | 174 | void release_waiters() |
166 | 175 | { |
167 | 176 | exclusive_cond.notify_one(); |
… |
… |
namespace boost
|
172 | 181 | |
173 | 182 | BOOST_THREAD_NO_COPYABLE(shared_mutex) |
174 | 183 | |
| 184 | #if defined BOOST_THREAD_PTHREAD_USE_RWLOCKS |
| 185 | BOOST_THREAD_NO_COPYABLE(rw_lock) |
| 186 | #endif |
| 187 | |
175 | 188 | shared_mutex() |
176 | 189 | { |
| 190 | #if defined BOOST_THREAD_PTHREAD_USE_RWLOCKS |
| 191 | int ret = 0; |
| 192 | #if defined(__linux__) |
| 193 | // Linux rwlocks are by default writer-starving |
| 194 | pthread_rwlockattr_t attr; |
| 195 | ret = pthread_rwlockattr_init(&attr); |
| 196 | if (ret) |
| 197 | { |
| 198 | throw std::runtime_error("pthread_rwlockattr_init faild"); |
| 199 | } |
| 200 | ret = pthread_rwlockattr_setkind_np(&attr, |
| 201 | PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); |
| 202 | if (ret) |
| 203 | { |
| 204 | throw std::runtime_error("pthread_rwlockattr_setkind_np failed"); |
| 205 | } |
| 206 | ret = pthread_rwlock_init(&lock_, &attr); |
| 207 | if (ret) |
| 208 | { |
| 209 | throw std::runtime_error("pthread_rwlock_init failed"); |
| 210 | } |
| 211 | ret = pthread_rwlockattr_destroy(&attr); |
| 212 | if (ret) |
| 213 | { |
| 214 | throw std::runtime_error("pthread_rwlockattr_destroy failed"); |
| 215 | } |
| 216 | #else |
| 217 | ret = pthread_rwlock_init(&lock_, NULL); |
| 218 | if (ret) |
| 219 | { |
| 220 | throw std::runtime_error("pthread_rwlock_init failed"); |
| 221 | } |
| 222 | #endif |
| 223 | #endif |
177 | 224 | } |
178 | 225 | |
179 | 226 | ~shared_mutex() |
180 | 227 | { |
| 228 | #if defined BOOST_THREAD_PTHREAD_USE_RWLOCKS |
| 229 | int ret = pthread_rwlock_destroy(&lock_); |
| 230 | if (ret) |
| 231 | { |
| 232 | throw std::runtime_error("pthread_rwlock_destroy failed"); |
| 233 | } |
| 234 | #endif |
181 | 235 | } |
182 | 236 | |
183 | 237 | void lock_shared() |
184 | 238 | { |
| 239 | #if defined BOOST_THREAD_USE_PTHREAD_RWLOCKS |
| 240 | int ret = pthread_rwlock_rdlock(&rw_lock); |
| 241 | if (ret) |
| 242 | { |
| 243 | throw std::runtime_error("pthread_rwlock_rdlock failed"); |
| 244 | } |
| 245 | #else |
185 | 246 | #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS |
186 | 247 | boost::this_thread::disable_interruption do_not_disturb; |
187 | 248 | #endif |
… |
… |
namespace boost
|
191 | 252 | shared_cond.wait(lk); |
192 | 253 | } |
193 | 254 | state.lock_shared(); |
| 255 | #endif |
194 | 256 | } |
195 | 257 | |
196 | 258 | bool try_lock_shared() |
197 | 259 | { |
| 260 | #if definet BOOST_THREAD_USE_PTHREAD_RWLOCKS |
| 261 | int ret = pthread_rwlock_tryrdlock(&rw_lock); |
| 262 | if (!ret) |
| 263 | { |
| 264 | return true; |
| 265 | } |
| 266 | else if (ret == EBUSY) |
| 267 | { |
| 268 | return false; |
| 269 | } |
| 270 | throw std::runtime_error("pthread_rwlock_tryrdlock failed"); |
| 271 | #else |
198 | 272 | boost::unique_lock<boost::mutex> lk(state_change); |
199 | 273 | |
200 | 274 | if(!state.can_lock_shared()) |
… |
… |
namespace boost
|
203 | 277 | } |
204 | 278 | state.lock_shared(); |
205 | 279 | return true; |
| 280 | #endif |
206 | 281 | } |
207 | 282 | |
208 | 283 | #if defined BOOST_THREAD_USES_DATETIME |
… |
… |
namespace boost
|
258 | 333 | #endif |
259 | 334 | void unlock_shared() |
260 | 335 | { |
| 336 | #if defined BOOST_THREAD_USE_PTHREAD_RWLOCKS |
| 337 | int ret = pthread_rwlock_unlock(&rw_lock); |
| 338 | if (ret) |
| 339 | { |
| 340 | throw std::runtime_error("pthread_rwlock_unlock failed"); |
| 341 | } |
| 342 | #else |
261 | 343 | boost::unique_lock<boost::mutex> lk(state_change); |
262 | 344 | state.assert_lock_shared(); |
263 | 345 | state.unlock_shared(); |
… |
… |
namespace boost
|
279 | 361 | } |
280 | 362 | release_waiters(); |
281 | 363 | } |
| 364 | #endif |
282 | 365 | } |
283 | 366 | |
284 | 367 | void lock() |
285 | 368 | { |
| 369 | #if defined BOOST_THREAD_USE_PTHREAD_RWLOCKS |
| 370 | int ret = pthread_rwlock_wrlock(&rw_lock); |
| 371 | if (ret) |
| 372 | { |
| 373 | throw std::runtime_error("pthread_rwlock_wrlock failed"); |
| 374 | } |
| 375 | #else |
286 | 376 | #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS |
287 | 377 | boost::this_thread::disable_interruption do_not_disturb; |
288 | 378 | #endif |
… |
… |
namespace boost
|
294 | 384 | exclusive_cond.wait(lk); |
295 | 385 | } |
296 | 386 | state.exclusive=true; |
| 387 | #endif |
297 | 388 | } |
298 | 389 | |
299 | 390 | #if defined BOOST_THREAD_USES_DATETIME |
… |
… |
namespace boost
|
363 | 454 | |
364 | 455 | bool try_lock() |
365 | 456 | { |
| 457 | #if defined BOOST_THREAD_USE_PTHREAD_RWLOCKS |
| 458 | int ret = pthread_rwlock_trywrlock(&rw_lock); |
| 459 | if (!ret) |
| 460 | { |
| 461 | return true; |
| 462 | } |
| 463 | else if (ret == EBUSY) |
| 464 | { |
| 465 | return false; |
| 466 | } |
| 467 | throw std::runtime_error("pthread_rwlock_trywrlock failed"); |
| 468 | #else |
366 | 469 | boost::unique_lock<boost::mutex> lk(state_change); |
367 | 470 | |
368 | 471 | if(state.shared_count || state.exclusive) |
… |
… |
namespace boost
|
374 | 477 | state.exclusive=true; |
375 | 478 | return true; |
376 | 479 | } |
377 | | |
| 480 | #endif |
378 | 481 | } |
379 | 482 | |
380 | 483 | void unlock() |
381 | 484 | { |
| 485 | #if defined BOOST_THREAD_USE_PTHREAD_RWLOCKS |
| 486 | int ret = pthread_rwlock_unlock(&rw_lock); |
| 487 | if (ret) |
| 488 | { |
| 489 | throw std::runtime_error("pthread_rwlock_unlock failed"); |
| 490 | } |
| 491 | #else |
382 | 492 | boost::unique_lock<boost::mutex> lk(state_change); |
383 | 493 | state.assert_locked(); |
384 | 494 | state.exclusive=false; |
385 | 495 | state.exclusive_waiting_blocked=false; |
386 | 496 | state.assert_free(); |
387 | 497 | release_waiters(); |
| 498 | #endif |
388 | 499 | } |
389 | 500 | |
390 | 501 | void lock_upgrade() |