#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 mbgl { namespace util { class AsyncTask::Impl { public: Impl(std::function&& fn) : async(new uv_async_t), task(std::move(fn)) { uv_loop_t* loop = reinterpret_cast(RunLoop::getLoopHandle()); if (uv_async_init(loop, async, asyncCallback) != 0) { throw std::runtime_error("Failed to initialize async."); } handle()->data = this; } ~Impl() { uv_close(handle(), [](uv_handle_t* h) { delete reinterpret_cast(h); }); } void maySend() { // uv_async_send will do the call coalescing for us. if (uv_async_send(async) != 0) { throw std::runtime_error("Failed to async send."); } } void unref() { uv_unref(handle()); } private: static void asyncCallback(UV_ASYNC_PARAMS(handle)) { reinterpret_cast(handle->data)->task(); } uv_handle_t* handle() { return reinterpret_cast(async); } uv_async_t* async; std::function task; }; AsyncTask::AsyncTask(std::function&& fn) : impl(std::make_unique(std::move(fn))) { } AsyncTask::~AsyncTask() { } void AsyncTask::send() { impl->maySend(); } void AsyncTask::unref() { impl->unref(); } } }