/usr/include/boost/thread
Edit: /usr/include/boost/thread/lock_algorithms.hpp (13201B)
// 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
#include
#include
#include
#include
#include
namespace boost
{
namespace detail
{
template
unsigned try_lock_internal(MutexType1& m1, MutexType2& m2)
{
boost::unique_lock l1(m1, boost::try_to_lock);
if (!l1)
{
return 1;
}
if (!m2.try_lock())
{
return 2;
}
l1.release();
return 0;
}
template
unsigned try_lock_internal(MutexType1& m1, MutexType2& m2, MutexType3& m3)
{
boost::unique_lock 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
unsigned try_lock_internal(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4)
{
boost::unique_lock 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
unsigned try_lock_internal(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4, MutexType5& m5)
{
boost::unique_lock 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
unsigned lock_helper(MutexType1& m1, MutexType2& m2)
{
boost::unique_lock l1(m1);
if (!m2.try_lock())
{
return 1;
}
l1.release();
return 0;
}
template
unsigned lock_helper(MutexType1& m1, MutexType2& m2, MutexType3& m3)
{
boost::unique_lock l1(m1);
if (unsigned const failed_lock=try_lock_internal(m2,m3))
{
return failed_lock;
}
l1.release();
return 0;
}
template
unsigned lock_helper(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4)
{
boost::unique_lock l1(m1);
if (unsigned const failed_lock=try_lock_internal(m2,m3,m4))
{
return failed_lock;
}
l1.release();
return 0;
}
template
unsigned lock_helper(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4, MutexType5& m5)
{
boost::unique_lock l1(m1);
if (unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5))
{
return failed_lock;
}
l1.release();
return 0;
}
}
namespace detail
{
template
struct is_mutex_type_wrapper
{
};
template
void lock_impl(MutexType1& m1, MutexType2& m2, is_mutex_type_wrapper )
{
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
void lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper );
}
template
void lock(MutexType1& m1, MutexType2& m2)
{
detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper::value>());
}
template
void lock(const MutexType1& m1, MutexType2& m2)
{
detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper::value>());
}
template
void lock(MutexType1& m1, const MutexType2& m2)
{
detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper::value>());
}
template
void lock(const MutexType1& m1, const MutexType2& m2)
{
detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper::value>());
}
template
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
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
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 ::value>
struct try_lock_impl_return
{
typedef int type;
};
template
struct try_lock_impl_return
{
typedef Iterator type;
};
template
int try_lock_impl(MutexType1& m1, MutexType2& m2, is_mutex_type_wrapper )
{
return ((int) detail::try_lock_internal(m1, m2)) - 1;
}
template
Iterator try_lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper );
}
template
typename detail::try_lock_impl_return::type try_lock(MutexType1& m1, MutexType2& m2)
{
return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper::value>());
}
template
typename detail::try_lock_impl_return::type try_lock(const MutexType1& m1, MutexType2& m2)
{
return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper::value>());
}
template
typename detail::try_lock_impl_return::type try_lock(MutexType1& m1, const MutexType2& m2)
{
return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper::value>());
}
template
typename detail::try_lock_impl_return::type try_lock(const MutexType1& m1, const MutexType2& m2)
{
return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper::value>());
}
template
int try_lock(MutexType1& m1, MutexType2& m2, MutexType3& m3)
{
return ((int) detail::try_lock_internal(m1, m2, m3)) - 1;
}
template
int try_lock(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4)
{
return ((int) detail::try_lock_internal(m1, m2, m3, m4)) - 1;
}
template
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
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
Iterator try_lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper )
{
if (begin == end)
{
return end;
}
typedef typename std::iterator_traits::value_type lock_type;
unique_lock 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
void lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper )
{
typedef typename std::iterator_traits::value_type lock_type;
if (begin == end)
{
return;
}
bool start_with_begin = true;
Iterator second = begin;
++second;
Iterator next = second;
for (;;)
{
unique_lock 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 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
#endif