]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/interprocess/sync/detail/condition_algorithm_8a.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / interprocess / sync / detail / condition_algorithm_8a.hpp
index 9978309b965ccf4b413216611d9f7cd16b4bea56..a4cce7ba7ecfcd03b1fb1c3e98a88eb1aaf5c26a 100644 (file)
@@ -193,130 +193,124 @@ class condition_algorithm_8a
    typedef typename ConditionMembers::integer_type    integer_type;
 
    public:
-   template<class Lock>
-   static bool wait  ( ConditionMembers &data, Lock &lock
-                     , bool timeout_enabled, const boost::posix_time::ptime &abs_time);
-   static void signal(ConditionMembers &data, bool broadcast);
-};
-
-template<class ConditionMembers>
-inline void condition_algorithm_8a<ConditionMembers>::signal(ConditionMembers &data, bool broadcast)
-{
-   integer_type nsignals_to_issue;
-
+   template<bool TimeoutEnabled, class Lock, class TimePoint>
+   static bool wait  ( ConditionMembers &data, Lock &lock, const TimePoint &abs_time)
    {
-      scoped_lock<mutex_type> locker(data.get_mtx_unblock_lock());
-
-      if ( 0 != data.get_nwaiters_to_unblock() ) {        // the gate is closed!!!
-         if ( 0 == data.get_nwaiters_blocked() ) {        // NO-OP
-            //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
-            return;
-         }
-         if (broadcast) {
-            data.get_nwaiters_to_unblock() += nsignals_to_issue = data.get_nwaiters_blocked();
-            data.get_nwaiters_blocked() = 0;
-         }
-         else {
-            nsignals_to_issue = 1;
-            data.get_nwaiters_to_unblock()++;
-            data.get_nwaiters_blocked()--;
+      //Initialize to avoid warnings
+      integer_type nsignals_was_left = 0;
+      integer_type nwaiters_was_gone = 0;
+
+      data.get_sem_block_lock().wait();
+      ++data.get_nwaiters_blocked();
+      data.get_sem_block_lock().post();
+
+      //Unlock external lock and program for relock
+      lock_inverter<Lock> inverted_lock(lock);
+      scoped_lock<lock_inverter<Lock> >   external_unlock(inverted_lock);
+
+      bool bTimedOut = !do_sem_timed_wait(data.get_sem_block_queue(), abs_time, bool_<TimeoutEnabled>());
+
+      {
+         scoped_lock<mutex_type> locker(data.get_mtx_unblock_lock());
+         if ( 0 != (nsignals_was_left = data.get_nwaiters_to_unblock()) ) {
+            if ( bTimedOut ) {                       // timeout (or canceled)
+               if ( 0 != data.get_nwaiters_blocked() ) {
+                  data.get_nwaiters_blocked()--;
+               }
+               else {
+                  data.get_nwaiters_gone()++;                     // count spurious wakeups.
+               }
+            }
+            if ( 0 == --data.get_nwaiters_to_unblock() ) {
+               if ( 0 != data.get_nwaiters_blocked() ) {
+                  data.get_sem_block_lock().post();          // open the gate.
+                  nsignals_was_left = 0;          // do not open the gate below again.
+               }
+               else if ( 0 != (nwaiters_was_gone = data.get_nwaiters_gone()) ) {
+                  data.get_nwaiters_gone() = 0;
+               }
+            }
          }
-      }
-      else if ( data.get_nwaiters_blocked() > data.get_nwaiters_gone() ) { // HARMLESS RACE CONDITION!
-         data.get_sem_block_lock().wait();                      // close the gate
-         if ( 0 != data.get_nwaiters_gone() ) {
-            data.get_nwaiters_blocked() -= data.get_nwaiters_gone();
+         else if ( (std::numeric_limits<integer_type>::max)()/2
+                   == ++data.get_nwaiters_gone() ) { // timeout/canceled or spurious semaphore :-)
+            data.get_sem_block_lock().wait();
+            data.get_nwaiters_blocked() -= data.get_nwaiters_gone();       // something is going on here - test of timeouts? :-)
+            data.get_sem_block_lock().post();
             data.get_nwaiters_gone() = 0;
          }
-         if (broadcast) {
-            nsignals_to_issue = data.get_nwaiters_to_unblock() = data.get_nwaiters_blocked();
-            data.get_nwaiters_blocked() = 0;
-         }
-         else {
-            nsignals_to_issue = data.get_nwaiters_to_unblock() = 1;
-            data.get_nwaiters_blocked()--;
-         }
-      }
-      else { // NO-OP
          //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
-         return;
       }
-      //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
-   }
-   data.get_sem_block_queue().post(nsignals_to_issue);
-}
 
-template<class ConditionMembers>
-template<class Lock>
-inline bool condition_algorithm_8a<ConditionMembers>::wait
-   ( ConditionMembers &data
-   , Lock &lock
-   , bool tout_enabled
-   , const boost::posix_time::ptime &abs_time
-   )
-{
-   //Initialize to avoid warnings
-   integer_type nsignals_was_left = 0;
-   integer_type nwaiters_was_gone = 0;
-
-   data.get_sem_block_lock().wait();
-   ++data.get_nwaiters_blocked();
-   data.get_sem_block_lock().post();
+      if ( 1 == nsignals_was_left ) {
+         if ( 0 != nwaiters_was_gone ) {
+            // sem_adjust( data.get_sem_block_queue(),-nwaiters_was_gone );
+            while ( nwaiters_was_gone-- ) {
+               data.get_sem_block_queue().wait();       // better now than spurious later
+            }
+         }
+         data.get_sem_block_lock().post(); // open the gate
+      }
 
-   //Unlock external lock and program for relock
-   lock_inverter<Lock> inverted_lock(lock);
-   scoped_lock<lock_inverter<Lock> >   external_unlock(inverted_lock);
+      //lock.lock(); called from unlocker destructor
 
-   bool bTimedOut = tout_enabled
-      ? !data.get_sem_block_queue().timed_wait(abs_time)
-      : (data.get_sem_block_queue().wait(), false);
+      return ( bTimedOut ) ? false : true;
+   }
 
+   static void signal(ConditionMembers &data, bool broadcast)
    {
-      scoped_lock<mutex_type> locker(data.get_mtx_unblock_lock());
-      if ( 0 != (nsignals_was_left = data.get_nwaiters_to_unblock()) ) {
-         if ( bTimedOut ) {                       // timeout (or canceled)
-            if ( 0 != data.get_nwaiters_blocked() ) {
-               data.get_nwaiters_blocked()--;
+      integer_type nsignals_to_issue;
+
+      {
+         scoped_lock<mutex_type> locker(data.get_mtx_unblock_lock());
+
+         if ( 0 != data.get_nwaiters_to_unblock() ) {        // the gate is closed!!!
+            if ( 0 == data.get_nwaiters_blocked() ) {        // NO-OP
+               //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
+               return;
+            }
+            if (broadcast) {
+               data.get_nwaiters_to_unblock() += nsignals_to_issue = data.get_nwaiters_blocked();
+               data.get_nwaiters_blocked() = 0;
             }
             else {
-               data.get_nwaiters_gone()++;                     // count spurious wakeups.
+               nsignals_to_issue = 1;
+               data.get_nwaiters_to_unblock()++;
+               data.get_nwaiters_blocked()--;
             }
          }
-         if ( 0 == --data.get_nwaiters_to_unblock() ) {
-            if ( 0 != data.get_nwaiters_blocked() ) {
-               data.get_sem_block_lock().post();          // open the gate.
-               nsignals_was_left = 0;          // do not open the gate below again.
-            }
-            else if ( 0 != (nwaiters_was_gone = data.get_nwaiters_gone()) ) {
+         else if ( data.get_nwaiters_blocked() > data.get_nwaiters_gone() ) { // HARMLESS RACE CONDITION!
+            data.get_sem_block_lock().wait();                      // close the gate
+            if ( 0 != data.get_nwaiters_gone() ) {
+               data.get_nwaiters_blocked() -= data.get_nwaiters_gone();
                data.get_nwaiters_gone() = 0;
             }
+            if (broadcast) {
+               nsignals_to_issue = data.get_nwaiters_to_unblock() = data.get_nwaiters_blocked();
+               data.get_nwaiters_blocked() = 0;
+            }
+            else {
+               nsignals_to_issue = data.get_nwaiters_to_unblock() = 1;
+               data.get_nwaiters_blocked()--;
+            }
          }
-      }
-      else if ( (std::numeric_limits<integer_type>::max)()/2
-                == ++data.get_nwaiters_gone() ) { // timeout/canceled or spurious semaphore :-)
-         data.get_sem_block_lock().wait();
-         data.get_nwaiters_blocked() -= data.get_nwaiters_gone();       // something is going on here - test of timeouts? :-)
-         data.get_sem_block_lock().post();
-         data.get_nwaiters_gone() = 0;
-      }
-      //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
-   }
-
-   if ( 1 == nsignals_was_left ) {
-      if ( 0 != nwaiters_was_gone ) {
-         // sem_adjust( data.get_sem_block_queue(),-nwaiters_was_gone );
-         while ( nwaiters_was_gone-- ) {
-            data.get_sem_block_queue().wait();       // better now than spurious later
+         else { // NO-OP
+            //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
+            return;
          }
+         //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
       }
-      data.get_sem_block_lock().post(); // open the gate
+      data.get_sem_block_queue().post(nsignals_to_issue);
    }
 
-   //lock.lock(); called from unlocker destructor
-
-   return ( bTimedOut ) ? false : true;
-}
+   private:
+   template<class TimePoint>
+   static bool do_sem_timed_wait(semaphore_type &sem, const TimePoint &abs_time, bool_<true>)
+   {  return sem.timed_wait(abs_time); }
 
+   template<class TimePoint>
+   static bool do_sem_timed_wait(semaphore_type &sem, const TimePoint &, bool_<false>)
+   {  sem.wait();  return true;  }
+};
 
 template<class ConditionMembers>
 class condition_8a_wrapper
@@ -326,7 +320,7 @@ class condition_8a_wrapper
    condition_8a_wrapper &operator=(const condition_8a_wrapper &);
 
    ConditionMembers m_data;
-   typedef ipcdetail::condition_algorithm_8a<ConditionMembers> algo_type;
+   typedef condition_algorithm_8a<ConditionMembers> algo_type;
 
    public:
 
@@ -352,7 +346,7 @@ class condition_8a_wrapper
    {
       if (!lock)
          throw lock_exception();
-      algo_type::wait(m_data, lock, false, boost::posix_time::ptime());
+      algo_type::template wait<false>(m_data, lock, 0);
    }
 
    template <typename L, typename Pr>
@@ -362,24 +356,24 @@ class condition_8a_wrapper
          throw lock_exception();
 
       while (!pred())
-         algo_type::wait(m_data, lock, false, boost::posix_time::ptime());
+         algo_type::template wait<false>(m_data, lock, 0);
    }
 
-   template <typename L>
-   bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
+   template <typename L, class TimePoint>
+   bool timed_wait(L& lock, const TimePoint &abs_time)
    {
       if (!lock)
          throw lock_exception();
-      return algo_type::wait(m_data, lock, true, abs_time);
+      return algo_type::template wait<true>(m_data, lock, abs_time);
    }
 
-   template <typename L, typename Pr>
-   bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
+   template <typename L, class TimePoint, typename Pr>
+   bool timed_wait(L& lock, const TimePoint &abs_time, Pr pred)
    {
       if (!lock)
             throw lock_exception();
       while (!pred()){
-         if (!algo_type::wait(m_data, lock, true, abs_time))
+         if (!algo_type::template wait<true>(m_data, lock, abs_time))
             return pred();
       }
       return true;