1 #pragma once 2 3 4 #include <functional> 5 #include <utility> 6 #include <memory> 7 #include <uv.h> 8 #include "request.hpp" 9 #include "loop.hpp" 10 11 12 namespace uvw { 13 14 15 /** 16 * @brief WorkEvent event. 17 * 18 * It will be emitted by WorkReq according with its functionalities. 19 */ 20 struct WorkEvent {}; 21 22 23 /** 24 * @brief The WorkReq request. 25 * 26 * It runs user code using a thread from the threadpool and gets notified in the 27 * loop thread by means of an event. 28 * 29 * To create a `WorkReq` through a `Loop`, arguments follow: 30 * 31 * * A valid instance of a `Task`, that is of type `std::function<void(void)>`. 32 * 33 * See the official 34 * [documentation](http://docs.libuv.org/en/v1.x/threadpool.html) 35 * for further details. 36 */ 37 class WorkReq final: public Request<WorkReq, uv_work_t> { 38 using InternalTask = std::function<void(void)>; 39 workCallback(uv_work_t * req)40 static void workCallback(uv_work_t *req) { 41 static_cast<WorkReq*>(req->data)->task(); 42 } 43 44 public: 45 using Task = InternalTask; 46 WorkReq(ConstructorAccess ca,std::shared_ptr<Loop> ref,InternalTask t)47 explicit WorkReq(ConstructorAccess ca, std::shared_ptr<Loop> ref, InternalTask t) 48 : Request{ca, std::move(ref)}, task{t} 49 {} 50 51 /** 52 * @brief Runs the given task in a separate thread. 53 * 54 * A WorkEvent event will be emitted on the loop thread when the task is 55 * finished.<br/> 56 * This request can be cancelled with `cancel()`. 57 */ queue()58 void queue() { 59 invoke(&uv_queue_work, parent(), get(), &workCallback, &defaultCallback<WorkEvent>); 60 } 61 62 private: 63 Task task{}; 64 }; 65 66 67 } 68