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