#pragma once #include #include #include #include #include #include #if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 #define UV_ASYNC_PARAMS(handle) uv_async_t *handle, int #else #define UV_ASYNC_PARAMS(handle) uv_async_t *handle #endif namespace node_mbgl { namespace util { template class AsyncQueue { public: AsyncQueue(uv_loop_t *loop, std::function fn) : callback(fn) { async.data = this; uv_async_init(loop, &async, [](UV_ASYNC_PARAMS(handle)) { auto q = reinterpret_cast(handle->data); q->process(); }); } 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((uv_handle_t *)&async, [](uv_handle_t *handle) { delete reinterpret_cast(handle->data); }); } void ref() { uv_ref((uv_handle_t *)&async); } void unref() { uv_unref((uv_handle_t *)&async); } private: ~AsyncQueue() { } 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; }; } }