#include "poll.h"
#include <thread>

namespace myapp::modbus {

std::shared_ptr<poll> poll::create()
{
    return std::make_shared<poll_impl>();
}

void poll_impl::run()
{
    std::thread([self = shared_from_this()]
    {
        self->aborted_ = false;
        for (task_t task;
             !self->aborted_ && self->next_task(task);)
        {
            if (task)
                task();
        }
    }).detach();
}

bool poll_impl::next_task(task_t& task)
{
    std::lock_guard<std::mutex> lock(mutex_);
    if (tasks_.empty())
        return false;

    task = std::move(tasks_.front());
    tasks_.pop();
    return true;
}

void poll_impl::abort()
{
    aborted_ = true;
}

poll::task_executor_t poll_impl::executor()
{
    return [self = shared_from_this()] (poll::task_t task_to_add)
    {
        std::lock_guard<std::mutex> lock(self->mutex_);
        self->tasks_.emplace(std::move(task_to_add));
    };
}

} /* namespace myapp::modbus */
