// (C) Copyright 2008 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/test/unit_test.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/condition_variable.hpp>

void test_lock_two_uncontended()
{
    boost::mutex m1,m2;

    boost::mutex::scoped_lock l1(m1,boost::defer_lock),
        l2(m2,boost::defer_lock);

    BOOST_CHECK(!l1.owns_lock());
    BOOST_CHECK(!l2.owns_lock());
    
    boost::lock(l1,l2);
    
    BOOST_CHECK(l1.owns_lock());
    BOOST_CHECK(l2.owns_lock());
}

struct wait_data
{
    boost::mutex m;
    bool flag;
    boost::condition_variable cond;
    
    wait_data():
        flag(false)
    {}
    
    void wait()
    {
        boost::mutex::scoped_lock l(m);
        while(!flag)
        {
            cond.wait(l);
        }
    }

    template<typename Duration>
    bool timed_wait(Duration d)
    {
        boost::system_time const target=boost::get_system_time()+d;
        
        boost::mutex::scoped_lock l(m);
        while(!flag)
        {
            if(!cond.timed_wait(l,target))
            {
                return flag;
            }
        }
        return true;
    }
    
    void signal()
    {
        boost::mutex::scoped_lock l(m);
        flag=true;
        cond.notify_all();
    }
};
       

void lock_mutexes_slowly(boost::mutex* m1,boost::mutex* m2,wait_data* locked,wait_data* quit)
{
    boost::lock_guard<boost::mutex> l1(*m1);
    boost::this_thread::sleep(boost::posix_time::milliseconds(500));
    boost::lock_guard<boost::mutex> l2(*m2);
    locked->signal();
    quit->wait();
}

void lock_pair(boost::mutex* m1,boost::mutex* m2)
{
    boost::lock(*m1,*m2);
    boost::mutex::scoped_lock l1(*m1,boost::adopt_lock),
        l2(*m2,boost::adopt_lock);
}

void test_lock_two_other_thread_locks_in_order()
{
    boost::mutex m1,m2;
    wait_data locked;
    wait_data release;
    
    boost::thread t(lock_mutexes_slowly,&m1,&m2,&locked,&release);
    boost::this_thread::sleep(boost::posix_time::milliseconds(10));

    boost::thread t2(lock_pair,&m1,&m2);
    BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(1)));

    release.signal();
    
    BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(1)));

    t.join();
}

void test_lock_two_other_thread_locks_in_opposite_order()
{
    boost::mutex m1,m2;
    wait_data locked;
    wait_data release;
    
    boost::thread t(lock_mutexes_slowly,&m1,&m2,&locked,&release);
    boost::this_thread::sleep(boost::posix_time::milliseconds(10));

    boost::thread t2(lock_pair,&m2,&m1);
    BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(1)));

    release.signal();
    
    BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(1)));

    t.join();
}

void test_lock_five_uncontended()
{
    boost::mutex m1,m2,m3,m4,m5;

    boost::mutex::scoped_lock l1(m1,boost::defer_lock),
        l2(m2,boost::defer_lock),
        l3(m3,boost::defer_lock),
        l4(m4,boost::defer_lock),
        l5(m5,boost::defer_lock);

    BOOST_CHECK(!l1.owns_lock());
    BOOST_CHECK(!l2.owns_lock());
    BOOST_CHECK(!l3.owns_lock());
    BOOST_CHECK(!l4.owns_lock());
    BOOST_CHECK(!l5.owns_lock());
    
    boost::lock(l1,l2,l3,l4,l5);
    
    BOOST_CHECK(l1.owns_lock());
    BOOST_CHECK(l2.owns_lock());
    BOOST_CHECK(l3.owns_lock());
    BOOST_CHECK(l4.owns_lock());
    BOOST_CHECK(l5.owns_lock());
}

