Ticket #11798: patch.2.diff

File patch.2.diff, 5.9 KB (added by alex@…, 7 years ago)

updated patch

  • boost/thread/pthread/shared_mutex.hpp

    diff --git a/boost/thread/pthread/shared_mutex.hpp b/boost/thread/pthread/shared_mutex.hpp
    index 458d6c8..9d527db 100644
    a b  
    2424
    2525#include <boost/config/abi_prefix.hpp>
    2626
     27#if defined BOOST_THREAD_USE_PTHREAD_RWLOCKS
     28#include <stdexcept>
     29#include <pthread.h>
     30#endif
     31
    2732namespace boost
    2833{
    2934    class shared_mutex
    namespace boost  
    162167        boost::condition_variable exclusive_cond;
    163168        boost::condition_variable upgrade_cond;
    164169
     170#if defined BOOST_THREAD_PTHREAD_USE_RWLOCKS
     171        pthread_rwlock_t rw_lock;
     172#endif
     173
    165174        void release_waiters()
    166175        {
    167176            exclusive_cond.notify_one();
    namespace boost  
    174183
    175184        shared_mutex()
    176185        {
     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
    177220        }
    178221
    179222        ~shared_mutex()
    180223        {
     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
    181231        }
    182232
    183233        void lock_shared()
    184234        {
     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
    185242#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
    186243            boost::this_thread::disable_interruption do_not_disturb;
    187244#endif
    namespace boost  
    191248                shared_cond.wait(lk);
    192249            }
    193250            state.lock_shared();
     251#endif
    194252        }
    195253
    196254        bool try_lock_shared()
    197255        {
     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
    198268            boost::unique_lock<boost::mutex> lk(state_change);
    199269
    200270            if(!state.can_lock_shared())
    namespace boost  
    203273            }
    204274            state.lock_shared();
    205275            return true;
     276#endif
    206277        }
    207278
    208279#if defined BOOST_THREAD_USES_DATETIME
    namespace boost  
    258329#endif
    259330        void unlock_shared()
    260331        {
     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
    261339            boost::unique_lock<boost::mutex> lk(state_change);
    262340            state.assert_lock_shared();
    263341            state.unlock_shared();
    namespace boost  
    279357                }
    280358                release_waiters();
    281359            }
     360#endif
    282361        }
    283362
    284363        void lock()
    285364        {
     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
    286372#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
    287373            boost::this_thread::disable_interruption do_not_disturb;
    288374#endif
    namespace boost  
    294380                exclusive_cond.wait(lk);
    295381            }
    296382            state.exclusive=true;
     383#endif
    297384        }
    298385
    299386#if defined BOOST_THREAD_USES_DATETIME
    namespace boost  
    363450
    364451        bool try_lock()
    365452        {
     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
    366465            boost::unique_lock<boost::mutex> lk(state_change);
    367466
    368467            if(state.shared_count || state.exclusive)
    namespace boost  
    374473                state.exclusive=true;
    375474                return true;
    376475            }
    377 
     476#endif
    378477        }
    379478
    380479        void unlock()
    381480        {
     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
    382488            boost::unique_lock<boost::mutex> lk(state_change);
    383489            state.assert_locked();
    384490            state.exclusive=false;
    385491            state.exclusive_waiting_blocked=false;
    386492            state.assert_free();
    387493            release_waiters();
     494#endif
    388495        }
    389496
    390497        void lock_upgrade()