code:
//  (C) Copyright 2008-10 Anthony Williams
//  (C) Copyright 2011-2015 Vicente J. Botet Escriba
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_THREAD_FUTURES_FUTURE_ERROR_HPP
#define BOOST_THREAD_FUTURES_FUTURE_ERROR_HPP

#include <boost/thread/detail/config.hpp>

#include <boost/thread/futures/future_error_code.hpp>
#include <boost/system/error_code.hpp>

#include <stdexcept>

namespace boost
{
  class BOOST_SYMBOL_VISIBLE future_error
      : public std::logic_error
  {
      system::error_code ec_;
  public:
      future_error(system::error_code ec)
      : logic_error(ec.message()),
        ec_(ec)
      {
      }

      const system::error_code& code() const BOOST_NOEXCEPT
      {
        return ec_;
      }
  };

    class BOOST_SYMBOL_VISIBLE future_uninitialized:
        public future_error
    {
    public:
        future_uninitialized() :
          future_error(system::make_error_code(future_errc::no_state))
        {}
    };
    class BOOST_SYMBOL_VISIBLE broken_promise:
        public future_error
    {
    public:
        broken_promise():
          future_error(system::make_error_code(future_errc::broken_promise))
        {}
    };
    class BOOST_SYMBOL_VISIBLE future_already_retrieved:
        public future_error
    {
    public:
        future_already_retrieved():
          future_error(system::make_error_code(future_errc::future_already_retrieved))
        {}
    };
    class BOOST_SYMBOL_VISIBLE promise_already_satisfied:
        public future_error
    {
    public:
        promise_already_satisfied():
          future_error(system::make_error_code(future_errc::promise_already_satisfied))
        {}
    };

    class BOOST_SYMBOL_VISIBLE task_already_started:
        public future_error
    {
    public:
        task_already_started():
        future_error(system::make_error_code(future_errc::promise_already_satisfied))
        {}
    };

    class BOOST_SYMBOL_VISIBLE task_moved:
        public future_error
    {
    public:
        task_moved():
          future_error(system::make_error_code(future_errc::no_state))
        {}
    };

    class promise_moved:
        public future_error
    {
    public:
          promise_moved():
          future_error(system::make_error_code(future_errc::no_state))
        {}
    };
}

#endif // header

license: mit


code:
//  (C) Copyright 2008-10 Anthony Williams
//  (C) Copyright 2011-2012,2015 Vicente J. Botet Escriba
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_THREAD_FUTURES_FUTURE_ERROR_CODE_HPP
#define BOOST_THREAD_FUTURES_FUTURE_ERROR_CODE_HPP

#include <boost/thread/detail/config.hpp>
#include <boost/core/scoped_enum.hpp>
#include <boost/system/error_code.hpp>
#include <boost/type_traits/integral_constant.hpp>

namespace boost
{

  //enum class future_errc
  BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
  {
      broken_promise = 1,
      future_already_retrieved,
      promise_already_satisfied,
      no_state
  }
  BOOST_SCOPED_ENUM_DECLARE_END(future_errc)

  namespace system
  {
    template <>
    struct BOOST_SYMBOL_VISIBLE is_error_code_enum< ::boost::future_errc> : public true_type {};

    #ifdef BOOST_NO_CXX11_SCOPED_ENUMS
    template <>
    struct BOOST_SYMBOL_VISIBLE is_error_code_enum< ::boost::future_errc::enum_type> : public true_type { };
    #endif
  } // system

  BOOST_THREAD_DECL
  const system::error_category& future_category() BOOST_NOEXCEPT;

  namespace system
  {
    inline
    error_code
    make_error_code(future_errc e) BOOST_NOEXCEPT
    {
        return error_code(underlying_cast<int>(e), boost::future_category());
    }

    inline
    error_condition
    make_error_condition(future_errc e) BOOST_NOEXCEPT
    {
        return error_condition(underlying_cast<int>(e), boost::future_category());
    }
  } // system
} // boost

#endif // header


code:
//  (C) Copyright 2008-10 Anthony Williams
//  (C) Copyright 2011-2015 Vicente J. Botet Escriba
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_THREAD_FUTURES_FUTURE_STATUS_HPP
#define BOOST_THREAD_FUTURES_FUTURE_STATUS_HPP

#include <boost/thread/detail/config.hpp>
#include <boost/core/scoped_enum.hpp>

namespace boost
{
  //enum class future_status
  BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_status)
  {
      ready,
      timeout,
      deferred
  }
  BOOST_SCOPED_ENUM_DECLARE_END(future_status)
  namespace future_state
  {
      enum state { uninitialized, waiting, ready, moved, deferred };
  }
}

#endif // header


code:
//  (C) Copyright 2008-10 Anthony Williams
//  (C) Copyright 2011-2015 Vicente J. Botet Escriba
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_THREAD_FUTURES_IS_FUTURE_TYPE_HPP
#define BOOST_THREAD_FUTURES_IS_FUTURE_TYPE_HPP

#include <boost/type_traits/integral_constant.hpp>

namespace boost
{
    template<typename T>
    struct is_future_type : false_type
    {
    };
}

#endif // header


code:
//  (C) Copyright 2008-10 Anthony Williams
//  (C) Copyright 2011-2015 Vicente J. Botet Escriba
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_THREAD_FUTURES_LAUNCH_HPP
#define BOOST_THREAD_FUTURES_LAUNCH_HPP

#include <boost/thread/detail/config.hpp>
#include <boost/core/scoped_enum.hpp>

namespace boost
{
  //enum class launch
  BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch)
  {
      none = 0,
      async = 1,
      deferred = 2,
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
      executor = 4,
#endif
      inherit = 8,
      sync = 16,
      any = async | deferred
  }
  BOOST_SCOPED_ENUM_DECLARE_END(launch)
}

#endif // header


code:
//  (C) Copyright 2008-10 Anthony Williams
//  (C) Copyright 2011-2015 Vicente J. Botet Escriba
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_THREAD_FUTURES_WAIT_FOR_ALL_HPP
#define BOOST_THREAD_FUTURES_WAIT_FOR_ALL_HPP

#include <boost/thread/detail/config.hpp>
#include <boost/thread/futures/is_future_type.hpp>

#include <boost/core/enable_if.hpp>

namespace boost
{
  template<typename Iterator>
  typename boost::disable_if<is_future_type<Iterator>,void>::type wait_for_all(Iterator begin,Iterator end)
  {
      for(Iterator current=begin;current!=end;++current)
      {
          current->wait();
      }
  }

#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
    template<typename F1,typename F2>
    typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1,F2& f2)
    {
        f1.wait();
        f2.wait();
    }

    template<typename F1,typename F2,typename F3>
    void wait_for_all(F1& f1,F2& f2,F3& f3)
    {
        f1.wait();
        f2.wait();
        f3.wait();
    }

    template<typename F1,typename F2,typename F3,typename F4>
    void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4)
    {
        f1.wait();
        f2.wait();
        f3.wait();
        f4.wait();
    }

    template<typename F1,typename F2,typename F3,typename F4,typename F5>
    void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
    {
        f1.wait();
        f2.wait();
        f3.wait();
        f4.wait();
        f5.wait();
    }
#else
    template<typename F1, typename... Fs>
    void wait_for_all(F1& f1, Fs&... fs)
    {
        bool dummy[] = { (f1.wait(), true), (fs.wait(), true)... };

        // prevent unused parameter warning
        (void) dummy;
    }
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)}

}

#endif // header


code:
//  (C) Copyright 2008-10 Anthony Williams
//  (C) Copyright 2011-2015 Vicente J. Botet Escriba
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_THREAD_FUTURES_WAIT_FOR_ANY_HPP
#define BOOST_THREAD_FUTURES_WAIT_FOR_ANY_HPP

#include <boost/thread/detail/config.hpp>

#include <boost/thread/detail/move.hpp>
#include <boost/thread/futures/is_future_type.hpp>
#include <boost/thread/lock_algorithms.hpp>
#include <boost/thread/mutex.hpp>

#include <boost/core/enable_if.hpp>
#include <boost/next_prior.hpp>
#include <boost/scoped_array.hpp>

#include <iterator>
#include <vector>

namespace boost
{
  namespace detail
  {
    template <class Future>
    class waiter_for_any_in_seq
    {
      struct registered_waiter;
      typedef std::vector<int>::size_type count_type;

      struct registered_waiter
      {
        typedef Future future_type;
        future_type* future_;
        typedef typename Future::notify_when_ready_handle notify_when_ready_handle;
        notify_when_ready_handle handle;
        count_type index;

        registered_waiter(future_type & a_future,
            notify_when_ready_handle handle_, count_type index_) :
          future_(&a_future), handle(handle_), index(index_)
        {
        }
      };

      struct all_futures_lock
      {
#ifdef _MANAGED
        typedef std::ptrdiff_t count_type_portable;
#else
        typedef count_type count_type_portable;
#endif
        count_type_portable count;
        boost::scoped_array<boost::unique_lock<boost::mutex> > locks;

        all_futures_lock(std::vector<registered_waiter>& waiters) :
          count(waiters.size()), locks(new boost::unique_lock<boost::mutex>[count])
        {
          for (count_type_portable i = 0; i < count; ++i)
          {
            locks[i] = BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(waiters[i].future_->mutex()));
          }
        }

        void lock()
        {
          boost::lock(locks.get(), locks.get() + count);
        }

        void unlock()
        {
          for (count_type_portable i = 0; i < count; ++i)
          {
            locks[i].unlock();
          }
        }
      };

      boost::condition_variable_any cv;
      std::vector<registered_waiter> waiters_;
      count_type future_count;

    public:
      waiter_for_any_in_seq() :
        future_count(0)
      {
      }