void lock_five_mutexes_slowly(boost::mutex* m1,boost::mutex* m2,boost::mutex* m3,boost::mutex* m4,boost::mutex* m5,
                              wait_data* locked,wait_data* quit)
{
    boost::lock_guard<boost::mutex> l1(*m1);
    boost::this_thread::sleep(boost::posix_time::milliseconds(500));
    boost::lock_guard<boost::mutex> l2(*m2);
    boost::this_thread::sleep(boost::posix_time::milliseconds(500));
    boost::lock_guard<boost::mutex> l3(*m3);
    boost::this_thread::sleep(boost::posix_time::milliseconds(500));
    boost::lock_guard<boost::mutex> l4(*m4);
    boost::this_thread::sleep(boost::posix_time::milliseconds(500));
    boost::lock_guard<boost::mutex> l5(*m5);
    locked->signal();
    quit->wait();
}

void lock_five(boost::mutex* m1,boost::mutex* m2,boost::mutex* m3,boost::mutex* m4,boost::mutex* m5)
{
    boost::lock(*m1,*m2,*m3,*m4,*m5);
    m1->unlock();
    m2->unlock();
    m3->unlock();
    m4->unlock();
    m5->unlock();
}

void test_lock_five_other_thread_locks_in_order()
{
    boost::mutex m1,m2,m3,m4,m5;
    wait_data locked;
    wait_data release;
    
    boost::thread t(lock_five_mutexes_slowly,&m1,&m2,&m3,&m4,&m5,&locked,&release);
    boost::this_thread::sleep(boost::posix_time::milliseconds(10));

    boost::thread t2(lock_five,&m1,&m2,&m3,&m4,&m5);
    BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(3)));

    release.signal();
    
    BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(3)));

    t.join();
}

void test_lock_five_other_thread_locks_in_different_order()
{
    boost::mutex m1,m2,m3,m4,m5;
    wait_data locked;
    wait_data release;
    
    boost::thread t(lock_five_mutexes_slowly,&m1,&m2,&m3,&m4,&m5,&locked,&release);
    boost::this_thread::sleep(boost::posix_time::milliseconds(10));

    boost::thread t2(lock_five,&m5,&m1,&m4,&m2,&m3);
    BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(3)));

    release.signal();
    
    BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(3)));

    t.join();
}

void lock_n(boost::mutex* mutexes,unsigned count)
{
    boost::lock(mutexes,mutexes+count);
    for(unsigned i=0;i<count;++i)
    {
        mutexes[i].unlock();
    }
}


void test_lock_ten_other_thread_locks_in_different_order()
{
    unsigned const num_mutexes=10;
    
    boost::mutex mutexes[num_mutexes];
    wait_data locked;
    wait_data release;
    
    boost::thread t(lock_five_mutexes_slowly,&mutexes[6],&mutexes[3],&mutexes[8],&mutexes[0],&mutexes[2],&locked,&release);
    boost::this_thread::sleep(boost::posix_time::milliseconds(10));

    boost::thread t2(lock_n,mutexes,num_mutexes);
    BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(3)));

    release.signal();

    BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(3)));

    t.join();
}

struct dummy_mutex
{
    bool is_locked;
    
    dummy_mutex():
        is_locked(false)
    {}
    
    void lock()
    {
        is_locked=true;
    }
    
    bool try_lock()
    {
        if(is_locked)
        {
            return false;
        }
        is_locked=true;
        return true;
    }
    
    void unlock()
    {
        is_locked=false;
    }
};

namespace boost
{
    template<>
    struct is_mutex_type<dummy_mutex>
    {
        BOOST_STATIC_CONSTANT(bool, value = true);
    };
}



void test_lock_five_in_range()
{
    unsigned const num_mutexes=5;
    dummy_mutex mutexes[num_mutexes];

    boost::lock(mutexes,mutexes+num_mutexes);
    
    for(unsigned i=0;i<num_mutexes;++i)
    {
        BOOST_CHECK(mutexes[i].is_locked);
    }
}

class dummy_iterator:
    public std::iterator<std::forward_iterator_tag,
                         dummy_mutex>
{
private:
    dummy_mutex* p;
public:
    explicit dummy_iterator(dummy_mutex* p_):
        p(p_)
    {}
    
    bool operator==(dummy_iterator const& other) const
    {
        return p==other.p;
    }

    bool operator!=(dummy_iterator const& other) const
    {
        return p!=other.p;
    }

    bool operator<(dummy_iterator const& other) const
    {
        return p<other.p;
    }
    
    dummy_mutex& operator*() const
    {
        return *p;
    }

    dummy_mutex* operator->() const
    {
        return p;
    }
    
    dummy_iterator operator++(int)
    {
        dummy_iterator temp(*this);
        ++p;
        return temp;
    }
    
    dummy_iterator& operator++()
    {
        ++p;
        return *this;
    }
    
};
    

