// Copyright (C) 2001-2003
// William E. Kempf
//
//  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/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <iostream>
#include <time.h>

namespace
{
boost::mutex iomx;
} // namespace

class canteen
{
public:
    canteen() : m_chickens(0) { }

    void get(int id)
    {
        boost::mutex::scoped_lock lock(m_mutex);
        while (m_chickens == 0)
        {
            {
                boost::mutex::scoped_lock lock(iomx);
                std::cout << "(" << clock() << ") Phil" << id <<
                    ": wot, no chickens?  I'll WAIT ..." << std::endl;
            }
            m_condition.wait(lock);
        }
        {
            boost::mutex::scoped_lock lock(iomx);
            std::cout << "(" << clock() << ") Phil" << id <<
                ": those chickens look good ... one please ..." << std::endl;
        }
        m_chickens--;
    }
    void put(int value)
    {
        boost::mutex::scoped_lock lock(m_mutex);
        {
            boost::mutex::scoped_lock lock(iomx);
            std::cout << "(" << clock()
                      << ") Chef: ouch ... make room ... this dish is "
                      << "very hot ..." << std::endl;
        }
        boost::xtime xt;
        boost::xtime_get(&xt, boost::TIME_UTC);
        xt.sec += 3;
        boost::thread::sleep(xt);
        m_chickens += value;
        {
            boost::mutex::scoped_lock lock(iomx);
            std::cout << "(" << clock() <<
                ") Chef: more chickens ... " << m_chickens <<
                " now available ... NOTIFYING ..." << std::endl;
        }
        m_condition.notify_all();
    }

private:
    boost::mutex m_mutex;
    boost::condition m_condition;
    int m_chickens;
};

canteen g_canteen;

void chef()
{
    const int chickens = 4;
    {
        boost::mutex::scoped_lock lock(iomx);
        std::cout << "(" << clock() << ") Chef: starting ..." << std::endl;
    }
    for (;;)
    {
        {
            boost::mutex::scoped_lock lock(iomx);
            std::cout << "(" << clock() << ") Chef: cooking ..." << std::endl;
        }
        boost::xtime xt;
        boost::xtime_get(&xt, boost::TIME_UTC);
        xt.sec += 2;
        boost::thread::sleep(xt);
        {
            boost::mutex::scoped_lock lock(iomx);
            std::cout << "(" << clock() << ") Chef: " << chickens
                      << " chickens, ready-to-go ..." << std::endl;
        }
        g_canteen.put(chickens);
    }
}

struct phil
{
    phil(int id) : m_id(id) { }
    void run() {
        {
            boost::mutex::scoped_lock lock(iomx);
            std::cout << "(" << clock() << ") Phil" << m_id
                      << ": starting ..." << std::endl;
        }
        for (;;)
        {
            if (m_id > 0)
            {
                boost::xtime xt;
                boost::xtime_get(&xt, boost::TIME_UTC);
                xt.sec += 3;
                boost::thread::sleep(xt);
            }
            {
                boost::mutex::scoped_lock lock(iomx);
                std::cout << "(" << clock() << ") Phil" << m_id
                          << ": gotta eat ..." << std::endl;
            }
            g_canteen.get(m_id);
            {
                boost::mutex::scoped_lock lock(iomx);
                std::cout << "(" << clock() << ") Phil" << m_id
                          << ": mmm ... that's good ..." << std::endl;
            }
        }
    }
    static void do_thread(void* param) {
        static_cast<phil*>(param)->run();
    }

    int m_id;
};

struct thread_adapt
{
    thread_adapt(void (*func)(void*), void* param)
        : _func(func), _param(param)
    {
    }
    int operator()() const
    {
        _func(_param);
        return 0;
    }

    void (*_func)(void*);
    void* _param;
};

class thread_adapter
{
public:
    thread_adapter(void (*func)(void*), void* param)
        : _func(func), _param(param)
    {
    }
    void operator()() const { _func(_param); }
private:
    void (*_func)(void*);
    void* _param;
};

int main(int argc, char* argv[])
{
    boost::thread thrd_chef(&chef);
    phil p[] = { phil(0), phil(1), phil(2), phil(3), phil(4) };
    boost::thread thrd_phil0(thread_adapter(&phil::do_thread, &p[0]));
    boost::thread thrd_phil1(thread_adapter(&phil::do_thread, &p[1]));
    boost::thread thrd_phil2(thread_adapter(&phil::do_thread, &p[2]));
    boost::thread thrd_phil3(thread_adapter(&phil::do_thread, &p[3]));
    boost::thread thrd_phil4(thread_adapter(&phil::do_thread, &p[4]));

    thrd_chef.join();
    thrd_phil0.join();
    thrd_phil1.join();
    thrd_phil2.join();
    thrd_phil3.join();
    thrd_phil4.join();

    return 0;
}