      template <typename F>
      void add(F& f)
      {
        if (f.valid())
        {
          registered_waiter waiter(f, f.notify_when_ready(cv), future_count);
          try
          {
            waiters_.push_back(waiter);
          }
          catch (...)
          {
            f.future_->unnotify_when_ready(waiter.handle);
            throw;
          }
          ++future_count;
        }
      }

#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
      template <typename F1, typename ... Fs>
      void add(F1& f1, Fs&... fs)
      {
        add(f1);
        add(fs...);
      }
#endif

      count_type wait()
      {
        all_futures_lock lk(waiters_);
        for (;;)
        {
          for (count_type i = 0; i < waiters_.size(); ++i)
          {
            if (waiters_[i].future_->is_ready(lk.locks[i]))
            {
              return waiters_[i].index;
            }
          }
          cv.wait(lk);
        }
      }

      ~waiter_for_any_in_seq()
      {
        for (count_type i = 0; i < waiters_.size(); ++i)
        {
          waiters_[i].future_->unnotify_when_ready(waiters_[i].handle);
        }
      }
    };
  }

  template <typename Iterator>
  typename boost::disable_if<is_future_type<Iterator> , Iterator>::type wait_for_any(Iterator begin, Iterator end)
  {
    if (begin == end) return end;

    detail::waiter_for_any_in_seq<typename std::iterator_traits<Iterator>::value_type> waiter;
    for (Iterator current = begin; current != end; ++current)
    {
      waiter.add(*current);
    }
    return boost::next(begin, waiter.wait());
  }
}

#endif // header


code:
// (C) Copyright 2012 Vicente J. Botet Escriba
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_THREAD_IS_LOCKED_BY_THIS_THREAD_HPP
#define BOOST_THREAD_IS_LOCKED_BY_THIS_THREAD_HPP

#include <boost/thread/detail/config.hpp>

#include <boost/config/abi_prefix.hpp>

namespace boost
{
  template <typename Lockable>
  class testable_mutex;

  /**
   * Overloaded function used to check if the mutex is locked when it is testable and do nothing otherwise.
   *
   * This function is used usually to assert the pre-condition when the function can only be called when the mutex
   * must be locked by the current thread.
   */
  template <typename Lockable>
  bool is_locked_by_this_thread(testable_mutex<Lockable> const& mtx)
  {
    return mtx.is_locked_by_this_thread();
  }
  template <typename Lockable>
  bool is_locked_by_this_thread(Lockable const&)
  {
    return true;
  }
}

#include <boost/config/abi_suffix.hpp>

#endif // header


code:
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba

#ifndef BOOST_THREAD_LOCK_ALGORITHMS_HPP
#define BOOST_THREAD_LOCK_ALGORITHMS_HPP

#include <boost/thread/detail/config.hpp>
#include <boost/thread/lock_types.hpp>
#include <boost/thread/lockable_traits.hpp>

#include <algorithm>
#include <iterator>

#include <boost/config/abi_prefix.hpp>

namespace boost
{
  namespace detail
  {
    template <typename MutexType1, typename MutexType2>
    unsigned try_lock_internal(MutexType1& m1, MutexType2& m2)
    {
      boost::unique_lock<MutexType1> l1(m1, boost::try_to_lock);
      if (!l1)
      {
        return 1;
      }
      if (!m2.try_lock())
      {
        return 2;
      }
      l1.release();
      return 0;
    }

    template <typename MutexType1, typename MutexType2, typename MutexType3>
    unsigned try_lock_internal(MutexType1& m1, MutexType2& m2, MutexType3& m3)
    {
      boost::unique_lock<MutexType1> l1(m1, boost::try_to_lock);
      if (!l1)
      {
        return 1;
      }
      if (unsigned const failed_lock=try_lock_internal(m2,m3))
      {
        return failed_lock + 1;
      }
      l1.release();
      return 0;
    }

    template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4>
    unsigned try_lock_internal(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4)
    {
      boost::unique_lock<MutexType1> l1(m1, boost::try_to_lock);
      if (!l1)
      {
        return 1;
      }
      if (unsigned const failed_lock=try_lock_internal(m2,m3,m4))
      {
        return failed_lock + 1;
      }
      l1.release();
      return 0;
    }

    template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4, typename MutexType5>
    unsigned try_lock_internal(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4, MutexType5& m5)
    {
      boost::unique_lock<MutexType1> l1(m1, boost::try_to_lock);
      if (!l1)
      {
        return 1;
      }
      if (unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5))
      {
        return failed_lock + 1;
      }
      l1.release();
      return 0;
    }

    template <typename MutexType1, typename MutexType2>
    unsigned lock_helper(MutexType1& m1, MutexType2& m2)
    {
      boost::unique_lock<MutexType1> l1(m1);
      if (!m2.try_lock())
      {
        return 1;
      }
      l1.release();
      return 0;
    }

    template <typename MutexType1, typename MutexType2, typename MutexType3>
    unsigned lock_helper(MutexType1& m1, MutexType2& m2, MutexType3& m3)
    {
      boost::unique_lock<MutexType1> l1(m1);
      if (unsigned const failed_lock=try_lock_internal(m2,m3))
      {
        return failed_lock;
      }
      l1.release();
      return 0;
    }

    template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4>
    unsigned lock_helper(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4)
    {
      boost::unique_lock<MutexType1> l1(m1);
      if (unsigned const failed_lock=try_lock_internal(m2,m3,m4))
      {
        return failed_lock;
      }
      l1.release();
      return 0;
    }

    template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4, typename MutexType5>
    unsigned lock_helper(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4, MutexType5& m5)
    {
      boost::unique_lock<MutexType1> l1(m1);
      if (unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5))
      {
        return failed_lock;
      }
      l1.release();
      return 0;
    }
  }

  namespace detail
  {
    template <bool x>
    struct is_mutex_type_wrapper
    {
    };

    template <typename MutexType1, typename MutexType2>
    void lock_impl(MutexType1& m1, MutexType2& m2, is_mutex_type_wrapper<true> )
    {
      unsigned const lock_count = 2;
      unsigned lock_first = 0;
      for (;;)
      {
        switch (lock_first)
        {
        case 0:
          lock_first = detail::lock_helper(m1, m2);
          if (!lock_first) return;
          break;
        case 1:
          lock_first = detail::lock_helper(m2, m1);
          if (!lock_first) return;
          lock_first = (lock_first + 1) % lock_count;
          break;
        }
      }
    }

    template <typename Iterator>
    void lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper<false> );
  }

  template <typename MutexType1, typename MutexType2>
  void lock(MutexType1& m1, MutexType2& m2)
  {
    detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
  }

  template <typename MutexType1, typename MutexType2>
  void lock(const MutexType1& m1, MutexType2& m2)
  {
    detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
  }

  template <typename MutexType1, typename MutexType2>
  void lock(MutexType1& m1, const MutexType2& m2)
  {
    detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
  }

  template <typename MutexType1, typename MutexType2>
  void lock(const MutexType1& m1, const MutexType2& m2)
  {
    detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
  }

  template <typename MutexType1, typename MutexType2, typename MutexType3>
  void lock(MutexType1& m1, MutexType2& m2, MutexType3& m3)
  {
    unsigned const lock_count = 3;
    unsigned lock_first = 0;
    for (;;)
    {
      switch (lock_first)
      {
      case 0:
        lock_first = detail::lock_helper(m1, m2, m3);
        if (!lock_first) return;
        break;
      case 1:
        lock_first = detail::lock_helper(m2, m3, m1);
        if (!lock_first) return;
        lock_first = (lock_first + 1) % lock_count;
        break;
      case 2:
        lock_first = detail::lock_helper(m3, m1, m2);
        if (!lock_first) return;
        lock_first = (lock_first + 2) % lock_count;
        break;
      }
    }
  }

  template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4>
  void lock(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4)
  {
    unsigned const lock_count = 4;
    unsigned lock_first = 0;
    for (;;)
    {
      switch (lock_first)
      {
      case 0:
        lock_first = detail::lock_helper(m1, m2, m3, m4);
        if (!lock_first) return;
        break;
      case 1:
        lock_first = detail::lock_helper(m2, m3, m4, m1);
        if (!lock_first) return;
        lock_first = (lock_first + 1) % lock_count;
        break;
      case 2:
        lock_first = detail::lock_helper(m3, m4, m1, m2);
        if (!lock_first) return;
        lock_first = (lock_first + 2) % lock_count;
        break;
      case 3:
        lock_first = detail::lock_helper(m4, m1, m2, m3);
        if (!lock_first) return;
        lock_first = (lock_first + 3) % lock_count;
        break;
      }
    }
  }

  template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4, typename MutexType5>
  void lock(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4, MutexType5& m5)
  {
    unsigned const lock_count = 5;
    unsigned lock_first = 0;
    for (;;)
    {
      switch (lock_first)
      {
      case 0:
        lock_first = detail::lock_helper(m1, m2, m3, m4, m5);
        if (!lock_first) return;
        break;
      case 1:
        lock_first = detail::lock_helper(m2, m3, m4, m5, m1);
        if (!lock_first) return;
        lock_first = (lock_first + 1) % lock_count;
        break;
      case 2:
        lock_first = detail::lock_helper(m3, m4, m5, m1, m2);
        if (!lock_first) return;
        lock_first = (lock_first + 2) % lock_count;
        break;
      case 3:
        lock_first = detail::lock_helper(m4, m5, m1, m2, m3);
        if (!lock_first) return;
        lock_first = (lock_first + 3) % lock_count;
        break;
      case 4:
        lock_first = detail::lock_helper(m5, m1, m2, m3, m4);
        if (!lock_first) return;
        lock_first = (lock_first + 4) % lock_count;
        break;
      }
    }
  }

  namespace detail
  {
    template <typename Mutex, bool x = is_mutex_type<Mutex>::value>
    struct try_lock_impl_return
    {
      typedef int type;
    };

    template <typename Iterator>
    struct try_lock_impl_return<Iterator, false>
    {
      typedef Iterator type;
    };

    template <typename MutexType1, typename MutexType2>
    int try_lock_impl(MutexType1& m1, MutexType2& m2, is_mutex_type_wrapper<true> )
    {
      return ((int) detail::try_lock_internal(m1, m2)) - 1;
    }

    template <typename Iterator>
    Iterator try_lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper<false> );
  }

  template <typename MutexType1, typename MutexType2>
  typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1, MutexType2& m2)
  {
    return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
  }

  template <typename MutexType1, typename MutexType2>
  typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1, MutexType2& m2)
  {
    return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
  }

  template <typename MutexType1, typename MutexType2>
  typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1, const MutexType2& m2)
  {
    return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
  }

  template <typename MutexType1, typename MutexType2>
  typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1, const MutexType2& m2)
  {
    return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
  }

  template <typename MutexType1, typename MutexType2, typename MutexType3>
  int try_lock(MutexType1& m1, MutexType2& m2, MutexType3& m3)
  {
    return ((int) detail::try_lock_internal(m1, m2, m3)) - 1;
  }

  template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4>
  int try_lock(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4)
  {
    return ((int) detail::try_lock_internal(m1, m2, m3, m4)) - 1;
  }

  template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4, typename MutexType5>
  int try_lock(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4, MutexType5& m5)
  {
    return ((int) detail::try_lock_internal(m1, m2, m3, m4, m5)) - 1;
  }

  namespace detail
  {
    template <typename Iterator>
    struct range_lock_guard
    {
      Iterator begin;
      Iterator end;

      range_lock_guard(Iterator begin_, Iterator end_) :
        begin(begin_), end(end_)
      {
        boost::lock(begin, end);
      }

      void release()
      {
        begin = end;
      }

      ~range_lock_guard()
      {
        for (; begin != end; ++begin)
        {
          begin->unlock();
        }
      }
    };

    template <typename Iterator>
    Iterator try_lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper<false> )

    {
      if (begin == end)
      {
        return end;
      }
      typedef typename std::iterator_traits<Iterator>::value_type lock_type;
      unique_lock<lock_type> guard(*begin, try_to_lock);

      if (!guard.owns_lock())
      {
        return begin;
      }
      Iterator const failed = boost::try_lock(++begin, end);
      if (failed == end)
      {
        guard.release();
      }

      return failed;
    }
  }

  namespace detail
  {
    template <typename Iterator>
    void lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper<false> )
    {
      typedef typename std::iterator_traits<Iterator>::value_type lock_type;

      if (begin == end)
      {
        return;
      }
      bool start_with_begin = true;
      Iterator second = begin;
      ++second;
      Iterator next = second;

      for (;;)
      {
        unique_lock<lock_type> begin_lock(*begin, defer_lock);
        if (start_with_begin)
        {
          begin_lock.lock();
          Iterator const failed_lock = boost::try_lock(next, end);
          if (failed_lock == end)
          {
            begin_lock.release();
            return;
          }
          start_with_begin = false;
          next = failed_lock;
        }
        else
        {
          detail::range_lock_guard<Iterator> guard(next, end);
          if (begin_lock.try_lock())
          {
            Iterator const failed_lock = boost::try_lock(second, next);
            if (failed_lock == next)
            {
              begin_lock.release();
              guard.release();
              return;
            }
            start_with_begin = false;
            next = failed_lock;
          }
          else
          {
            start_with_begin = true;
            next = second;
          }
        }
      }
    }

  }

}
#include <boost/config/abi_suffix.hpp>

