github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/util/quitable_thread.h (about)

     1  // Copyright (C) 2018 go-nebulas authors
     2  //
     3  // This file is part of the go-nebulas library.
     4  //
     5  // the go-nebulas library is free software: you can redistribute it and/or
     6  // modify
     7  // it under the terms of the GNU General Public License as published by
     8  // the Free Software Foundation, either version 3 of the License, or
     9  // (at your option) any later version.
    10  //
    11  // the go-nebulas library is distributed in the hope that it will be useful,
    12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  // GNU General Public License for more details.
    15  //
    16  // You should have received a copy of the GNU General Public License
    17  // along with the go-nebulas library.  If not, see
    18  // <http://www.gnu.org/licenses/>.
    19  //
    20  #pragma once
    21  #include "common/common.h"
    22  #include "core/command.h"
    23  #include "util/wakeable_queue.h"
    24  #include <atomic>
    25  #include <thread>
    26  
    27  namespace neb {
    28  namespace util {
    29  class quitable_thread {
    30  public:
    31    quitable_thread();
    32    virtual ~quitable_thread();
    33  
    34    virtual void start();
    35    virtual void stop();
    36    virtual void thread_func() = 0;
    37  
    38  protected:
    39    std::unique_ptr<std::thread> m_thread;
    40    std::atomic_bool m_exit_flag;
    41  };
    42  
    43  class wakeable_thread : public quitable_thread {
    44  public:
    45    wakeable_thread();
    46    template <typename Func> void schedule(Func &&f) {
    47      m_queue.push_back(std::make_shared<std::function<void()>>(f));
    48      if (!m_started) {
    49        m_started = true;
    50        neb::core::command_queue::instance()
    51            .listen_command<neb::core::exit_command>(
    52                this, [this](const std::shared_ptr<neb::core::exit_command> &) {
    53                  m_queue.wake_up_if_empty();
    54                });
    55        start();
    56      }
    57    }
    58    virtual void thread_func();
    59    inline size_t size() const { return m_queue.size(); }
    60  
    61  protected:
    62    typedef std::shared_ptr<std::function<void()>> func_ptr;
    63    using queue_t = wakeable_queue<func_ptr>;
    64    queue_t m_queue;
    65    bool m_started;
    66  };
    67  } // namespace util
    68  } // namespace neb