// Copyright (C) 2001-2003
// William E. Kempf
//
// Copyright Frank Mori Hess 2009
//
// Use, modification and
// distribution is subject to 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)

// This is a simplified/modified version of libs/thread/test/test_mutex.cpp
// added to test boost::signals2::mutex.
// For more information, see http://www.boost.org

// note boost/test/minimal.hpp can cause windows.h to get included, which
// can screw up our checks of _WIN32_WINNT if it is included
// after boost/signals2/mutex.hpp.  Frank Hess 2009-03-07.
#include <boost/test/minimal.hpp>

#include <boost/bind.hpp>
#include <boost/signals2/dummy_mutex.hpp>
#include <boost/signals2/mutex.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/thread_time.hpp>
#include <boost/thread/condition.hpp>

class execution_monitor
{
public:
    enum wait_type { use_sleep_only, use_mutex, use_condition };

    execution_monitor(wait_type type, int secs)
        : done(false), type(type), secs(secs) { }
    void start()
    {
        if (type != use_sleep_only) {
            boost::mutex::scoped_lock lock(mutex); done = false;
        } else {
            done = false;
        }
    }
    void finish()
    {
        if (type != use_sleep_only) {
            boost::mutex::scoped_lock lock(mutex);
            done = true;
            if (type == use_condition)
                cond.notify_one();
        } else {
            done = true;
        }
    }
    bool wait()
    {
        boost::posix_time::time_duration timeout = boost::posix_time::seconds(secs);
        if (type != use_condition)
            boost::this_thread::sleep(timeout);
        if (type != use_sleep_only) {
            boost::mutex::scoped_lock lock(mutex);
            while (type == use_condition && !done) {
                if (!cond.timed_wait(lock, timeout))
                    break;
            }
            return done;
        }
        return done;
    }

private:
    boost::mutex mutex;
    boost::condition cond;
    bool done;
    wait_type type;
    int secs;
};

template <typename F>
class indirect_adapter
{
public:
    indirect_adapter(F func, execution_monitor& monitor)
        : func(func), monitor(monitor) { }
    void operator()() const
    {
        try
        {
            boost::thread thrd(func);
            thrd.join();
        }
        catch (...)
        {
            monitor.finish();
            throw;
        }
        monitor.finish();
    }

private:
    F func;
    execution_monitor& monitor;
    void operator=(indirect_adapter&);
};

template <typename F>
void timed_test(F func, int secs,
    execution_monitor::wait_type type = execution_monitor::use_sleep_only)
{
    execution_monitor monitor(type, secs);
    indirect_adapter<F> ifunc(func, monitor);
    monitor.start();
    boost::thread thrd(ifunc);
    BOOST_REQUIRE(monitor.wait()); // Timed test didn't complete in time, possible deadlock
}

template <typename M>
struct test_lock
{
    typedef M mutex_type;
    typedef typename boost::unique_lock<M> lock_type;

    void operator()()
    {
        mutex_type mutex;
        boost::condition condition;

        // Test the lock's constructors.
        {
            lock_type lock(mutex, boost::defer_lock);
            BOOST_CHECK(!lock);
        }
        lock_type lock(mutex);
        BOOST_CHECK(lock ? true : false);

        // Construct a fast time out.
        boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(100);

        // Test the lock and the mutex with condition variables.
        // No one is going to notify this condition variable.  We expect to
        // time out.
        BOOST_CHECK(!condition.timed_wait(lock, timeout));
        BOOST_CHECK(lock ? true : false);

        // Test the lock and unlock methods.
        lock.unlock();
        BOOST_CHECK(!lock);
        lock.lock();
        BOOST_CHECK(lock ? true : false);
    }
};

template <typename M>
struct test_trylock
{
    typedef M mutex_type;
    typedef typename boost::unique_lock<M> lock_type;

    void operator()()
    {
        mutex_type mutex;
        boost::condition condition;

        // Test the lock's constructors.
        {
            lock_type lock(mutex, boost::try_to_lock);
            BOOST_CHECK(lock ? true : false);
        }
        {
            lock_type lock(mutex, boost::defer_lock);
            BOOST_CHECK(!lock);
        }
        lock_type lock(mutex, boost::try_to_lock);
        BOOST_CHECK(lock ? true : false);

        // Construct a fast time out.
        boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(100);

        // Test the lock and the mutex with condition variables.
        // No one is going to notify this condition variable.  We expect to
        // time out.
        BOOST_CHECK(!condition.timed_wait(lock, timeout));
        BOOST_CHECK(lock ? true : false);

        // Test the lock, unlock and trylock methods.
        lock.unlock();
        BOOST_CHECK(!lock);
        lock.lock();
        BOOST_CHECK(lock ? true : false);
        lock.unlock();
        BOOST_CHECK(!lock);
        BOOST_CHECK(lock.try_lock());
        BOOST_CHECK(lock ? true : false);
    }
};

template<typename Mutex>
struct test_lock_exclusion
{
    typedef boost::unique_lock<Mutex> Lock;

    Mutex m;
    boost::mutex done_mutex;
    bool done;
    bool locked;
    boost::condition_variable done_cond;

    test_lock_exclusion():
        done(false),locked(false)
    {}

    void locking_thread()
    {
        Lock lock(m);

        boost::lock_guard<boost::mutex> lk(done_mutex);
        locked=lock.owns_lock();
        done=true;
        done_cond.notify_one();
    }

    bool is_done() const
    {
        return done;
    }

    typedef test_lock_exclusion<Mutex> this_type;

    void do_test(void (this_type::*test_func)())
    {
        Lock lock(m);

        locked=false;
        done=false;

        boost::thread t(test_func,this);

        try
        {
            {
                boost::mutex::scoped_lock lk(done_mutex);
                BOOST_CHECK(!done_cond.timed_wait(lk, boost::posix_time::seconds(1),
                                                 boost::bind(&this_type::is_done,this)));
            }
            lock.unlock();
            {
                boost::mutex::scoped_lock lk(done_mutex);
                BOOST_CHECK(done_cond.timed_wait(lk, boost::posix_time::seconds(1),
                                                 boost::bind(&this_type::is_done,this)));
            }
            t.join();
            BOOST_CHECK(locked);
        }
        catch(...)
        {
            lock.unlock();
            t.join();
            throw;
        }
    }


    void operator()()
    {
        do_test(&this_type::locking_thread);
    }
};


void do_test_mutex()
{
    test_lock<boost::signals2::mutex>()();
// try_lock not supported on old versions of windows
#if !defined(BOOST_HAS_WINTHREADS) || (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400))
    test_trylock<boost::signals2::mutex>()();
#endif
    test_lock_exclusion<boost::signals2::mutex>()();
}

void test_mutex()
{
    timed_test(&do_test_mutex, 3);
}

void do_test_dummy_mutex()
{
    test_lock<boost::signals2::dummy_mutex>()();
    test_trylock<boost::signals2::dummy_mutex>()();
}

void test_dummy_mutex()
{
    timed_test(&do_test_dummy_mutex, 2);
}

int test_main(int, char*[])
{
    test_mutex();
    test_dummy_mutex();

    return 0;
}