#endif


code:
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba

#ifndef BOOST_THREAD_LOCK_GUARD_HPP
#define BOOST_THREAD_LOCK_GUARD_HPP

#include <boost/thread/detail/config.hpp>
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/detail/lockable_wrapper.hpp>
#include <boost/thread/lock_options.hpp>
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
#include <boost/thread/is_locked_by_this_thread.hpp>
#include <boost/assert.hpp>
#endif

#include <boost/config/abi_prefix.hpp>

namespace boost
{

  template <typename Mutex>
  class lock_guard
  {
  private:
    Mutex& m;

  public:
    typedef Mutex mutex_type;
    BOOST_THREAD_NO_COPYABLE( lock_guard )

    explicit lock_guard(Mutex& m_) :
      m(m_)
    {
      m.lock();
    }

    lock_guard(Mutex& m_, adopt_lock_t) :
      m(m_)
    {
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
      BOOST_ASSERT(is_locked_by_this_thread(m));
#endif
    }

#if ! defined BOOST_THREAD_NO_CXX11_HDR_INITIALIZER_LIST
    lock_guard(std::initializer_list<thread_detail::lockable_wrapper<Mutex> > l_) :
      m(*(const_cast<thread_detail::lockable_wrapper<Mutex>*>(l_.begin())->m))
    {
      m.lock();
    }

    lock_guard(std::initializer_list<thread_detail::lockable_adopt_wrapper<Mutex> > l_) :
      m(*(const_cast<thread_detail::lockable_adopt_wrapper<Mutex>*>(l_.begin())->m))
    {
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
      BOOST_ASSERT(is_locked_by_this_thread(m));
#endif
    }

#endif
    ~lock_guard()
    {
      m.unlock();
    }
  };

#if ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD
  template <typename Lockable>
  lock_guard<Lockable> make_lock_guard(Lockable& mtx)
  {
    return { thread_detail::lockable_wrapper<Lockable>(mtx) };
  }
  template <typename Lockable>
  lock_guard<Lockable> make_lock_guard(Lockable& mtx, adopt_lock_t)
  {
    return { thread_detail::lockable_adopt_wrapper<Lockable>(mtx) };
  }
#endif
}

#include <boost/config/abi_suffix.hpp>

#endif


code:
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba

#ifndef BOOST_THREAD_LOCK_OPTIONS_HPP
#define BOOST_THREAD_LOCK_OPTIONS_HPP

#include <boost/config/abi_prefix.hpp>

namespace boost
{
  struct defer_lock_t
  {
  };
  struct try_to_lock_t
  {
  };
  struct adopt_lock_t
  {
  };

  BOOST_CONSTEXPR_OR_CONST defer_lock_t defer_lock = {};
  BOOST_CONSTEXPR_OR_CONST try_to_lock_t try_to_lock = {};
  BOOST_CONSTEXPR_OR_CONST adopt_lock_t adopt_lock = {};

}
#include <boost/config/abi_suffix.hpp>

#endif


code:
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba

#ifndef BOOST_THREAD_LOCK_TYPES_HPP
#define BOOST_THREAD_LOCK_TYPES_HPP

#include <boost/thread/detail/config.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/lock_options.hpp>
#include <boost/thread/lockable_traits.hpp>
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
#include <boost/thread/is_locked_by_this_thread.hpp>
#endif
#include <boost/thread/thread_time.hpp>

#include <boost/assert.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/time_point.hpp>
#include <boost/chrono/duration.hpp>
#endif
#include <boost/detail/workaround.hpp>

#include <boost/config/abi_prefix.hpp>

namespace boost
{
  struct xtime;

  template <typename Mutex>
  class shared_lock;

  template <typename Mutex>
  class upgrade_lock;

  template <typename Mutex>
  class unique_lock;

  namespace detail
  {
    template <typename Mutex>
    class try_lock_wrapper;
  }

#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
  namespace sync
  {
    template<typename T>
    struct is_basic_lockable<unique_lock<T> >
    {
      BOOST_STATIC_CONSTANT(bool, value = true);
    };
    template<typename T>
    struct is_lockable<unique_lock<T> >
    {
      BOOST_STATIC_CONSTANT(bool, value = true);
    };

    template<typename T>
    struct is_basic_lockable<shared_lock<T> >
    {
      BOOST_STATIC_CONSTANT(bool, value = true);
    };
    template<typename T>
    struct is_lockable<shared_lock<T> >
    {
      BOOST_STATIC_CONSTANT(bool, value = true);
    };

    template<typename T>
    struct is_basic_lockable<upgrade_lock<T> >
    {
      BOOST_STATIC_CONSTANT(bool, value = true);
    };
    template<typename T>
    struct is_lockable<upgrade_lock<T> >
    {
      BOOST_STATIC_CONSTANT(bool, value = true);
    };

    template<typename T>
    struct is_basic_lockable<detail::try_lock_wrapper<T> >
    {
      BOOST_STATIC_CONSTANT(bool, value = true);
    };
    template<typename T>
    struct is_lockable<detail::try_lock_wrapper<T> >
    {
      BOOST_STATIC_CONSTANT(bool, value = true);
    };
  }
#endif

  template <typename Mutex>
  class unique_lock
  {
  private:
    Mutex* m;
    bool is_locked;

  private:
    explicit unique_lock(upgrade_lock<Mutex>&);
    unique_lock& operator=(upgrade_lock<Mutex>& other);
  public:
    typedef Mutex mutex_type;
    BOOST_THREAD_MOVABLE_ONLY( unique_lock)

#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
    unique_lock(const volatile unique_lock&);
#endif
#endif
    unique_lock()BOOST_NOEXCEPT :
    m(0),is_locked(false)
    {}

    explicit unique_lock(Mutex& m_) :
      m(&m_), is_locked(false)
    {
      lock();
    }
    unique_lock(Mutex& m_, adopt_lock_t) :
      m(&m_), is_locked(true)
    {
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
      BOOST_ASSERT(is_locked_by_this_thread(m));
#endif
    }
    unique_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
    m(&m_),is_locked(false)
    {}
    unique_lock(Mutex& m_, try_to_lock_t) :
      m(&m_), is_locked(false)
    {
      try_lock();
    }
#if defined BOOST_THREAD_USES_DATETIME
    template<typename TimeDuration>
    unique_lock(Mutex& m_,TimeDuration const& target_time):
    m(&m_),is_locked(false)
    {
      timed_lock(target_time);
    }
    unique_lock(Mutex& m_,system_time const& target_time):
    m(&m_),is_locked(false)
    {
      timed_lock(target_time);
    }
#endif
#ifdef BOOST_THREAD_USES_CHRONO
    template <class Clock, class Duration>
    unique_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
    : m(&mtx), is_locked(mtx.try_lock_until(t))
    {
    }
    template <class Rep, class Period>
    unique_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
    : m(&mtx), is_locked(mtx.try_lock_for(d))
    {
    }
#endif

