Ticket #11798: patch.diff

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

initial patch for pthread_rwlock* implementation

  • boost/thread/pthread/shared_mutex.hpp

    diff --git a/boost/thread/pthread/shared_mutex.hpp b/boost/thread/pthread/shared_mutex.hpp
    index 458d6c8..2a7b983 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  
    172181
    173182        BOOST_THREAD_NO_COPYABLE(shared_mutex)
    174183
     184#if defined BOOST_THREAD_PTHREAD_USE_RWLOCKS
     185        BOOST_THREAD_NO_COPYABLE(rw_lock)
     186#endif
     187
    175188        shared_mutex()
    176189        {
     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
    177224        }
    178225
    179226        ~shared_mutex()
    180227        {
     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
    181235        }
    182236
    183237        void lock_shared()
    184238        {
     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
    185246#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
    186247            boost::this_thread::disable_interruption do_not_disturb;
    187248#endif
    namespace boost  
    191252                shared_cond.wait(lk);
    192253            }
    193254            state.lock_shared();
     255#endif
    194256        }
    195257
    196258        bool try_lock_shared()
    197259        {
     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
    198272            boost::unique_lock<boost::mutex> lk(state_change);
    199273
    200274            if(!state.can_lock_shared())
    namespace boost  
    203277            }
    204278            state.lock_shared();
    205279            return true;
     280#endif
    206281        }
    207282
    208283#if defined BOOST_THREAD_USES_DATETIME
    namespace boost  
    258333#endif
    259334        void unlock_shared()
    260335        {
     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
    261343            boost::unique_lock<boost::mutex> lk(state_change);
    262344            state.assert_lock_shared();
    263345            state.unlock_shared();
    namespace boost  
    279361                }
    280362                release_waiters();
    281363            }
     364#endif
    282365        }
    283366
    284367        void lock()
    285368        {
     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
    286376#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
    287377            boost::this_thread::disable_interruption do_not_disturb;
    288378#endif
    namespace boost  
    294384                exclusive_cond.wait(lk);
    295385            }
    296386            state.exclusive=true;
     387#endif
    297388        }
    298389
    299390#if defined BOOST_THREAD_USES_DATETIME
    namespace boost  
    363454
    364455        bool try_lock()
    365456        {
     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
    366469            boost::unique_lock<boost::mutex> lk(state_change);
    367470
    368471            if(state.shared_count || state.exclusive)
    namespace boost  
    374477                state.exclusive=true;
    375478                return true;
    376479            }
    377 
     480#endif
    378481        }
    379482
    380483        void unlock()
    381484        {
     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
    382492            boost::unique_lock<boost::mutex> lk(state_change);
    383493            state.assert_locked();
    384494            state.exclusive=false;
    385495            state.exclusive_waiting_blocked=false;
    386496            state.assert_free();
    387497            release_waiters();
     498#endif
    388499        }
    389500
    390501        void lock_upgrade()