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() |