void test_lock_five_in_range_custom_iterator()
{
    unsigned const num_mutexes=5;
    dummy_mutex mutexes[num_mutexes];

    boost::lock(dummy_iterator(mutexes),dummy_iterator(mutexes+num_mutexes));
    
    for(unsigned i=0;i<num_mutexes;++i)
    {
        BOOST_CHECK(mutexes[i].is_locked);
    }
}

class dummy_mutex2:
    public dummy_mutex
{};


void test_lock_ten_in_range_inherited_mutex()
{
    unsigned const num_mutexes=10;
    dummy_mutex2 mutexes[num_mutexes];

    boost::lock(mutexes,mutexes+num_mutexes);
    
    for(unsigned i=0;i<num_mutexes;++i)
    {
        BOOST_CHECK(mutexes[i].is_locked);
    }
}

void test_try_lock_two_uncontended()
{
    dummy_mutex m1,m2;

    int const res=boost::try_lock(m1,m2);
    
    BOOST_CHECK(res==-1);
    BOOST_CHECK(m1.is_locked);
    BOOST_CHECK(m2.is_locked);
}
void test_try_lock_two_first_locked()
{
    dummy_mutex m1,m2;
    m1.lock();

    boost::unique_lock<dummy_mutex> l1(m1,boost::defer_lock),
        l2(m2,boost::defer_lock);

    int const res=boost::try_lock(l1,l2);
    
    BOOST_CHECK(res==0);
    BOOST_CHECK(m1.is_locked);
    BOOST_CHECK(!m2.is_locked);
    BOOST_CHECK(!l1.owns_lock());
    BOOST_CHECK(!l2.owns_lock());
}
void test_try_lock_two_second_locked()
{
    dummy_mutex m1,m2;
    m2.lock();

    boost::unique_lock<dummy_mutex> l1(m1,boost::defer_lock),
        l2(m2,boost::defer_lock);

    int const res=boost::try_lock(l1,l2);
    
    BOOST_CHECK(res==1);
    BOOST_CHECK(!m1.is_locked);
    BOOST_CHECK(m2.is_locked);
    BOOST_CHECK(!l1.owns_lock());
    BOOST_CHECK(!l2.owns_lock());
}

void test_try_lock_three()
{
    int const num_mutexes=3;
    
    for(int i=-1;i<num_mutexes;++i)
    {
        dummy_mutex mutexes[num_mutexes];

        if(i>=0)
        {
            mutexes[i].lock();
        }
        boost::unique_lock<dummy_mutex> l1(mutexes[0],boost::defer_lock),
            l2(mutexes[1],boost::defer_lock),
            l3(mutexes[2],boost::defer_lock);

        int const res=boost::try_lock(l1,l2,l3);
    
        BOOST_CHECK(res==i);
        for(int j=0;j<num_mutexes;++j)
        {
            if((i==j) || (i==-1))
            {
                BOOST_CHECK(mutexes[j].is_locked);
            }
            else
            {
                BOOST_CHECK(!mutexes[j].is_locked);
            }
        }
        if(i==-1)
        {
            BOOST_CHECK(l1.owns_lock());
            BOOST_CHECK(l2.owns_lock());
            BOOST_CHECK(l3.owns_lock());
        }
        else
        {
            BOOST_CHECK(!l1.owns_lock());
            BOOST_CHECK(!l2.owns_lock());
            BOOST_CHECK(!l3.owns_lock());
        }
    }
}

