diff --git a/boost/thread/pthread/shared_mutex.hpp b/boost/thread/pthread/shared_mutex.hpp
index 458d6c8..9d527db 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
|
| 174 | 183 | |
| 175 | 184 | shared_mutex() |
| 176 | 185 | { |
| | 186 | #if defined BOOST_THREAD_PTHREAD_USE_RWLOCKS |
| | 187 | int ret = 0; |
| | 188 | #if defined(__linux__) |
| | 189 | // Linux rwlocks are by default writer-starving |
| | 190 | pthread_rwlockattr_t attr; |
| | 191 | ret = pthread_rwlockattr_init(&attr); |
| | 192 | if (ret) |
| | 193 | { |
| | 194 | throw std::runtime_error("pthread_rwlockattr_init faild"); |
| | 195 | } |
| | 196 | ret = pthread_rwlockattr_setkind_np(&attr, |
| | 197 | PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); |
| | 198 | if (ret) |
| | 199 | { |
| | 200 | throw std::runtime_error("pthread_rwlockattr_setkind_np failed"); |
| | 201 | } |
| | 202 | ret = pthread_rwlock_init(&lock_, &attr); |
| | 203 | if (ret) |
| | 204 | { |
| | 205 | throw std::runtime_error("pthread_rwlock_init failed"); |
| | 206 | } |
| | 207 | ret = pthread_rwlockattr_destroy(&attr); |
| | 208 | if (ret) |
| | 209 | { |
| | 210 | throw std::runtime_error("pthread_rwlockattr_destroy failed"); |
| | 211 | } |
| | 212 | #else |
| | 213 | ret = pthread_rwlock_init(&lock_, NULL); |
| | 214 | if (ret) |
| | 215 | { |
| | 216 | throw std::runtime_error("pthread_rwlock_init failed"); |
| | 217 | } |
| | 218 | #endif |
| | 219 | #endif |
| 177 | 220 | } |
| 178 | 221 | |
| 179 | 222 | ~shared_mutex() |
| 180 | 223 | { |
| | 224 | #if defined BOOST_THREAD_PTHREAD_USE_RWLOCKS |
| | 225 | int ret = pthread_rwlock_destroy(&lock_); |
| | 226 | if (ret) |
| | 227 | { |
| | 228 | throw std::runtime_error("pthread_rwlock_destroy failed"); |
| | 229 | } |
| | 230 | #endif |
| 181 | 231 | } |
| 182 | 232 | |
| 183 | 233 | void lock_shared() |
| 184 | 234 | { |
| | 235 | #if defined BOOST_THREAD_USE_PTHREAD_RWLOCKS |
| | 236 | int ret = pthread_rwlock_rdlock(&rw_lock); |
| | 237 | if (ret) |
| | 238 | { |
| | 239 | throw std::runtime_error("pthread_rwlock_rdlock failed"); |
| | 240 | } |
| | 241 | #else |
| 185 | 242 | #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS |
| 186 | 243 | boost::this_thread::disable_interruption do_not_disturb; |
| 187 | 244 | #endif |
| … |
… |
namespace boost
|
| 191 | 248 | shared_cond.wait(lk); |
| 192 | 249 | } |
| 193 | 250 | state.lock_shared(); |
| | 251 | #endif |
| 194 | 252 | } |
| 195 | 253 | |
| 196 | 254 | bool try_lock_shared() |
| 197 | 255 | { |
| | 256 | #if definet BOOST_THREAD_USE_PTHREAD_RWLOCKS |
| | 257 | int ret = pthread_rwlock_tryrdlock(&rw_lock); |
| | 258 | if (!ret) |
| | 259 | { |
| | 260 | return true; |
| | 261 | } |
| | 262 | else if (ret == EBUSY) |
| | 263 | { |
| | 264 | return false; |
| | 265 | } |
| | 266 | throw std::runtime_error("pthread_rwlock_tryrdlock failed"); |
| | 267 | #else |
| 198 | 268 | boost::unique_lock<boost::mutex> lk(state_change); |
| 199 | 269 | |
| 200 | 270 | if(!state.can_lock_shared()) |
| … |
… |
namespace boost
|
| 203 | 273 | } |
| 204 | 274 | state.lock_shared(); |
| 205 | 275 | return true; |
| | 276 | #endif |
| 206 | 277 | } |
| 207 | 278 | |
| 208 | 279 | #if defined BOOST_THREAD_USES_DATETIME |
| … |
… |
namespace boost
|
| 258 | 329 | #endif |
| 259 | 330 | void unlock_shared() |
| 260 | 331 | { |
| | 332 | #if defined BOOST_THREAD_USE_PTHREAD_RWLOCKS |
| | 333 | int ret = pthread_rwlock_unlock(&rw_lock); |
| | 334 | if (ret) |
| | 335 | { |
| | 336 | throw std::runtime_error("pthread_rwlock_unlock failed"); |
| | 337 | } |
| | 338 | #else |
| 261 | 339 | boost::unique_lock<boost::mutex> lk(state_change); |
| 262 | 340 | state.assert_lock_shared(); |
| 263 | 341 | state.unlock_shared(); |
| … |
… |
namespace boost
|
| 279 | 357 | } |
| 280 | 358 | release_waiters(); |
| 281 | 359 | } |
| | 360 | #endif |
| 282 | 361 | } |
| 283 | 362 | |
| 284 | 363 | void lock() |
| 285 | 364 | { |
| | 365 | #if defined BOOST_THREAD_USE_PTHREAD_RWLOCKS |
| | 366 | int ret = pthread_rwlock_wrlock(&rw_lock); |
| | 367 | if (ret) |
| | 368 | { |
| | 369 | throw std::runtime_error("pthread_rwlock_wrlock failed"); |
| | 370 | } |
| | 371 | #else |
| 286 | 372 | #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS |
| 287 | 373 | boost::this_thread::disable_interruption do_not_disturb; |
| 288 | 374 | #endif |
| … |
… |
namespace boost
|
| 294 | 380 | exclusive_cond.wait(lk); |
| 295 | 381 | } |
| 296 | 382 | state.exclusive=true; |
| | 383 | #endif |
| 297 | 384 | } |
| 298 | 385 | |
| 299 | 386 | #if defined BOOST_THREAD_USES_DATETIME |
| … |
… |
namespace boost
|
| 363 | 450 | |
| 364 | 451 | bool try_lock() |
| 365 | 452 | { |
| | 453 | #if defined BOOST_THREAD_USE_PTHREAD_RWLOCKS |
| | 454 | int ret = pthread_rwlock_trywrlock(&rw_lock); |
| | 455 | if (!ret) |
| | 456 | { |
| | 457 | return true; |
| | 458 | } |
| | 459 | else if (ret == EBUSY) |
| | 460 | { |
| | 461 | return false; |
| | 462 | } |
| | 463 | throw std::runtime_error("pthread_rwlock_trywrlock failed"); |
| | 464 | #else |
| 366 | 465 | boost::unique_lock<boost::mutex> lk(state_change); |
| 367 | 466 | |
| 368 | 467 | if(state.shared_count || state.exclusive) |
| … |
… |
namespace boost
|
| 374 | 473 | state.exclusive=true; |
| 375 | 474 | return true; |
| 376 | 475 | } |
| 377 | | |
| | 476 | #endif |
| 378 | 477 | } |
| 379 | 478 | |
| 380 | 479 | void unlock() |
| 381 | 480 | { |
| | 481 | #if defined BOOST_THREAD_USE_PTHREAD_RWLOCKS |
| | 482 | int ret = pthread_rwlock_unlock(&rw_lock); |
| | 483 | if (ret) |
| | 484 | { |
| | 485 | throw std::runtime_error("pthread_rwlock_unlock failed"); |
| | 486 | } |
| | 487 | #else |
| 382 | 488 | boost::unique_lock<boost::mutex> lk(state_change); |
| 383 | 489 | state.assert_locked(); |
| 384 | 490 | state.exclusive=false; |
| 385 | 491 | state.exclusive_waiting_blocked=false; |
| 386 | 492 | state.assert_free(); |
| 387 | 493 | release_waiters(); |
| | 494 | #endif |
| 388 | 495 | } |
| 389 | 496 | |
| 390 | 497 | void lock_upgrade() |