<commit_before>#include "evpp/inner_pre.h"

#include "evpp/event_loop.h"
#include "evpp/event_loop_thread.h"

namespace evpp {
    class EventLoopThread::Impl {
    public:
        Impl();
        ~Impl();

        bool Start(bool wait_until_thread_started, const Functor& pre, const Functor& post);
        void Stop(bool wait_thread_exit);

        EventLoop* event_loop() const { return event_loop_.get(); }

        bool IsRunning() const;
        bool IsStopped() const;

        void SetName(const std::string& n);
        const std::string& name() const;

        std::thread::id tid() const;

    private:
        void Run(const Functor& pre, const Functor& post);

    private:
        std::shared_ptr<EventLoop> event_loop_;
        std::shared_ptr<std::thread> thread_;
        enum State {
            kRunning = 1,
            kStopping = 2,
            kStopped = 3,
        };
        State state_;

        std::string name_;
    };


    EventLoopThread::Impl::Impl()
        : event_loop_(new EventLoop)
        , state_(kStopped) {
    }

    EventLoopThread::Impl::~Impl() {
        if (thread_->joinable()) {
            thread_->join();
        }
    }

    bool EventLoopThread::Impl::Start(bool wait_until_thread_started,
        const Functor& pre, const Functor& post) {
        thread_.reset(new std::thread(
            std::bind(&Impl::Run, this, pre, post)));
        // waiting until the thread started
        while (wait_until_thread_started) {
            if (IsRunning()) {
                break;
            }

            usleep(1);
        }

        return true;
    }

    void EventLoopThread::Impl::Run(const Functor& pre, const Functor& post) {
        if (name_.empty()) {
            std::ostringstream os;<commit_msg>Fix a thread exit coredump: Add if (thread_ && thread_->joinable())<commit_after>#include "evpp/inner_pre.h"

#include "evpp/event_loop.h"
#include "evpp/event_loop_thread.h"

namespace evpp {
    class EventLoopThread::Impl {
    public:
        Impl();
        ~Impl();

        bool Start(bool wait_until_thread_started, const Functor& pre, const Functor& post);
        void Stop(bool wait_thread_exit);

        EventLoop* event_loop() const { return event_loop_.get(); }

        bool IsRunning() const;
        bool IsStopped() const;

        void SetName(const std::string& n);
        const std::string& name() const;

        std::thread::id tid() const;

    private:
        void Run(const Functor& pre, const Functor& post);

    private:
        std::shared_ptr<EventLoop> event_loop_;
        std::shared_ptr<std::thread> thread_;
        enum State {
            kRunning = 1,
            kStopping = 2,
            kStopped = 3,
        };
        State state_;

        std::string name_;
    };


    EventLoopThread::Impl::Impl()
        : event_loop_(new EventLoop)
        , state_(kStopped) {
    }

    EventLoopThread::Impl::~Impl() {
        if (thread_ && thread_->joinable()) {
            thread_->join();
        }
    }

    bool EventLoopThread::Impl::Start(bool wait_until_thread_started,
        const Functor& pre, const Functor& post) {
        thread_.reset(new std::thread(
            std::bind(&Impl::Run, this, pre, post)));
        // waiting until the thread started
        while (wait_until_thread_started) {
            if (IsRunning()) {
                break;
            }

            usleep(1);
        }

        return true;
    }

    void EventLoopThread::Impl::Run(const Functor& pre, const Functor& post) {
        if (name_.empty()) {
            std::ostringstream os;
{'fraction_non_alphanumeric': 0.12057922584238373, 'fraction_numerical': 0.002227791701475912, 'mean_word_length': 2.10995670995671, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3068634', 'n_tokens_mistral': 1090, 'n_tokens_neox': 1044, 'n_words': 246}