LCOV - code coverage report
Current view: top level - usr/include/boost/thread/pthread - shared_mutex.hpp (source / functions) Hit Total Coverage
Test: bitcoincash_test.info Lines: 55 62 88.7 %
Date: 2018-04-13 15:12:50 Functions: 10 11 90.9 %

          Line data    Source code
       1             : #ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
       2             : #define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
       3             : 
       4             : //  (C) Copyright 2006-8 Anthony Williams
       5             : //  (C) Copyright 2012 Vicente J. Botet Escriba
       6             : //
       7             : //  Distributed under the Boost Software License, Version 1.0. (See
       8             : //  accompanying file LICENSE_1_0.txt or copy at
       9             : //  http://www.boost.org/LICENSE_1_0.txt)
      10             : 
      11             : #include <boost/assert.hpp>
      12             : #include <boost/static_assert.hpp>
      13             : #include <boost/thread/mutex.hpp>
      14             : #include <boost/thread/condition_variable.hpp>
      15             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
      16             : #include <boost/thread/detail/thread_interruption.hpp>
      17             : #endif
      18             : #ifdef BOOST_THREAD_USES_CHRONO
      19             : #include <boost/chrono/system_clocks.hpp>
      20             : #include <boost/chrono/ceil.hpp>
      21             : #endif
      22             : #include <boost/thread/detail/delete.hpp>
      23             : #include <boost/assert.hpp>
      24             : 
      25             : #include <boost/config/abi_prefix.hpp>
      26             : 
      27             : namespace boost
      28             : {
      29             :     class shared_mutex
      30             :     {
      31             :     private:
      32             :         class state_data
      33             :         {
      34             :         public:
      35             :             state_data () :
      36             :               shared_count(0),
      37             :               exclusive(false),
      38             :               upgrade(false),
      39          40 :               exclusive_waiting_blocked(false)
      40             :             {}
      41             : 
      42          88 :             void assert_free() const
      43             :             {
      44          88 :                 BOOST_ASSERT( ! exclusive );
      45          88 :                 BOOST_ASSERT( ! upgrade );
      46          88 :                 BOOST_ASSERT( shared_count==0 );
      47          88 :             }
      48             : 
      49          88 :             void assert_locked() const
      50             :             {
      51          88 :                 BOOST_ASSERT( exclusive );
      52          88 :                 BOOST_ASSERT( shared_count==0 );
      53          88 :                 BOOST_ASSERT( ! upgrade );
      54          88 :             }
      55             : 
      56          80 :             void assert_lock_shared () const
      57             :             {
      58          80 :                 BOOST_ASSERT( ! exclusive );
      59          80 :                 BOOST_ASSERT( shared_count>0 );
      60             :                 //BOOST_ASSERT( (! upgrade) || (shared_count>1));
      61             :                 // if upgraded there are at least 2 threads sharing the mutex,
      62             :                 // except when unlock_upgrade_and_lock has decreased the number of readers but has not taken yet exclusive ownership.
      63          80 :             }
      64             : 
      65             :             void assert_lock_upgraded () const
      66             :             {
      67             :                 BOOST_ASSERT( ! exclusive );
      68             :                 BOOST_ASSERT(  upgrade );
      69             :                 BOOST_ASSERT(  shared_count>0 );
      70             :             }
      71             : 
      72             :             void assert_lock_not_upgraded () const
      73             :             {
      74             :                 BOOST_ASSERT(  ! upgrade );
      75             :             }
      76             : 
      77             :             bool can_lock () const
      78             :             {
      79             :                 return ! (shared_count || exclusive);
      80             :             }
      81             : 
      82             :             void exclusive_blocked (bool blocked)
      83             :             {
      84             :                 exclusive_waiting_blocked = blocked;
      85             :             }
      86             : 
      87             :             void lock ()
      88             :             {
      89             :                 exclusive = true;
      90             :             }
      91             : 
      92             :             void unlock ()
      93             :             {
      94             :                 exclusive = false;
      95             :                 exclusive_waiting_blocked = false;
      96             :             }
      97             : 
      98             :             bool can_lock_shared () const
      99             :             {
     100          80 :                 return ! (exclusive || exclusive_waiting_blocked);
     101             :             }
     102             : 
     103             :             bool more_shared () const
     104             :             {
     105             :                 return shared_count > 0 ;
     106             :             }
     107             :             unsigned get_shared_count () const
     108             :             {
     109             :                 return shared_count ;
     110             :             }
     111             :             unsigned  lock_shared ()
     112             :             {
     113          80 :                 return ++shared_count;
     114             :             }
     115             : 
     116             : 
     117             :             void unlock_shared ()
     118             :             {
     119          80 :                 --shared_count;
     120             :             }
     121             : 
     122             :             bool unlock_shared_downgrades()
     123             :             {
     124             :                   if (upgrade) {
     125             :                       upgrade=false;
     126             :                       exclusive=true;
     127             :                       return true;
     128             :                   } else {
     129             :                       exclusive_waiting_blocked=false;
     130             :                       return false;
     131             :                   }
     132             :             }
     133             : 
     134             :             void lock_upgrade ()
     135             :             {
     136             :                 ++shared_count;
     137             :                 upgrade=true;
     138             :             }
     139             :             bool can_lock_upgrade () const
     140             :             {
     141             :                 return ! (exclusive || exclusive_waiting_blocked || upgrade);
     142             :             }
     143             : 
     144             :             void unlock_upgrade ()
     145             :             {
     146             :                 upgrade=false;
     147             :                 --shared_count;
     148             :             }
     149             : 
     150             :         //private:
     151             :             unsigned shared_count;
     152             :             bool exclusive;
     153             :             bool upgrade;
     154             :             bool exclusive_waiting_blocked;
     155             :         };
     156             : 
     157             : 
     158             : 
     159             :         state_data state;
     160             :         boost::mutex state_change;
     161             :         boost::condition_variable shared_cond;
     162             :         boost::condition_variable exclusive_cond;
     163             :         boost::condition_variable upgrade_cond;
     164             : 
     165             :         void release_waiters()
     166             :         {
     167         166 :             exclusive_cond.notify_one();
     168         166 :             shared_cond.notify_all();
     169             :         }
     170             : 
     171             :     public:
     172             : 
     173             :         BOOST_THREAD_NO_COPYABLE(shared_mutex)
     174             : 
     175          40 :         shared_mutex()
     176          80 :         {
     177          40 :         }
     178             : 
     179          40 :         ~shared_mutex()
     180          40 :         {
     181          40 :         }
     182             : 
     183          80 :         void lock_shared()
     184             :         {
     185             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     186         160 :             boost::this_thread::disable_interruption do_not_disturb;
     187             : #endif
     188         160 :             boost::unique_lock<boost::mutex> lk(state_change);
     189         160 :             while(!state.can_lock_shared())
     190             :             {
     191           0 :                 shared_cond.wait(lk);
     192             :             }
     193         160 :             state.lock_shared();
     194          80 :         }
     195             : 
     196             :         bool try_lock_shared()
     197             :         {
     198             :             boost::unique_lock<boost::mutex> lk(state_change);
     199             : 
     200             :             if(!state.can_lock_shared())
     201             :             {
     202             :                 return false;
     203             :             }
     204             :             state.lock_shared();
     205             :             return true;
     206             :         }
     207             : 
     208             : #if defined BOOST_THREAD_USES_DATETIME
     209             :         bool timed_lock_shared(system_time const& timeout)
     210             :         {
     211             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     212             :             boost::this_thread::disable_interruption do_not_disturb;
     213             : #endif
     214             :             boost::unique_lock<boost::mutex> lk(state_change);
     215             : 
     216             :             while(!state.can_lock_shared())
     217             :             {
     218             :                 if(!shared_cond.timed_wait(lk,timeout))
     219             :                 {
     220             :                     return false;
     221             :                 }
     222             :             }
     223             :             state.lock_shared();
     224             :             return true;
     225             :         }
     226             : 
     227             :         template<typename TimeDuration>
     228             :         bool timed_lock_shared(TimeDuration const & relative_time)
     229             :         {
     230             :             return timed_lock_shared(get_system_time()+relative_time);
     231             :         }
     232             : #endif
     233             : #ifdef BOOST_THREAD_USES_CHRONO
     234             :         template <class Rep, class Period>
     235             :         bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
     236             :         {
     237             :           return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
     238             :         }
     239             :         template <class Clock, class Duration>
     240             :         bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
     241             :         {
     242             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     243             :           boost::this_thread::disable_interruption do_not_disturb;
     244             : #endif
     245             :           boost::unique_lock<boost::mutex> lk(state_change);
     246             : 
     247             :           while(!state.can_lock_shared())
     248             :           //while(state.exclusive || state.exclusive_waiting_blocked)
     249             :           {
     250             :               if(cv_status::timeout==shared_cond.wait_until(lk,abs_time))
     251             :               {
     252             :                   return false;
     253             :               }
     254             :           }
     255             :           state.lock_shared();
     256             :           return true;
     257             :         }
     258             : #endif
     259          80 :         void unlock_shared()
     260             :         {
     261         240 :             boost::unique_lock<boost::mutex> lk(state_change);
     262          80 :             state.assert_lock_shared();
     263         160 :             state.unlock_shared();
     264          80 :             if (! state.more_shared())
     265             :             {
     266          78 :                 if (state.upgrade)
     267             :                 {
     268             :                     // As there is a thread doing a unlock_upgrade_and_lock that is waiting for ! state.more_shared()
     269             :                     // avoid other threads to lock, lock_upgrade or lock_shared, so only this thread is notified.
     270           0 :                     state.upgrade=false;
     271           0 :                     state.exclusive=true;
     272           0 :                     lk.unlock();
     273           0 :                     upgrade_cond.notify_one();
     274             :                 }
     275             :                 else
     276             :                 {
     277          78 :                     state.exclusive_waiting_blocked=false;
     278          78 :                     lk.unlock();
     279             :                 }
     280             :                 release_waiters();
     281             :             }
     282          80 :         }
     283             : 
     284          88 :         void lock()
     285             :         {
     286             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     287         176 :             boost::this_thread::disable_interruption do_not_disturb;
     288             : #endif
     289         176 :             boost::unique_lock<boost::mutex> lk(state_change);
     290             : 
     291          88 :             while (state.shared_count || state.exclusive)
     292             :             {
     293           0 :                 state.exclusive_waiting_blocked=true;
     294           0 :                 exclusive_cond.wait(lk);
     295             :             }
     296          88 :             state.exclusive=true;
     297          88 :         }
     298             : 
     299             : #if defined BOOST_THREAD_USES_DATETIME
     300             :         bool timed_lock(system_time const& timeout)
     301             :         {
     302             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     303             :             boost::this_thread::disable_interruption do_not_disturb;
     304             : #endif
     305             :             boost::unique_lock<boost::mutex> lk(state_change);
     306             : 
     307             :             while(state.shared_count || state.exclusive)
     308             :             {
     309             :                 state.exclusive_waiting_blocked=true;
     310             :                 if(!exclusive_cond.timed_wait(lk,timeout))
     311             :                 {
     312             :                     if(state.shared_count || state.exclusive)
     313             :                     {
     314             :                         state.exclusive_waiting_blocked=false;
     315             :                         release_waiters();
     316             :                         return false;
     317             :                     }
     318             :                     break;
     319             :                 }
     320             :             }
     321             :             state.exclusive=true;
     322             :             return true;
     323             :         }
     324             : 
     325             :         template<typename TimeDuration>
     326             :         bool timed_lock(TimeDuration const & relative_time)
     327             :         {
     328             :             return timed_lock(get_system_time()+relative_time);
     329             :         }
     330             : #endif
     331             : #ifdef BOOST_THREAD_USES_CHRONO
     332             :         template <class Rep, class Period>
     333             :         bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
     334             :         {
     335             :           return try_lock_until(chrono::steady_clock::now() + rel_time);
     336             :         }
     337             :         template <class Clock, class Duration>
     338             :         bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
     339             :         {
     340             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     341             :           boost::this_thread::disable_interruption do_not_disturb;
     342             : #endif
     343             :           boost::unique_lock<boost::mutex> lk(state_change);
     344             : 
     345             :           while(state.shared_count || state.exclusive)
     346             :           {
     347             :               state.exclusive_waiting_blocked=true;
     348             :               if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time))
     349             :               {
     350             :                   if(state.shared_count || state.exclusive)
     351             :                   {
     352             :                       state.exclusive_waiting_blocked=false;
     353             :                       release_waiters();
     354             :                       return false;
     355             :                   }
     356             :                   break;
     357             :               }
     358             :           }
     359             :           state.exclusive=true;
     360             :           return true;
     361             :         }
     362             : #endif
     363             : 
     364             :         bool try_lock()
     365             :         {
     366             :             boost::unique_lock<boost::mutex> lk(state_change);
     367             : 
     368             :             if(state.shared_count || state.exclusive)
     369             :             {
     370             :                 return false;
     371             :             }
     372             :             else
     373             :             {
     374             :                 state.exclusive=true;
     375             :                 return true;
     376             :             }
     377             : 
     378             :         }
     379             : 
     380          88 :         void unlock()
     381             :         {
     382         264 :             boost::unique_lock<boost::mutex> lk(state_change);
     383          88 :             state.assert_locked();
     384          88 :             state.exclusive=false;
     385          88 :             state.exclusive_waiting_blocked=false;
     386          88 :             state.assert_free();
     387          88 :             release_waiters();
     388          88 :         }
     389             : 
     390             :         void lock_upgrade()
     391             :         {
     392             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     393             :             boost::this_thread::disable_interruption do_not_disturb;
     394             : #endif
     395             :             boost::unique_lock<boost::mutex> lk(state_change);
     396             :             while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
     397             :             {
     398             :                 shared_cond.wait(lk);
     399             :             }
     400             :             state.lock_shared();
     401             :             state.upgrade=true;
     402             :         }
     403             : 
     404             : #if defined BOOST_THREAD_USES_DATETIME
     405             :         bool timed_lock_upgrade(system_time const& timeout)
     406             :         {
     407             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     408             :             boost::this_thread::disable_interruption do_not_disturb;
     409             : #endif
     410             :             boost::unique_lock<boost::mutex> lk(state_change);
     411             :             while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
     412             :             {
     413             :                 if(!shared_cond.timed_wait(lk,timeout))
     414             :                 {
     415             :                     if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
     416             :                     {
     417             :                         return false;
     418             :                     }
     419             :                     break;
     420             :                 }
     421             :             }
     422             :             state.lock_shared();
     423             :             state.upgrade=true;
     424             :             return true;
     425             :         }
     426             : 
     427             :         template<typename TimeDuration>
     428             :         bool timed_lock_upgrade(TimeDuration const & relative_time)
     429             :         {
     430             :             return timed_lock_upgrade(get_system_time()+relative_time);
     431             :         }
     432             : #endif
     433             : #ifdef BOOST_THREAD_USES_CHRONO
     434             :         template <class Rep, class Period>
     435             :         bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time)
     436             :         {
     437             :           return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
     438             :         }
     439             :         template <class Clock, class Duration>
     440             :         bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time)
     441             :         {
     442             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     443             :           boost::this_thread::disable_interruption do_not_disturb;
     444             : #endif
     445             :           boost::unique_lock<boost::mutex> lk(state_change);
     446             :           while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
     447             :           {
     448             :               if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
     449             :               {
     450             :                   if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
     451             :                   {
     452             :                       return false;
     453             :                   }
     454             :                   break;
     455             :               }
     456             :           }
     457             :           state.lock_shared();
     458             :           state.upgrade=true;
     459             :           return true;
     460             :         }
     461             : #endif
     462             :         bool try_lock_upgrade()
     463             :         {
     464             :             boost::unique_lock<boost::mutex> lk(state_change);
     465             :             if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
     466             :             {
     467             :                 return false;
     468             :             }
     469             :             else
     470             :             {
     471             :                 state.lock_shared();
     472             :                 state.upgrade=true;
     473             :                 state.assert_lock_upgraded();
     474             :                 return true;
     475             :             }
     476             :         }
     477             : 
     478             :         void unlock_upgrade()
     479             :         {
     480             :             boost::unique_lock<boost::mutex> lk(state_change);
     481             :             //state.upgrade=false;
     482             :             state.unlock_upgrade();
     483             :             if(! state.more_shared() )
     484             :             {
     485             :                 state.exclusive_waiting_blocked=false;
     486             :                 release_waiters();
     487             :             } else {
     488             :                 shared_cond.notify_all();
     489             :             }
     490             :         }
     491             : 
     492             :         // Upgrade <-> Exclusive
     493             :         void unlock_upgrade_and_lock()
     494             :         {
     495             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     496             :             boost::this_thread::disable_interruption do_not_disturb;
     497             : #endif
     498             :             boost::unique_lock<boost::mutex> lk(state_change);
     499             :             state.assert_lock_upgraded();
     500             :             state.unlock_shared();
     501             :             while (state.more_shared())
     502             :             {
     503             :                 upgrade_cond.wait(lk);
     504             :             }
     505             :             state.upgrade=false;
     506             :             state.exclusive=true;
     507             :             state.assert_locked();
     508             :         }
     509             : 
     510             :         void unlock_and_lock_upgrade()
     511             :         {
     512             :             boost::unique_lock<boost::mutex> lk(state_change);
     513             :             state.assert_locked();
     514             :             state.exclusive=false;
     515             :             state.upgrade=true;
     516             :             state.lock_shared();
     517             :             state.exclusive_waiting_blocked=false;
     518             :             state.assert_lock_upgraded();
     519             :             release_waiters();
     520             :         }
     521             : 
     522             :         bool try_unlock_upgrade_and_lock()
     523             :         {
     524             :           boost::unique_lock<boost::mutex> lk(state_change);
     525             :           state.assert_lock_upgraded();
     526             :           if(    !state.exclusive
     527             :               && !state.exclusive_waiting_blocked
     528             :               && state.upgrade
     529             :               && state.shared_count==1)
     530             :           {
     531             :             state.shared_count=0;
     532             :             state.exclusive=true;
     533             :             state.upgrade=false;
     534             :             state.assert_locked();
     535             :             return true;
     536             :           }
     537             :           return false;
     538             :         }
     539             : #ifdef BOOST_THREAD_USES_CHRONO
     540             :         template <class Rep, class Period>
     541             :         bool
     542             :         try_unlock_upgrade_and_lock_for(
     543             :                                 const chrono::duration<Rep, Period>& rel_time)
     544             :         {
     545             :           return try_unlock_upgrade_and_lock_until(
     546             :                                  chrono::steady_clock::now() + rel_time);
     547             :         }
     548             :         template <class Clock, class Duration>
     549             :         bool
     550             :         try_unlock_upgrade_and_lock_until(
     551             :                           const chrono::time_point<Clock, Duration>& abs_time)
     552             :         {
     553             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     554             :           boost::this_thread::disable_interruption do_not_disturb;
     555             : #endif
     556             :           boost::unique_lock<boost::mutex> lk(state_change);
     557             :           state.assert_lock_upgraded();
     558             :           if (state.shared_count != 1)
     559             :           {
     560             :               for (;;)
     561             :               {
     562             :                 cv_status status = shared_cond.wait_until(lk,abs_time);
     563             :                 if (state.shared_count == 1)
     564             :                   break;
     565             :                 if(status == cv_status::timeout)
     566             :                   return false;
     567             :               }
     568             :           }
     569             :           state.upgrade=false;
     570             :           state.exclusive=true;
     571             :           state.exclusive_waiting_blocked=false;
     572             :           state.shared_count=0;
     573             :           return true;
     574             :         }
     575             : #endif
     576             : 
     577             :         // Shared <-> Exclusive
     578             :         void unlock_and_lock_shared()
     579             :         {
     580             :             boost::unique_lock<boost::mutex> lk(state_change);
     581             :             state.assert_locked();
     582             :             state.exclusive=false;
     583             :             state.lock_shared();
     584             :             state.exclusive_waiting_blocked=false;
     585             :             release_waiters();
     586             :         }
     587             : 
     588             : #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
     589             :         bool try_unlock_shared_and_lock()
     590             :         {
     591             :           boost::unique_lock<boost::mutex> lk(state_change);
     592             :           state.assert_lock_shared();
     593             :           if(    !state.exclusive
     594             :               && !state.exclusive_waiting_blocked
     595             :               && !state.upgrade
     596             :               && state.shared_count==1)
     597             :           {
     598             :             state.shared_count=0;
     599             :             state.exclusive=true;
     600             :             return true;
     601             :           }
     602             :           return false;
     603             :         }
     604             : #ifdef BOOST_THREAD_USES_CHRONO
     605             :         template <class Rep, class Period>
     606             :             bool
     607             :             try_unlock_shared_and_lock_for(
     608             :                                 const chrono::duration<Rep, Period>& rel_time)
     609             :         {
     610             :           return try_unlock_shared_and_lock_until(
     611             :                                  chrono::steady_clock::now() + rel_time);
     612             :         }
     613             :         template <class Clock, class Duration>
     614             :             bool
     615             :             try_unlock_shared_and_lock_until(
     616             :                           const chrono::time_point<Clock, Duration>& abs_time)
     617             :         {
     618             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     619             :           boost::this_thread::disable_interruption do_not_disturb;
     620             : #endif
     621             :           boost::unique_lock<boost::mutex> lk(state_change);
     622             :           state.assert_lock_shared();
     623             :           if (state.shared_count != 1)
     624             :           {
     625             :               for (;;)
     626             :               {
     627             :                 cv_status status = shared_cond.wait_until(lk,abs_time);
     628             :                 if (state.shared_count == 1)
     629             :                   break;
     630             :                 if(status == cv_status::timeout)
     631             :                   return false;
     632             :               }
     633             :           }
     634             :           state.upgrade=false;
     635             :           state.exclusive=true;
     636             :           state.exclusive_waiting_blocked=false;
     637             :           state.shared_count=0;
     638             :           return true;
     639             :         }
     640             : #endif
     641             : #endif
     642             : 
     643             :         // Shared <-> Upgrade
     644             :         void unlock_upgrade_and_lock_shared()
     645             :         {
     646             :             boost::unique_lock<boost::mutex> lk(state_change);
     647             :             state.assert_lock_upgraded();
     648             :             state.upgrade=false;
     649             :             state.exclusive_waiting_blocked=false;
     650             :             release_waiters();
     651             :         }
     652             : 
     653             : #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
     654             :         bool try_unlock_shared_and_lock_upgrade()
     655             :         {
     656             :           boost::unique_lock<boost::mutex> lk(state_change);
     657             :           state.assert_lock_shared();
     658             :           if(    !state.exclusive
     659             :               && !state.exclusive_waiting_blocked
     660             :               && !state.upgrade
     661             :               )
     662             :           {
     663             :             state.upgrade=true;
     664             :             return true;
     665             :           }
     666             :           return false;
     667             :         }
     668             : #ifdef BOOST_THREAD_USES_CHRONO
     669             :         template <class Rep, class Period>
     670             :             bool
     671             :             try_unlock_shared_and_lock_upgrade_for(
     672             :                                 const chrono::duration<Rep, Period>& rel_time)
     673             :         {
     674             :           return try_unlock_shared_and_lock_upgrade_until(
     675             :                                  chrono::steady_clock::now() + rel_time);
     676             :         }
     677             :         template <class Clock, class Duration>
     678             :             bool
     679             :             try_unlock_shared_and_lock_upgrade_until(
     680             :                           const chrono::time_point<Clock, Duration>& abs_time)
     681             :         {
     682             : #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     683             :           boost::this_thread::disable_interruption do_not_disturb;
     684             : #endif
     685             :           boost::unique_lock<boost::mutex> lk(state_change);
     686             :           state.assert_lock_shared();
     687             :           if(    state.exclusive
     688             :               || state.exclusive_waiting_blocked
     689             :               || state.upgrade
     690             :               )
     691             :           {
     692             :               for (;;)
     693             :               {
     694             :                 cv_status status = exclusive_cond.wait_until(lk,abs_time);
     695             :                 if(    ! state.exclusive
     696             :                     && ! state.exclusive_waiting_blocked
     697             :                     && ! state.upgrade
     698             :                     )
     699             :                   break;
     700             :                 if(status == cv_status::timeout)
     701             :                   return false;
     702             :               }
     703             :           }
     704             :           state.upgrade=true;
     705             :           return true;
     706             :         }
     707             : #endif
     708             : #endif
     709             :     };
     710             : 
     711             :     typedef shared_mutex upgrade_mutex;
     712             : }
     713             : 
     714             : #include <boost/config/abi_suffix.hpp>
     715             : 
     716             : #endif

Generated by: LCOV version 1.12