    unique_lock(BOOST_THREAD_RV_REF(unique_lock) other) BOOST_NOEXCEPT:
    m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
    {
      BOOST_THREAD_RV(other).is_locked=false;
      BOOST_THREAD_RV(other).m=0;
    }

    BOOST_THREAD_EXPLICIT_LOCK_CONVERSION unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other);

#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
    //std-2104 unique_lock move-assignment should not be noexcept
    unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
    {
      unique_lock temp(::boost::move(other));
      swap(temp);
      return *this;
    }
#endif

    //std-2104 unique_lock move-assignment should not be noexcept
    unique_lock& operator=(BOOST_THREAD_RV_REF(unique_lock) other) //BOOST_NOEXCEPT
    {
      unique_lock temp(::boost::move(other));
      swap(temp);
      return *this;
    }
#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
    unique_lock& operator=(unique_lock<Mutex> other)
    {
      swap(other);
      return *this;
    }
#endif // BOOST_WORKAROUND
#endif

    // Conversion from upgrade locking
    unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, try_to_lock_t)
    : m(0),is_locked(false)
    {
      if (BOOST_THREAD_RV(ul).owns_lock())
      {
        if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock())
        {
          m = BOOST_THREAD_RV(ul).release();
          is_locked = true;
        }
      }
      else
      {
        m = BOOST_THREAD_RV(ul).release();
      }
    }

#ifdef BOOST_THREAD_USES_CHRONO
    template <class Clock, class Duration>
    unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,
        const chrono::time_point<Clock, Duration>& abs_time)
    : m(0),is_locked(false)
    {
      if (BOOST_THREAD_RV(ul).owns_lock())
      {
        if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_until(abs_time))
        {
          m = BOOST_THREAD_RV(ul).release();
          is_locked = true;
        }
      }
      else
      {
        m = BOOST_THREAD_RV(ul).release();
      }
    }

    template <class Rep, class Period>
    unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,
        const chrono::duration<Rep, Period>& rel_time)
    : m(0),is_locked(false)
    {
      if (BOOST_THREAD_RV(ul).owns_lock())
      {
        if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_for(rel_time))
        {
          m = BOOST_THREAD_RV(ul).release();
          is_locked = true;
        }
      }
      else
      {
        m = BOOST_THREAD_RV(ul).release();
      }
    }
#endif

#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
    // Conversion from shared locking
    unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t)
    : m(0),is_locked(false)
    {
      if (BOOST_THREAD_RV(sl).owns_lock())
      {
        if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock())
        {
          m = BOOST_THREAD_RV(sl).release();
          is_locked = true;
        }
      }
      else
      {
        m = BOOST_THREAD_RV(sl).release();
      }
    }

#ifdef BOOST_THREAD_USES_CHRONO
    template <class Clock, class Duration>
    unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
        const chrono::time_point<Clock, Duration>& abs_time)
    : m(0),is_locked(false)
    {
      if (BOOST_THREAD_RV(sl).owns_lock())
      {
        if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_until(abs_time))
        {
          m = BOOST_THREAD_RV(sl).release();
          is_locked = true;
        }
      }
      else
      {
        m = BOOST_THREAD_RV(sl).release();
      }
    }

    template <class Rep, class Period>
    unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
        const chrono::duration<Rep, Period>& rel_time)
    : m(0),is_locked(false)
    {
      if (BOOST_THREAD_RV(sl).owns_lock())
      {
        if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_for(rel_time))
        {
          m = BOOST_THREAD_RV(sl).release();
          is_locked = true;
        }
      }
      else
      {
        m = BOOST_THREAD_RV(sl).release();
      }
    }
#endif // BOOST_THREAD_USES_CHRONO
#endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS

    void swap(unique_lock& other)BOOST_NOEXCEPT
    {
      std::swap(m,other.m);
      std::swap(is_locked,other.is_locked);
    }

    ~unique_lock()
    {
      if (owns_lock())
      {
        m->unlock();
      }
    }
    void lock()
    {
      if (m == 0)
      {
        boost::throw_exception(
            boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
      }
      if (owns_lock())
      {
        boost::throw_exception(
            boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
      }
      m->lock();
      is_locked = true;
    }
    bool try_lock()
    {
      if (m == 0)
      {
        boost::throw_exception(
            boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
      }
      if (owns_lock())
      {
        boost::throw_exception(
            boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
      }
      is_locked = m->try_lock();
      return is_locked;
    }
#if defined BOOST_THREAD_USES_DATETIME
    template<typename TimeDuration>
    bool timed_lock(TimeDuration const& relative_time)
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
      }
      if(owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
      }
      is_locked=m->timed_lock(relative_time);
      return is_locked;
    }

    bool timed_lock(::boost::system_time const& absolute_time)
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
      }
      if(owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
      }
      is_locked=m->timed_lock(absolute_time);
      return is_locked;
    }
    bool timed_lock(::boost::xtime const& absolute_time)
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
      }
      if(owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
      }
      is_locked=m->timed_lock(absolute_time);
      return is_locked;
    }
#endif
#ifdef BOOST_THREAD_USES_CHRONO

    template <class Rep, class Period>
    bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
      }
      if(owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
      }
      is_locked=m->try_lock_for(rel_time);
      return is_locked;
    }
    template <class Clock, class Duration>
    bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
      }
      if(owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
      }
      is_locked=m->try_lock_until(abs_time);
      return is_locked;
    }
#endif

    void unlock()
    {
      if (m == 0)
      {
        boost::throw_exception(
            boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
      }
      if (!owns_lock())
      {
        boost::throw_exception(
            boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock doesn't own the mutex"));
      }
      m->unlock();
      is_locked = false;
    }

#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
    typedef void (unique_lock::*bool_type)();
    operator bool_type() const BOOST_NOEXCEPT
    {
      return is_locked?&unique_lock::lock:0;
    }
    bool operator!() const BOOST_NOEXCEPT
    {
      return !owns_lock();
    }
#else
    explicit operator bool() const BOOST_NOEXCEPT
    {
      return owns_lock();
    }
#endif
    bool owns_lock() const BOOST_NOEXCEPT
    {
      return is_locked;
    }

    Mutex* mutex() const BOOST_NOEXCEPT
    {
      return m;
    }

    Mutex* release()BOOST_NOEXCEPT
    {
      Mutex* const res=m;
      m=0;
      is_locked=false;
      return res;
    }

    friend class shared_lock<Mutex> ;
    friend class upgrade_lock<Mutex> ;
  };

  template<typename Mutex>
  void swap(unique_lock<Mutex>& lhs, unique_lock<Mutex>& rhs)
  BOOST_NOEXCEPT
  {
    lhs.swap(rhs);
  }

  BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END

  template<typename Mutex>
  class shared_lock
  {
  protected:
    Mutex* m;
    bool is_locked;

  public:
    typedef Mutex mutex_type;
    BOOST_THREAD_MOVABLE_ONLY(shared_lock)

    shared_lock() BOOST_NOEXCEPT:
    m(0),is_locked(false)
    {}

    explicit shared_lock(Mutex& m_):
    m(&m_),is_locked(false)
    {
      lock();
    }
    shared_lock(Mutex& m_,adopt_lock_t):
    m(&m_),is_locked(true)
    {
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
      BOOST_ASSERT(is_locked_by_this_thread(m));
#endif
    }
    shared_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:
    m(&m_),is_locked(false)
    {}
    shared_lock(Mutex& m_,try_to_lock_t):
    m(&m_),is_locked(false)
    {
      try_lock();
    }
#if defined BOOST_THREAD_USES_DATETIME
    shared_lock(Mutex& m_,system_time const& target_time):
    m(&m_),is_locked(false)
    {
      timed_lock(target_time);
    }
#endif
#ifdef BOOST_THREAD_USES_CHRONO
    template <class Clock, class Duration>
    shared_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
    : m(&mtx), is_locked(mtx.try_lock_shared_until(t))
    {
    }
    template <class Rep, class Period>
    shared_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
    : m(&mtx), is_locked(mtx.try_lock_shared_for(d))
    {
    }
#endif

    shared_lock(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
    m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
    {
      BOOST_THREAD_RV(other).is_locked=false;
      BOOST_THREAD_RV(other).m=0;
    }

    BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other):
    m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
    {
      if(is_locked)
      {
        m->unlock_and_lock_shared();
      }
      BOOST_THREAD_RV(other).is_locked=false;
      BOOST_THREAD_RV(other).m=0;
    }

    BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other):
    m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
    {
      if(is_locked)
      {
        m->unlock_upgrade_and_lock_shared();
      }
      BOOST_THREAD_RV(other).is_locked=false;
      BOOST_THREAD_RV(other).m=0;
    }

    //std-2104 unique_lock move-assignment should not be noexcept
    shared_lock& operator=(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
    {
      shared_lock temp(::boost::move(other));
      swap(temp);
      return *this;
    }
#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
    shared_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)
    {
      shared_lock temp(::boost::move(other));
      swap(temp);
      return *this;
    }

    shared_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)
    {
      shared_lock temp(::boost::move(other));
      swap(temp);
      return *this;
    }
