#pragma once #include #include #include #include #include #include #include namespace node_mbgl { namespace util { template class AsyncQueue { public: AsyncQueue(uv_loop_t *loop, std::function fn) : callback(std::move(fn)) { async.data = this; uv_async_init(loop, &async, [](uv_async_t* handle) { auto q = reinterpret_cast(handle->data); q->process(); }); } ~AsyncQueue() = default; void send(T &&data) { { std::lock_guard lock(mutex); queue.push(std::make_unique(std::move(data))); } uv_async_send(&async); } void send(std::unique_ptr data) { { std::lock_guard lock(mutex); queue.push(std::move(data)); } uv_async_send(&async); } void stop() { uv_close(reinterpret_cast(&async), [](uv_handle_t *handle) { delete reinterpret_cast(handle->data); }); } void ref() { uv_ref(reinterpret_cast(&async)); } void unref() { uv_unref(reinterpret_cast(&async)); } private: void process() { std::unique_ptr item; while (true) { mutex.lock(); if (queue.empty()) { mutex.unlock(); break; } item = std::move(queue.front()); queue.pop(); mutex.unlock(); callback(*item); } } private: std::mutex mutex; uv_async_t async; std::queue> queue; std::function callback; }; } // namespace util } // namespace node_mbgl