同步队列、线程池模式服务器消息处理类

////////////////////////////////////////////////////////////////////////////////
template<typename message_t>
class message_server_indie : public nocopyable
{
public:
    typedef message_queue< std::shared_ptr<message_t> > message_queue_alias;
////////////////////////////////////////////////////////////////////////////////
public:
    inline message_server_indie(){}

    inline ~message_server_indie()
    {
        stop();
    }

    /*@ start message server: start dispatch message and process it.
    * @ para.thread_size: how many threads to start, if equal to "0", message 
    server will run in a synchronous mode, else it will start number of threads 
    (decicated by "thread_size")and message server run in a asynchronous mode.
    */
    void run(const size_t thread_size)
    {
        // update server state.
        m_state.run();

        // start work thread, if "thread_size"==0, this server will run in a 
        // synchronous mode and message queue will not be init.
        if (thread_size != 0) {    // asynchronous mode    
            m_message_queue.reset(new message_queue_alias());

            m_thread_manager.reset(new thread_manager);
            m_thread_manager->run_thread(std::bind(&message_server::work, this), thread_size);
        }
        // else {}                // synchronous mode
    }

    /*@ stop message server: stop message queue and thread pool. */
    void stop()
    {
        // update server state to notify work thread.
        m_state.stop();

        // close message queue.
        if (m_message_queue != nullptr) {
            m_message_queue->close();
        }

        // wait server stop.
        join();
    }

    /*@ wait server stop.*/
    inline void join()
    {
        std::shared_ptr<thread_manager> thread_p = m_thread_manager;
        if (thread_p != nullptr) {
            thread_p->join_all();
        }
    }

public:
    /*@ push message to message server.
    * @ if server running in synchronous mode, process this message.
    * @ else push this message in message queue.
    */
    inline void post(std::shared_ptr<message_t>& msg)
    {
        if (m_state.is_stoped()) {
            throw std::logic_error("message server is stopped.");
        }

        std::shared_ptr<message_queue_alias> msg_q = m_message_queue;
        if (msg_q == nullptr) {    // synchronous mode
            handle(msg);
        }
        else {                    // asynchronous mode
            msg_q->post(msg);
        }
    }

    /*@ get the message handler.*/
    inline dispatch_handler<message_t>& get_handler() {
        return m_message_handler;
    }

////////////////////////////////////////////////////////////////////////////////
protected:
    /*@ work thread method.    */
    virtual void work()
    {
        while (m_state.is_running()) {
            std::shared_ptr<message_t> msg;
            if (m_message_queue->take(msg)) {
                handle(msg);
            }
        }// end while
    }

    inline void handle(std::shared_ptr<message_t>& msg)
    {
        try {
        }
        catch (std::exception& err) {
            std::cout << "message dispatch handle error: " << err.what();
        }
        catch (...) {
            std::cout << "message dispatch handle unknown error.";
        }
    }

////////////////////////////////////////////////////////////////////////////////
protected:
    // thread pool.
    std::shared_ptr<thread_manager> m_thread_manager;

    // message queue.
    std::shared_ptr<message_queue_alias> m_message_queue;

    // message server state.
    state m_state;
};

 

posted @ 2017-04-20 11:18  略加思索的河马  阅读(311)  评论(0编辑  收藏  举报