#endif

    void swap(shared_lock& other) BOOST_NOEXCEPT
    {
      std::swap(m,other.m);
      std::swap(is_locked,other.is_locked);
    }

    Mutex* mutex() const BOOST_NOEXCEPT
    {
      return m;
    }

    Mutex* release() BOOST_NOEXCEPT
    {
      Mutex* const res=m;
      m=0;
      is_locked=false;
      return res;
    }

    ~shared_lock()
    {
      if(owns_lock())
      {
        m->unlock_shared();
      }
    }
    void lock()
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
      }
      if(owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
      }
      m->lock_shared();
      is_locked=true;
    }
    bool try_lock()
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
      }
      if(owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
      }
      is_locked=m->try_lock_shared();
      return is_locked;
    }
#if defined BOOST_THREAD_USES_DATETIME
    bool timed_lock(boost::system_time const& target_time)
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
      }
      if(owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
      }
      is_locked=m->timed_lock_shared(target_time);
      return is_locked;
    }
    template<typename Duration>
    bool timed_lock(Duration const& target_time)
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
      }
      if(owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
      }
      is_locked=m->timed_lock_shared(target_time);
      return is_locked;
    }
#endif
#ifdef BOOST_THREAD_USES_CHRONO
    template <class Rep, class Period>
    bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
      }
      if(owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
      }
      is_locked=m->try_lock_shared_for(rel_time);
      return is_locked;
    }
    template <class Clock, class Duration>
    bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
      }
      if(owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
      }
      is_locked=m->try_lock_shared_until(abs_time);
      return is_locked;
    }
#endif
    void unlock()
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
      }
      if(!owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock doesn't own the mutex"));
      }
      m->unlock_shared();
      is_locked=false;
    }

#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
    typedef void (shared_lock<Mutex>::*bool_type)();
    operator bool_type() const BOOST_NOEXCEPT
    {
      return is_locked?&shared_lock::lock:0;
    }
    bool operator!() const BOOST_NOEXCEPT
    {
      return !owns_lock();
    }
#else
    explicit operator bool() const BOOST_NOEXCEPT
    {
      return owns_lock();
    }
#endif
    bool owns_lock() const BOOST_NOEXCEPT
    {
      return is_locked;
    }

  };

  BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) shared_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END

  template<typename Mutex>
  void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) BOOST_NOEXCEPT
  {
    lhs.swap(rhs);
  }

  template <typename Mutex>
  class upgrade_lock
  {
  protected:
    Mutex* m;
    bool is_locked;

  public:
    typedef Mutex mutex_type;
    BOOST_THREAD_MOVABLE_ONLY( upgrade_lock)

    upgrade_lock()BOOST_NOEXCEPT:
    m(0),is_locked(false)
    {}

    explicit upgrade_lock(Mutex& m_) :
      m(&m_), is_locked(false)
    {
      lock();
    }
    upgrade_lock(Mutex& m_, adopt_lock_t) :
      m(&m_), is_locked(true)
    {
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
      BOOST_ASSERT(is_locked_by_this_thread(m));
#endif
    }
    upgrade_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
    m(&m_),is_locked(false)
    {}
    upgrade_lock(Mutex& m_, try_to_lock_t) :
      m(&m_), is_locked(false)
    {
      try_lock();
    }

#ifdef BOOST_THREAD_USES_CHRONO
    template <class Clock, class Duration>
    upgrade_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
    : m(&mtx), is_locked(mtx.try_lock_upgrade_until(t))
    {
    }
    template <class Rep, class Period>
    upgrade_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
    : m(&mtx), is_locked(mtx.try_lock_upgrade_for(d))
    {
    }
#endif

    upgrade_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
    m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
    {
      BOOST_THREAD_RV(other).is_locked=false;
      BOOST_THREAD_RV(other).m=0;
    }

    BOOST_THREAD_EXPLICIT_LOCK_CONVERSION upgrade_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other):
    m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
    {
      if(is_locked)
      {
        m->unlock_and_lock_upgrade();
      }
      BOOST_THREAD_RV(other).is_locked=false;
      BOOST_THREAD_RV(other).m=0;
    }

    //std-2104 unique_lock move-assignment should not be noexcept
    upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
    {
      upgrade_lock temp(::boost::move(other));
      swap(temp);
      return *this;
    }

#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
    upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)
    {
      upgrade_lock temp(::boost::move(other));
      swap(temp);
      return *this;
    }
#endif

#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
    // Conversion from shared locking
    upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t)
    : m(0),is_locked(false)
    {
      if (BOOST_THREAD_RV(sl).owns_lock())
      {
        if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade())
        {
          m = BOOST_THREAD_RV(sl).release();
          is_locked = true;
        }
      }
      else
      {
        m = BOOST_THREAD_RV(sl).release();
      }
    }

#ifdef BOOST_THREAD_USES_CHRONO
    template <class Clock, class Duration>
    upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
        const chrono::time_point<Clock, Duration>& abs_time)
    : m(0),is_locked(false)
    {
      if (BOOST_THREAD_RV(sl).owns_lock())
      {
        if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time))
        {
          m = BOOST_THREAD_RV(sl).release();
          is_locked = true;
        }
      }
      else
      {
        m = BOOST_THREAD_RV(sl).release();
      }
    }

    template <class Rep, class Period>
    upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
        const chrono::duration<Rep, Period>& rel_time)
    : m(0),is_locked(false)
    {
      if (BOOST_THREAD_RV(sl).owns_lock())
      {
        if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time))
        {
          m = BOOST_THREAD_RV(sl).release();
          is_locked = true;
        }
      }
      else
      {
        m = BOOST_THREAD_RV(sl).release();
      }
    }
#endif // BOOST_THREAD_USES_CHRONO
#endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
    void swap(upgrade_lock& other)BOOST_NOEXCEPT
    {
      std::swap(m,other.m);
      std::swap(is_locked,other.is_locked);
    }
    Mutex* mutex() const BOOST_NOEXCEPT
    {
      return m;
    }

    Mutex* release()BOOST_NOEXCEPT
    {
      Mutex* const res=m;
      m=0;
      is_locked=false;
      return res;
    }
    ~upgrade_lock()
    {
      if (owns_lock())
      {
        m->unlock_upgrade();
      }
    }
    void lock()
    {
      if (m == 0)
      {
        boost::throw_exception(
            boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
      }
      if (owns_lock())
      {
        boost::throw_exception(
            boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
      }
      m->lock_upgrade();
      is_locked = true;
    }
    bool try_lock()
    {
      if (m == 0)
      {
        boost::throw_exception(
            boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
      }
      if (owns_lock())
      {
        boost::throw_exception(
            boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
      }
      is_locked = m->try_lock_upgrade();
      return is_locked;
    }
    void unlock()
    {
      if (m == 0)
      {
        boost::throw_exception(
            boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
      }
      if (!owns_lock())
      {
        boost::throw_exception(
            boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock doesn't own the mutex"));
      }
      m->unlock_upgrade();
      is_locked = false;
    }
#ifdef BOOST_THREAD_USES_CHRONO
    template <class Rep, class Period>
    bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
      }
      if(owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
      }
      is_locked=m->try_lock_upgrade_for(rel_time);
      return is_locked;
    }
    template <class Clock, class Duration>
    bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
    {
      if(m==0)
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
      }
      if(owns_lock())
      {
        boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
      }
      is_locked=m->try_lock_upgrade_until(abs_time);
      return is_locked;
    }
#endif
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
    typedef void (upgrade_lock::*bool_type)();
    operator bool_type() const BOOST_NOEXCEPT
    {
      return is_locked?&upgrade_lock::lock:0;
    }
    bool operator!() const BOOST_NOEXCEPT
    {
      return !owns_lock();
    }
#else
    explicit operator bool() const BOOST_NOEXCEPT
    {
      return owns_lock();
    }
#endif
    bool owns_lock() const BOOST_NOEXCEPT
    {
      return is_locked;
    }
    friend class shared_lock<Mutex> ;
    friend class unique_lock<Mutex> ;
  };

  template<typename Mutex>
  void swap(upgrade_lock<Mutex>& lhs, upgrade_lock<Mutex>& rhs)
  BOOST_NOEXCEPT
  {
    lhs.swap(rhs);
  }

  BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END

  template<typename Mutex>
  unique_lock<Mutex>::unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other):
  m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
  {
    if(is_locked)
    {
      m->unlock_upgrade_and_lock();
    }
    BOOST_THREAD_RV(other).release();
  }

  template <class Mutex>
  class upgrade_to_unique_lock
  {
  private:
    upgrade_lock<Mutex>* source;
    unique_lock<Mutex> exclusive;

  public:
    typedef Mutex mutex_type;
    BOOST_THREAD_MOVABLE_ONLY( upgrade_to_unique_lock)

    explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_) :
      source(&m_), exclusive(::boost::move(*source))
    {
    }
    ~upgrade_to_unique_lock()
    {
      if (source)
      {
        *source = BOOST_THREAD_MAKE_RV_REF(upgrade_lock<Mutex> (::boost::move(exclusive)));
      }
    }

    upgrade_to_unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
    source(BOOST_THREAD_RV(other).source),exclusive(::boost::move(BOOST_THREAD_RV(other).exclusive))
    {
      BOOST_THREAD_RV(other).source=0;
    }

    //std-2104 unique_lock move-assignment should not be noexcept
    upgrade_to_unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
    {
      upgrade_to_unique_lock temp(::boost::move(other));
      swap(temp);
      return *this;
    }

    void swap(upgrade_to_unique_lock& other)BOOST_NOEXCEPT
    {
      std::swap(source,other.source);
      exclusive.swap(other.exclusive);
    }

#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
    typedef void (upgrade_to_unique_lock::*bool_type)(upgrade_to_unique_lock&);
    operator bool_type() const BOOST_NOEXCEPT
    {
      return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0;
    }
    bool operator!() const BOOST_NOEXCEPT
    {
      return !owns_lock();
    }
#else
    explicit operator bool() const BOOST_NOEXCEPT
    {
      return owns_lock();
    }
#endif

    bool owns_lock() const BOOST_NOEXCEPT
    {
      return exclusive.owns_lock();
    }
    Mutex* mutex() const BOOST_NOEXCEPT
    {
      return exclusive.mutex();
    }
  };

BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_to_unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END

namespace detail
{
  template<typename Mutex>
  class try_lock_wrapper:
private unique_lock<Mutex>
  {
    typedef unique_lock<Mutex> base;
  public:
    BOOST_THREAD_MOVABLE_ONLY(try_lock_wrapper)

    try_lock_wrapper()
    {}

    explicit try_lock_wrapper(Mutex& m):
    base(m,try_to_lock)
    {}

    try_lock_wrapper(Mutex& m_,adopt_lock_t):
    base(m_,adopt_lock)
    {
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
      BOOST_ASSERT(is_locked_by_this_thread(m_));
#endif
    }
    try_lock_wrapper(Mutex& m_,defer_lock_t):
    base(m_,defer_lock)
    {}
    try_lock_wrapper(Mutex& m_,try_to_lock_t):
    base(m_,try_to_lock)
    {}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
    try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
    base(::boost::move(other))
    {}

#elif defined BOOST_THREAD_USES_MOVE
    try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
    base(::boost::move(static_cast<base&>(other)))
    {}

#else
    try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
    base(BOOST_THREAD_RV_REF(base)(*other))
    {}
#endif
    try_lock_wrapper& operator=(BOOST_THREAD_RV_REF_BEG try_lock_wrapper<Mutex> BOOST_THREAD_RV_REF_END other)
    {
      try_lock_wrapper temp(::boost::move(other));
      swap(temp);
      return *this;
    }
    void swap(try_lock_wrapper& other)
    {
      base::swap(other);
    }
    void lock()
    {
      base::lock();
    }
    bool try_lock()
    {
      return base::try_lock();
    }
    void unlock()
    {
      base::unlock();
    }
    bool owns_lock() const
    {
      return base::owns_lock();
    }
    Mutex* mutex() const BOOST_NOEXCEPT
    {
      return base::mutex();
    }
    Mutex* release()
    {
      return base::release();
    }

#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
    typedef typename base::bool_type bool_type;
    operator bool_type() const
    {
      return base::operator bool_type();
    }
    bool operator!() const
    {
      return !this->owns_lock();
    }
#else
    explicit operator bool() const
    {
      return owns_lock();
    }
#endif
  };

  template<typename Mutex>
  void swap(try_lock_wrapper<Mutex>& lhs,try_lock_wrapper<Mutex>& rhs)
  {
    lhs.swap(rhs);
  }
}
}
#include <boost/config/abi_suffix.hpp>

#endif


code:
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba

#ifndef BOOST_THREAD_LOCKABLE_TRAITS_HPP
#define BOOST_THREAD_LOCKABLE_TRAITS_HPP

#include <boost/thread/detail/config.hpp>

#include <boost/assert.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/type_traits/is_class.hpp>

#include <boost/config/abi_prefix.hpp>

// todo make use of integral_constant, true_type and false_type

namespace boost
{
  namespace sync
  {

#if defined(BOOST_NO_SFINAE) ||                           \
    BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) || \
    BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
#if ! defined BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
#define BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
#endif
#endif

#ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
    namespace detail
    {
#define BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(member_name)                     \
        template<typename T, bool=boost::is_class<T>::value>            \
        struct has_member_called_##member_name                          \
        {                                                               \
            BOOST_STATIC_CONSTANT(bool, value=false);                   \
        };                                                              \
                                                                        \
        template<typename T>                                            \
        struct has_member_called_##member_name<T,true>                  \
        {                                                               \
            typedef char true_type;                                     \
            struct false_type                                           \
            {                                                           \
                true_type dummy[2];                                     \
            };                                                          \
                                                                        \
            struct fallback { int member_name; };                       \
            struct derived:                                             \
                T, fallback                                             \
            {                                                           \
                derived();                                              \
            };                                                          \
                                                                        \
            template<int fallback::*> struct tester;                    \
                                                                        \
            template<typename U>                                        \
                static false_type has_member(tester<&U::member_name>*); \
            template<typename U>                                        \
                static true_type has_member(...);                       \
                                                                        \
            BOOST_STATIC_CONSTANT(                                      \
                bool, value=sizeof(has_member<derived>(0))==sizeof(true_type)); \
        }

      BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(lock)
;      BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(unlock);
      BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(try_lock);

      template<typename T,bool=has_member_called_lock<T>::value >
      struct has_member_lock
      {
        BOOST_STATIC_CONSTANT(bool, value=false);
      };

      template<typename T>
      struct has_member_lock<T,true>
      {
        typedef char true_type;
        struct false_type
        {
          true_type dummy[2];
        };

        template<typename U,typename V>
        static true_type has_member(V (U::*)());
        template<typename U>
        static false_type has_member(U);

        BOOST_STATIC_CONSTANT(
            bool,value=sizeof(has_member_lock<T>::has_member(&T::lock))==sizeof(true_type));
      };

      template<typename T,bool=has_member_called_unlock<T>::value >
      struct has_member_unlock
      {
        BOOST_STATIC_CONSTANT(bool, value=false);
      };

      template<typename T>
      struct has_member_unlock<T,true>
      {
        typedef char true_type;
        struct false_type
        {
          true_type dummy[2];
        };

        template<typename U,typename V>
        static true_type has_member(V (U::*)());
        template<typename U>
        static false_type has_member(U);

        BOOST_STATIC_CONSTANT(
            bool,value=sizeof(has_member_unlock<T>::has_member(&T::unlock))==sizeof(true_type));
      };

      template<typename T,bool=has_member_called_try_lock<T>::value >
      struct has_member_try_lock
      {
        BOOST_STATIC_CONSTANT(bool, value=false);
      };

      template<typename T>
      struct has_member_try_lock<T,true>
      {
        typedef char true_type;
        struct false_type
        {
          true_type dummy[2];
        };

        template<typename U>
        static true_type has_member(bool (U::*)());
        template<typename U>
        static false_type has_member(U);

        BOOST_STATIC_CONSTANT(
            bool,value=sizeof(has_member_try_lock<T>::has_member(&T::try_lock))==sizeof(true_type));
      };

    }

    template<typename T>
    struct is_basic_lockable
    {
      BOOST_STATIC_CONSTANT(bool, value = detail::has_member_lock<T>::value &&
          detail::has_member_unlock<T>::value);
    };
    template<typename T>
    struct is_lockable
    {
      BOOST_STATIC_CONSTANT(bool, value =
          is_basic_lockable<T>::value &&
          detail::has_member_try_lock<T>::value);
    };

#else
    template<typename T>
    struct is_basic_lockable
    {
      BOOST_STATIC_CONSTANT(bool, value = false);
    };
    template<typename T>
    struct is_lockable
    {
      BOOST_STATIC_CONSTANT(bool, value = false);
    };
#endif

    template<typename T>
    struct is_recursive_mutex_sur_parole
    {
      BOOST_STATIC_CONSTANT(bool, value = false);
    };
    template<typename T>
    struct is_recursive_mutex_sur_parolle : is_recursive_mutex_sur_parole<T>
    {
    };

    template<typename T>
    struct is_recursive_basic_lockable
    {
      BOOST_STATIC_CONSTANT(bool, value = is_basic_lockable<T>::value &&
          is_recursive_mutex_sur_parolle<T>::value);
    };
    template<typename T>
    struct is_recursive_lockable
    {
      BOOST_STATIC_CONSTANT(bool, value = is_lockable<T>::value &&
          is_recursive_mutex_sur_parolle<T>::value);
    };
  }
  template<typename T>
  struct is_mutex_type
  {
    BOOST_STATIC_CONSTANT(bool, value = sync::is_lockable<T>::value);
  };

}
#include <boost/config/abi_suffix.hpp>

#endif


code:
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba

#ifndef BOOST_THREAD_LOCKS_HPP
#define BOOST_THREAD_LOCKS_HPP

#include <boost/thread/lock_algorithms.hpp>
#include <boost/thread/lock_types.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/shared_lock_guard.hpp>
#include <boost/thread/lockable_traits.hpp>
#include <boost/thread/lock_options.hpp>

#endif


code:
#ifndef BOOST_THREAD_MUTEX_HPP
#define BOOST_THREAD_MUTEX_HPP

//  mutex.hpp
//
//  (C) Copyright 2007 Anthony Williams
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#include <boost/thread/detail/platform.hpp>
#if defined(BOOST_THREAD_PLATFORM_WIN32)
#include <boost/thread/win32/mutex.hpp>
#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
#include <boost/thread/pthread/mutex.hpp>
#else
#error "Boost threads unavailable on this platform"
#endif

#include <boost/thread/lockable_traits.hpp>

namespace boost
{
  namespace sync
  {
#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
    template<>
    struct is_basic_lockable<mutex>
    {
      BOOST_STATIC_CONSTANT(bool, value = true);
    };
    template<>
    struct is_lockable<mutex>
    {
      BOOST_STATIC_CONSTANT(bool, value = true);
    };
    template<>
    struct is_basic_lockable<timed_mutex>
    {
      BOOST_STATIC_CONSTANT(bool, value = true);
    };
    template<>
    struct is_lockable<timed_mutex>
    {
      BOOST_STATIC_CONSTANT(bool, value = true);
    };
#endif
  }
}

#endif


code:
#ifndef BOOST_THREAD_ONCE_HPP
#define BOOST_THREAD_ONCE_HPP

