First
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <future>
|
||||
#include <tl/deque.h>
|
||||
#include <tl/functional.h>
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
||||
class async_queue
|
||||
{
|
||||
public:
|
||||
using Item = function<void()>;
|
||||
|
||||
void enqueue(Item func) noexcept
|
||||
{
|
||||
std::lock_guard lg(m_mutex);
|
||||
m_items.push_back(std::move(func));
|
||||
}
|
||||
|
||||
bool run_one() noexcept
|
||||
{
|
||||
std::unique_lock lg(m_mutex);
|
||||
if (m_items.empty())
|
||||
return false;
|
||||
|
||||
const Item item = std::move(m_items.front());
|
||||
m_items.pop_front();
|
||||
lg.unlock();
|
||||
|
||||
item();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool run() noexcept
|
||||
{
|
||||
std::unique_lock lg(m_mutex);
|
||||
if (m_items.empty())
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
Item item = std::move(m_items.front());
|
||||
m_items.pop_front();
|
||||
lg.unlock();
|
||||
|
||||
item();
|
||||
|
||||
lg.lock();
|
||||
} while (!m_items.empty());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex m_mutex;
|
||||
|
||||
deque<Item> m_items;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename Res, typename Func>
|
||||
std::future<Res> async(async_queue& queue, Func&& func) noexcept
|
||||
{
|
||||
shared_ptr<std::promise<Res>> promise = make_shared<std::promise<Res>>();
|
||||
auto future = promise->get_future();
|
||||
queue.enqueue([promise = std::move(promise), func = std::move(func)]()
|
||||
{
|
||||
if constexpr (tl::is_same_v<Res, void>)
|
||||
{
|
||||
func();
|
||||
promise->set_value();
|
||||
}
|
||||
else
|
||||
promise->set_value(func());
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
bool is_ready(std::future<R> const& f) noexcept
|
||||
{
|
||||
return f.valid() && f.wait_until(std::chrono::system_clock::time_point::min()) == std::future_status::ready;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user