2 #ifndef UVCC_REQUEST_MISC__HPP 3 #define UVCC_REQUEST_MISC__HPP 5 #include "uvcc/utility.hpp" 6 #include "uvcc/request-base.hpp" 12 #include <type_traits> 22 template<
typename _Result_ =
void >
26 friend class request::instance< work >;
30 using uv_t = ::uv_work_t;
31 using on_request_t = std::function<
void(
work _request) >;
35 template<
typename... _Args_ >
36 using on_work_t = std::function< _Result_(_Args_&&... _args) >;
45 struct properties :
request::properties
47 std::packaged_task< _Result_() > task;
48 std::shared_future< _Result_ > result;
58 explicit work(uv_t *_uv_req) :
request(
reinterpret_cast<
request::uv_t* >(_uv_req)) {}
65 uv_req = instance::create();
66 static_cast< uv_t* >(uv_req)->type = UV_WORK;
69 work(
const work&) =
default;
70 work& operator =(
const work&) =
default;
72 work(
work&&)
noexcept =
default;
73 work& operator =(
work&&)
noexcept =
default;
76 template<
typename =
void >
static void work_cb(::uv_work_t*);
77 template<
typename =
void >
static void after_work_cb(::uv_work_t*,
int);
80 on_request_t& on_request()
const noexcept {
return instance::from(uv_req)->request_cb_storage.value(); }
84 uv::
loop loop()
const noexcept {
return uv::loop(
static_cast< uv_t* >(uv_req)->loop); }
87 std::shared_future< _Result_ >&
result()
const {
return instance::from(uv_req)->properties().result; }
96 template<
class _Task_,
typename... _Args_,
99 int run(uv::loop &_loop, _Task_&& _task, _Args_&&... _args)
101 auto instance_ptr = instance::from(uv_req);
105 auto &properties = instance_ptr->properties();
107 using task_t =
decltype(properties.task);
108 properties.task = task_t{ std::bind(std::forward< _Task_ >(_task), std::forward< _Args_ >(_args)...) };
109 properties.result = properties.task.get_future().share();
113 auto uv_ret = ::uv_queue_work(
114 static_cast< uv::loop::uv_t* >(_loop),
static_cast< uv_t* >(uv_req),
115 work_cb<>, after_work_cb<>
120 instance_ptr->unref();
127 explicit operator
const uv_t*()
const noexcept {
return static_cast<
const uv_t* >(uv_req); }
128 explicit operator uv_t*()
noexcept {
return static_cast< uv_t* >(uv_req); }
133 void work< _Result_ >::work_cb(::uv_work_t *_uv_req)
135 auto &task = instance::from(_uv_req)->properties().task;
136 if (task.valid()) task();
141 void work< _Result_ >::after_work_cb(::uv_work_t *_uv_req,
int _status)
143 auto instance_ptr = instance::from(_uv_req);
144 instance_ptr->uv_error = _status;
148 auto &after_work_cb = instance_ptr->request_cb_storage.value();
149 if (after_work_cb) after_work_cb(
work(_uv_req));
Namespace for all uvcc definitions.
Work scheduling request type.
constexpr const adopt_ref_t adopt_ref
The tag to be used to prevent ref_guard constructor from increasing reference count of the protected ...
The base class for the libuv requests.
int run(uv::loop &_loop, _Task_ &&_task, _Args_ &&... _args)
Run the request. Queue the _Task_ to the thread pool.
A scoped reference counting guard.
std::shared_future< _Result_ > & result() const
Get the result of the work.
uv::loop loop() const noexcept
The libuv loop that started this work request and where completion will be reported.