//  once.hpp
//
//  (C) Copyright 2006-7 Anthony Williams
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#include <boost/thread/detail/config.hpp>
#include <boost/thread/detail/platform.hpp>
#if defined(BOOST_THREAD_PLATFORM_WIN32)
#include <boost/thread/win32/once.hpp>
#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
#if defined BOOST_THREAD_ONCE_FAST_EPOCH
#include <boost/thread/pthread/once.hpp>
#elif defined BOOST_THREAD_ONCE_ATOMIC
#include <boost/thread/pthread/once_atomic.hpp>
#else
#error "Once Not Implemented"
#endif
#else
#error "Boost threads unavailable on this platform"
#endif

#include <boost/config/abi_prefix.hpp>

namespace boost
{
  // template<class Callable, class ...Args> void
  // call_once(once_flag& flag, Callable&& func, Args&&... args);
template<typename Function>
inline void call_once(Function func,once_flag& flag)
//inline void call_once(void (*func)(),once_flag& flag)
    {
        call_once(flag,func);
    }
}

#include <boost/config/abi_suffix.hpp>

#endif


code:
#ifndef BOOST_THREAD_CONDITION_VARIABLE_PTHREAD_HPP
#define BOOST_THREAD_CONDITION_VARIABLE_PTHREAD_HPP
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007-10 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba

#include <boost/thread/pthread/timespec.hpp>
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
#include <boost/thread/pthread/thread_data.hpp>
#endif
#include <boost/thread/pthread/condition_variable_fwd.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>

#include <boost/config/abi_prefix.hpp>

namespace boost
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
    namespace this_thread
    {
        void BOOST_THREAD_DECL interruption_point();
    }
#endif

    namespace thread_cv_detail
    {
        template<typename MutexType>
        struct lock_on_exit
        {
            MutexType* m;

            lock_on_exit():
                m(0)
            {}

            void activate(MutexType& m_)
            {
                m_.unlock();
                m=&m_;
            }
            ~lock_on_exit()
            {
                if(m)
                {
                    m->lock();
                }
           }
        };
    }

    inline void condition_variable::wait(unique_lock<mutex>& m)
    {
#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
        if(! m.owns_lock())
        {
            boost::throw_exception(condition_error(-1, "boost::condition_variable::wait() failed precondition mutex not owned"));
        }
#endif
        int res=0;
        {
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
            thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
            detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
            pthread_mutex_t* the_mutex = &internal_mutex;
            guard.activate(m);
#else
            pthread_mutex_t* the_mutex = m.mutex()->native_handle();
#endif
            res = pthread_cond_wait(&cond,the_mutex);
        }
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
        this_thread::interruption_point();
#endif
        if(res && res != EINTR)
        {
            boost::throw_exception(condition_error(res, "boost::condition_variable::wait failed in pthread_cond_wait"));
        }
    }

    inline bool condition_variable::do_wait_until(
                unique_lock<mutex>& m,
                struct timespec const &timeout)
    {
#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
        if (!m.owns_lock())
        {
            boost::throw_exception(condition_error(EPERM, "boost::condition_variable::do_wait_until() failed precondition mutex not owned"));
        }
#endif
        int cond_res;
        {
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
            thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
            detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
            pthread_mutex_t* the_mutex = &internal_mutex;
            guard.activate(m);
#else
            pthread_mutex_t* the_mutex = m.mutex()->native_handle();
#endif
            cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout);
        }
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
        this_thread::interruption_point();