void test_try_lock_four()
{
    int const num_mutexes=4;
    
    for(int i=-1;i<num_mutexes;++i)
    {
        dummy_mutex mutexes[num_mutexes];

        if(i>=0)
        {
            mutexes[i].lock();
        }
        boost::unique_lock<dummy_mutex> l1(mutexes[0],boost::defer_lock),
            l2(mutexes[1],boost::defer_lock),
            l3(mutexes[2],boost::defer_lock),
            l4(mutexes[3],boost::defer_lock);

        int const res=boost::try_lock(l1,l2,l3,l4);
    
        BOOST_CHECK(res==i);
        for(int j=0;j<num_mutexes;++j)
        {
            if((i==j) || (i==-1))
            {
                BOOST_CHECK(mutexes[j].is_locked);
            }
            else
            {
                BOOST_CHECK(!mutexes[j].is_locked);
            }
        }
        if(i==-1)
        {
            BOOST_CHECK(l1.owns_lock());
            BOOST_CHECK(l2.owns_lock());
            BOOST_CHECK(l3.owns_lock());
            BOOST_CHECK(l4.owns_lock());
        }
        else
        {
            BOOST_CHECK(!l1.owns_lock());
            BOOST_CHECK(!l2.owns_lock());
            BOOST_CHECK(!l3.owns_lock());
            BOOST_CHECK(!l4.owns_lock());
        }
    }
}

void test_try_lock_five()
{
    int const num_mutexes=5;
    
    for(int i=-1;i<num_mutexes;++i)
    {
        dummy_mutex mutexes[num_mutexes];

        if(i>=0)
        {
            mutexes[i].lock();
        }
        boost::unique_lock<dummy_mutex> l1(mutexes[0],boost::defer_lock),
            l2(mutexes[1],boost::defer_lock),
            l3(mutexes[2],boost::defer_lock),
            l4(mutexes[3],boost::defer_lock),
            l5(mutexes[4],boost::defer_lock);

        int const res=boost::try_lock(l1,l2,l3,l4,l5);
    
        BOOST_CHECK(res==i);
        for(int j=0;j<num_mutexes;++j)
        {
            if((i==j) || (i==-1))
            {
                BOOST_CHECK(mutexes[j].is_locked);
            }
            else
            {
                BOOST_CHECK(!mutexes[j].is_locked);
            }
        }
        if(i==-1)
        {
            BOOST_CHECK(l1.owns_lock());
            BOOST_CHECK(l2.owns_lock());
            BOOST_CHECK(l3.owns_lock());
            BOOST_CHECK(l4.owns_lock());
            BOOST_CHECK(l5.owns_lock());
        }
        else
        {
            BOOST_CHECK(!l1.owns_lock());
            BOOST_CHECK(!l2.owns_lock());
            BOOST_CHECK(!l3.owns_lock());
            BOOST_CHECK(!l4.owns_lock());
            BOOST_CHECK(!l5.owns_lock());
        }
    }
}



boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
{
    boost::unit_test_framework::test_suite* test =
        BOOST_TEST_SUITE("Boost.Threads: generic locks test suite");

    test->add(BOOST_TEST_CASE(&test_lock_two_uncontended));
    test->add(BOOST_TEST_CASE(&test_lock_two_other_thread_locks_in_order));
    test->add(BOOST_TEST_CASE(&test_lock_two_other_thread_locks_in_opposite_order));
    test->add(BOOST_TEST_CASE(&test_lock_five_uncontended));
    test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_order));
    test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_different_order));
    test->add(BOOST_TEST_CASE(&test_lock_five_in_range));
    test->add(BOOST_TEST_CASE(&test_lock_five_in_range_custom_iterator));
    test->add(BOOST_TEST_CASE(&test_lock_ten_in_range_inherited_mutex));
    test->add(BOOST_TEST_CASE(&test_lock_ten_other_thread_locks_in_different_order));
    test->add(BOOST_TEST_CASE(&test_try_lock_two_uncontended));
    test->add(BOOST_TEST_CASE(&test_try_lock_two_first_locked));
    test->add(BOOST_TEST_CASE(&test_try_lock_two_second_locked));
    test->add(BOOST_TEST_CASE(&test_try_lock_three));
    test->add(BOOST_TEST_CASE(&test_try_lock_four));
    test->add(BOOST_TEST_CASE(&test_try_lock_five));

    return test;
}