#endif
        if(cond_res==ETIMEDOUT)
        {
            return false;
        }
        if(cond_res)
        {
            boost::throw_exception(condition_error(cond_res, "boost::condition_variable::do_wait_until failed in pthread_cond_timedwait"));
        }
        return true;
    }

    inline void condition_variable::notify_one() BOOST_NOEXCEPT
    {
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
        boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
#endif
        BOOST_VERIFY(!pthread_cond_signal(&cond));
    }

    inline void condition_variable::notify_all() BOOST_NOEXCEPT
    {
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
        boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
#endif
        BOOST_VERIFY(!pthread_cond_broadcast(&cond));
    }

    class condition_variable_any
    {
        pthread_mutex_t internal_mutex;
        pthread_cond_t cond;

    public:
        BOOST_THREAD_NO_COPYABLE(condition_variable_any)
        condition_variable_any()
        {
            int const res=pthread_mutex_init(&internal_mutex,NULL);
            if(res)
            {
                boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_mutex_init"));
            }
            int const res2 = detail::monotonic_pthread_cond_init(cond);
            if(res2)
            {
                BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
                boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in detail::monotonic_pthread_cond_init"));
            }
        }
        ~condition_variable_any()
        {
            BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
            BOOST_VERIFY(!pthread_cond_destroy(&cond));
        }

        template<typename lock_type>
        void wait(lock_type& m)
        {
            int res=0;
            {
                thread_cv_detail::lock_on_exit<lock_type> guard;
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
                detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
#else
                boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
#endif
                guard.activate(m);
                res=pthread_cond_wait(&cond,&internal_mutex);
            }
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
            this_thread::interruption_point();
#endif
            if(res)
            {
                boost::throw_exception(condition_error(res, "boost::condition_variable_any::wait() failed in pthread_cond_wait"));
            }
        }

        template<typename lock_type,typename predicate_type>
        void wait(lock_type& m,predicate_type pred)
        {
            while(!pred()) wait(m);
        }

#if defined BOOST_THREAD_USES_DATETIME
        template<typename lock_type>
        bool timed_wait(lock_type& m,boost::system_time const& abs_time)
        {
            struct timespec const timeout=detail::to_timespec(abs_time);
            return do_wait_until(m, timeout);
        }
        template<typename lock_type>
        bool timed_wait(lock_type& m,xtime const& abs_time)
        {
            return timed_wait(m,system_time(abs_time));
        }

        template<typename lock_type,typename duration_type>
        bool timed_wait(lock_type& m,duration_type const& wait_duration)
        {
            return timed_wait(m,get_system_time()+wait_duration);
        }

        template<typename lock_type,typename predicate_type>
        bool timed_wait(lock_type& m,boost::system_time const& abs_time, predicate_type pred)
        {
            while (!pred())
            {
                if(!timed_wait(m, abs_time))
                    return pred();
            }
            return true;
        }

        template<typename lock_type,typename predicate_type>
        bool timed_wait(lock_type& m,xtime const& abs_time, predicate_type pred)
        {
            return timed_wait(m,system_time(abs_time),pred);
        }

        template<typename lock_type,typename duration_type,typename predicate_type>
        bool timed_wait(lock_type& m,duration_type const& wait_duration,predicate_type pred)
        {
            return timed_wait(m,get_system_time()+wait_duration,pred);
        }
#endif
#ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC

#ifdef BOOST_THREAD_USES_CHRONO
        template <class lock_type,class Duration>
        cv_status
        wait_until(
                lock_type& lock,
                const chrono::time_point<chrono::system_clock, Duration>& t)
        {
          using namespace chrono;
          typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
          wait_until(lock,
                        nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
          return system_clock::now() < t ? cv_status::no_timeout :
                                             cv_status::timeout;
        }

        template <class lock_type, class Clock, class Duration>
        cv_status
        wait_until(
                lock_type& lock,
                const chrono::time_point<Clock, Duration>& t)
        {
          using namespace chrono;
          system_clock::time_point     s_now = system_clock::now();
          typename Clock::time_point  c_now = Clock::now();
          wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
          return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
        }

        template <class lock_type, class Rep, class Period>
        cv_status
        wait_for(
                lock_type& lock,
                const chrono::duration<Rep, Period>& d)
        {
          using namespace chrono;
          system_clock::time_point s_now = system_clock::now();
          steady_clock::time_point c_now = steady_clock::now();
          wait_until(lock, s_now + ceil<nanoseconds>(d));
          return steady_clock::now() - c_now < d ? cv_status::no_timeout :
                                                   cv_status::timeout;

        }

        template <class lock_type>
        cv_status wait_until(
            lock_type& lk,
            chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
        {
            using namespace chrono;
            nanoseconds d = tp.time_since_epoch();
            timespec ts = boost::detail::to_timespec(d);
            if (do_wait_until(lk, ts)) return cv_status::no_timeout;
            else return cv_status::timeout;
        }
#endif
#else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO

        template <class lock_type, class Duration>
        cv_status
        wait_until(
            lock_type& lock,
            const chrono::time_point<chrono::steady_clock, Duration>& t)
        {
            using namespace chrono;
            typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
            wait_until(lock,
                        nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
            return steady_clock::now() < t ? cv_status::no_timeout :
                                             cv_status::timeout;
        }

        template <class lock_type, class Clock, class Duration>
        cv_status
        wait_until(
            lock_type& lock,
            const chrono::time_point<Clock, Duration>& t)
        {
            using namespace chrono;
            steady_clock::time_point     s_now = steady_clock::now();
            typename Clock::time_point  c_now = Clock::now();
            wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
            return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
        }

        template <class lock_type, class Rep, class Period>
        cv_status
        wait_for(
            lock_type& lock,
            const chrono::duration<Rep, Period>& d)
        {
            using namespace chrono;
            steady_clock::time_point c_now = steady_clock::now();
            wait_until(lock, c_now + ceil<nanoseconds>(d));
            return steady_clock::now() - c_now < d ? cv_status::no_timeout :
                                                   cv_status::timeout;
        }

        template <class lock_type>
        inline cv_status wait_until(
            lock_type& lock,
            chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
        {
            using namespace chrono;
            nanoseconds d = tp.time_since_epoch();
            timespec ts = boost::detail::to_timespec(d);
            if (do_wait_until(lock, ts)) return cv_status::no_timeout;
            else return cv_status::timeout;
        }

#endif
#endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC

#ifdef BOOST_THREAD_USES_CHRONO
        template <class lock_type, class Clock, class Duration, class Predicate>
        bool
        wait_until(
                lock_type& lock,
                const chrono::time_point<Clock, Duration>& t,
                Predicate pred)
        {
            while (!pred())
            {
                if (wait_until(lock, t) == cv_status::timeout)
                    return pred();
            }
            return true;
        }

        template <class lock_type, class Rep, class Period, class Predicate>
        bool
        wait_for(
                lock_type& lock,
                const chrono::duration<Rep, Period>& d,
                Predicate pred)
        {
          return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
        }
#endif

        void notify_one() BOOST_NOEXCEPT
        {
            boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
            BOOST_VERIFY(!pthread_cond_signal(&cond));
        }

        void notify_all() BOOST_NOEXCEPT
        {
            boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
            BOOST_VERIFY(!pthread_cond_broadcast(&cond));
        }
    private: // used by boost::thread::try_join_until

        template <class lock_type>
        bool do_wait_until(
          lock_type& m,
          struct timespec const &timeout)
        {
          int res=0;
          {
              thread_cv_detail::lock_on_exit<lock_type> guard;
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
              detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
#else
              boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
#endif
              guard.activate(m);
              res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
          }
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
          this_thread::interruption_point();
#endif
          if(res==ETIMEDOUT)
          {
              return false;
          }
          if(res)
          {
              boost::throw_exception(condition_error(res, "boost::condition_variable_any::do_wait_until() failed in pthread_cond_timedwait"));
          }
          return true;
        }
    };

}

#include <boost/config/abi_suffix.hpp>

#endif


code:
#ifndef BOOST_THREAD_PTHREAD_CONDITION_VARIABLE_FWD_HPP
#define BOOST_THREAD_PTHREAD_CONDITION_VARIABLE_FWD_HPP
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007-8 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba

#include <boost/assert.hpp>
#include <boost/throw_exception.hpp>
#include <pthread.h>
#include <boost/thread/cv_status.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/lock_types.hpp>
#include <boost/thread/thread_time.hpp>
#include <boost/thread/pthread/timespec.hpp>
#if defined BOOST_THREAD_USES_DATETIME
#include <boost/thread/xtime.hpp>
#endif
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>

#include <boost/config/abi_prefix.hpp>

namespace boost
{
  namespace detail {
    inline int monotonic_pthread_cond_init(pthread_cond_t& cond) {

#ifdef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
            pthread_condattr_t attr;
            int res = pthread_condattr_init(&attr);
            if (res)
            {
              return res;
            }
            pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
            res=pthread_cond_init(&cond,&attr);
            pthread_condattr_destroy(&attr);
            return res;
#else
            return pthread_cond_init(&cond,NULL);
#endif

    }
  }

    class condition_variable
    {
    private:
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
        pthread_mutex_t internal_mutex;
#endif
        pthread_cond_t cond;

    public:
    //private: // used by boost::thread::try_join_until

        inline bool do_wait_until(
            unique_lock<mutex>& lock,
            struct timespec const &timeout);

        bool do_wait_for(
            unique_lock<mutex>& lock,
            struct timespec const &timeout)
        {
          return do_wait_until(lock, boost::detail::timespec_plus(timeout, boost::detail::timespec_now()));
        }

    public:
      BOOST_THREAD_NO_COPYABLE(condition_variable)
        condition_variable()
        {
            int res;
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
            res=pthread_mutex_init(&internal_mutex,NULL);
            if(res)
            {
                boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init"));
            }
#endif
            res = detail::monotonic_pthread_cond_init(cond);
            if (res)
            {
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
                BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
#endif
                boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in detail::monotonic_pthread_cond_init"));
            }
        }
        ~condition_variable()
        {
            int ret;
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
            do {
              ret = pthread_mutex_destroy(&internal_mutex);
            } while (ret == EINTR);
            BOOST_ASSERT(!ret);
#endif
            do {
              ret = pthread_cond_destroy(&cond);
            } while (ret == EINTR);
            BOOST_ASSERT(!ret);
        }

        void wait(unique_lock<mutex>& m);

        template<typename predicate_type>
        void wait(unique_lock<mutex>& m,predicate_type pred)
        {
            while(!pred()) wait(m);
        }

#if defined BOOST_THREAD_USES_DATETIME
        inline bool timed_wait(
            unique_lock<mutex>& m,
            boost::system_time const& abs_time)
        {
#if defined BOOST_THREAD_WAIT_BUG
            struct timespec const timeout=detail::to_timespec(abs_time + BOOST_THREAD_WAIT_BUG);
            return do_wait_until(m, timeout);
#else
            struct timespec const timeout=detail::to_timespec(abs_time);
            return do_wait_until(m, timeout);
#endif
        }
        bool timed_wait(
            unique_lock<mutex>& m,
            xtime const& abs_time)
        {
            return timed_wait(m,system_time(abs_time));
        }

        template<typename duration_type>
        bool timed_wait(
            unique_lock<mutex>& m,
            duration_type const& wait_duration)
        {
            if (wait_duration.is_pos_infinity())
            {
                wait(m); // or do_wait(m,detail::timeout::sentinel());
                return true;
            }
            if (wait_duration.is_special())
            {
                return true;
            }
            return timed_wait(m,get_system_time()+wait_duration);
        }

        template<typename predicate_type>
        bool timed_wait(
            unique_lock<mutex>& m,
            boost::system_time const& abs_time,predicate_type pred)
        {
            while (!pred())
            {
                if(!timed_wait(m, abs_time))
                    return pred();
            }
            return true;
        }

        template<typename predicate_type>
        bool timed_wait(
            unique_lock<mutex>& m,
            xtime const& abs_time,predicate_type pred)
        {
            return timed_wait(m,system_time(abs_time),pred);
        }

        template<typename duration_type,typename predicate_type>
        bool timed_wait(
            unique_lock<mutex>& m,
            duration_type const& wait_duration,predicate_type pred)
        {
            if (wait_duration.is_pos_infinity())
            {
                while (!pred())
                {
                  wait(m); // or do_wait(m,detail::timeout::sentinel());
                }
                return true;
            }
            if (wait_duration.is_special())
            {
                return pred();
            }
            return timed_wait(m,get_system_time()+wait_duration,pred);
        }
#endif

#ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC

#ifdef BOOST_THREAD_USES_CHRONO

        template <class Duration>
        cv_status
        wait_until(
                unique_lock<mutex>& lock,
                const chrono::time_point<chrono::system_clock, Duration>& t)
        {
          using namespace chrono;
          typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
          wait_until(lock,
                        nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
          return system_clock::now() < t ? cv_status::no_timeout :
                                             cv_status::timeout;
        }

        template <class Clock, class Duration>
        cv_status
        wait_until(
                unique_lock<mutex>& lock,
                const chrono::time_point<Clock, Duration>& t)
        {
          using namespace chrono;
          system_clock::time_point     s_now = system_clock::now();
          typename Clock::time_point  c_now = Clock::now();
          wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
          return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
        }

        template <class Rep, class Period>
        cv_status
        wait_for(
                unique_lock<mutex>& lock,
                const chrono::duration<Rep, Period>& d)
        {
          using namespace chrono;
          system_clock::time_point s_now = system_clock::now();
          steady_clock::time_point c_now = steady_clock::now();
          wait_until(lock, s_now + ceil<nanoseconds>(d));
          return steady_clock::now() - c_now < d ? cv_status::no_timeout :
                                                   cv_status::timeout;

        }

        inline cv_status wait_until(
            unique_lock<mutex>& lk,
            chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
        {
            using namespace chrono;
            nanoseconds d = tp.time_since_epoch();
            timespec ts = boost::detail::to_timespec(d);
            if (do_wait_until(lk, ts)) return cv_status::no_timeout;
            else return cv_status::timeout;
        }
#endif

#else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO

        template <class Duration>
        cv_status
        wait_until(
              unique_lock<mutex>& lock,
              const chrono::time_point<chrono::steady_clock, Duration>& t)
        {
            using namespace chrono;
            typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
            wait_until(lock,
                        nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
            return steady_clock::now() < t ? cv_status::no_timeout :
                                             cv_status::timeout;
        }

        template <class Clock, class Duration>
        cv_status
        wait_until(
            unique_lock<mutex>& lock,
            const chrono::time_point<Clock, Duration>& t)
        {
            using namespace chrono;
            steady_clock::time_point     s_now = steady_clock::now();
            typename Clock::time_point  c_now = Clock::now();
            wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
            return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
        }

        template <class Rep, class Period>
        cv_status
        wait_for(
            unique_lock<mutex>& lock,
            const chrono::duration<Rep, Period>& d)
        {
            using namespace chrono;
            steady_clock::time_point c_now = steady_clock::now();
            wait_until(lock, c_now + ceil<nanoseconds>(d));
            return steady_clock::now() - c_now < d ? cv_status::no_timeout :
                                                   cv_status::timeout;
        }

        inline cv_status wait_until(
            unique_lock<mutex>& lk,
            chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
        {
            using namespace chrono;
            nanoseconds d = tp.time_since_epoch();
            timespec ts = boost::detail::to_timespec(d);
            if (do_wait_until(lk, ts)) return cv_status::no_timeout;
            else return cv_status::timeout;
        }
#endif

#endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC

#ifdef BOOST_THREAD_USES_CHRONO
        template <class Clock, class Duration, class Predicate>
        bool
        wait_until(
                unique_lock<mutex>& lock,
                const chrono::time_point<Clock, Duration>& t,
                Predicate pred)
        {
            while (!pred())
            {
                if (wait_until(lock, t) == cv_status::timeout)
                    return pred();
            }
            return true;
        }

        template <class Rep, class Period, class Predicate>
        bool
        wait_for(
                unique_lock<mutex>& lock,
                const chrono::duration<Rep, Period>& d,
                Predicate pred)
        {
          return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
        }
#endif

#define BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE
        typedef pthread_cond_t* native_handle_type;
        native_handle_type native_handle()
        {
            return &cond;
        }

        void notify_one() BOOST_NOEXCEPT;
        void notify_all() BOOST_NOEXCEPT;

    };

    BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);

}

#include <boost/config/abi_suffix.hpp>

#endif