2 #ifndef UVCC_HANDLE_MISC__HPP 3 #define UVCC_HANDLE_MISC__HPP 5 #include "uvcc/utility.hpp" 6 #include "uvcc/handle-base.hpp" 7 #include "uvcc/handle-io.hpp" 28 friend class handle::uv_interface;
29 friend class handle::instance< async >;
33 using uv_t = ::uv_async_t;
34 using on_send_t = std::function<
void(
async _handle) >;
46 struct properties :
handle::properties
51 struct uv_interface :
handle::uv_handle_interface {};
60 template <
typename =
void >
static void async_cb(::uv_async_t*);
64 explicit async(uv_t *_uv_handle) :
handle(
reinterpret_cast<
handle::uv_t* >(_uv_handle)) {}
70 async(
const async&) =
default;
73 async(
async&&)
noexcept =
default;
80 uv_handle = instance::create();
82 auto uv_ret = ::uv_async_init(
static_cast< uv::loop::uv_t* >(_loop),
static_cast< uv_t* >(uv_handle), async_cb);
83 if (uv_status(uv_ret) < 0)
return;
85 instance::from(uv_handle)->book_loop();
90 on_send_t&
on_send()
const noexcept {
return instance::from(uv_handle)->properties().async_cb; }
96 auto instance_ptr = instance::from(uv_handle);
102 auto uv_ret = ::uv_async_send(
static_cast< uv_t* >(uv_handle));
106 instance_ptr->unref();
119 template<
class _Cb_,
typename... _Args_,
typename =
std::
enable_if_t<
125 int send(_Cb_ &&_cb, _Args_&&... _args)
const 127 instance::from(uv_handle)->properties().async_cb = std::bind(
128 std::forward< _Cb_ >(_cb), std::placeholders::_1, std::forward< _Args_ >(_args)...
134 explicit operator
const uv_t*()
const noexcept {
return static_cast<
const uv_t* >(uv_handle); }
135 explicit operator uv_t*()
noexcept {
return static_cast< uv_t* >(uv_handle); }
139 void async::async_cb(::uv_async_t *_uv_handle)
141 auto instance_ptr = instance::from(_uv_handle);
142 auto &async_cb = instance_ptr->properties().async_cb;
144 ref_guard< instance > unref_handle(*instance_ptr, adopt_ref);
146 if (async_cb) async_cb(async(_uv_handle));
157 friend class handle::uv_interface;
158 friend class handle::instance< timer >;
162 using uv_t = ::uv_timer_t;
163 using on_timer_t = std::function<
void(
timer _handle) >;
171 struct properties :
handle::properties
173 bool has_extra_ref =
false;
177 struct uv_interface :
handle::uv_handle_interface {};
186 template <
typename =
void >
static void timer_cb(::uv_timer_t*);
190 explicit timer(uv_t *_uv_handle) :
handle(
reinterpret_cast<
handle::uv_t* >(_uv_handle)) {}
196 timer(
const timer&) =
default;
199 timer(
timer&&)
noexcept =
default;
200 timer& operator =(
timer&&)
noexcept =
default;
206 uv_handle = instance::create();
208 auto uv_ret = ::uv_timer_init(
static_cast<
uv::
loop::uv_t* >(_loop),
static_cast< uv_t* >(uv_handle));
209 if (uv_status(uv_ret) < 0)
return;
211 ::uv_timer_set_repeat(
static_cast< uv_t* >(uv_handle), _repeat_interval);
213 instance::from(uv_handle)->book_loop();
218 uint64_t
repeat_interval()
const noexcept {
return ::uv_timer_get_repeat(
static_cast< uv_t* >(uv_handle)); }
222 void repeat_interval(uint64_t _value)
noexcept { ::uv_timer_set_repeat(
static_cast< uv_t* >(uv_handle), _value); }
225 on_timer_t&
on_timer()
const noexcept {
return instance::from(uv_handle)->properties().timer_cb; }
238 auto instance_ptr = instance::from(uv_handle);
239 auto &properties = instance_ptr->properties();
241 if (!properties.has_extra_ref)
244 properties.has_extra_ref =
true;
248 auto uv_ret = ::uv_timer_start(
static_cast< uv_t* >(uv_handle), timer_cb,
249 _timeout, ::uv_timer_get_repeat(
static_cast< uv_t* >(uv_handle))
254 properties.has_extra_ref =
false;
255 instance_ptr->unref();
270 template<
class _Cb_,
typename... _Args_,
typename =
std::
enable_if_t<
276 int start(uint64_t _timeout, _Cb_ &&_cb, _Args_&&... _args)
const 278 instance::from(uv_handle)->properties().timer_cb = std::bind(
279 std::forward< _Cb_ >(_cb), std::placeholders::_1, std::forward< _Args_ >(_args)...
288 auto instance_ptr = instance::from(uv_handle);
289 auto &properties = instance_ptr->properties();
291 auto uv_ret = uv_status(::uv_timer_stop(
static_cast< uv_t* >(uv_handle)));
293 if (properties.has_extra_ref)
295 properties.has_extra_ref =
false;
296 instance_ptr->unref();
303 explicit operator
const uv_t*()
const noexcept {
return static_cast<
const uv_t* >(uv_handle); }
304 explicit operator uv_t*()
noexcept {
return static_cast< uv_t* >(uv_handle); }
308 void timer::timer_cb(::uv_timer_t *_uv_handle)
310 auto instance_ptr = instance::from(_uv_handle);
311 auto &properties = instance_ptr->properties();
314 uvcc_debug_log_if(
true,
"timer [0x%08tX]: repeat_interval=%llu is_active=%i\n",
315 (ptrdiff_t)_uv_handle, ::uv_timer_get_repeat(_uv_handle), ::uv_is_active((::uv_handle_t*)_uv_handle)
319 if (::uv_timer_get_repeat(_uv_handle) == 0
and properties.has_extra_ref)
321 ref_guard< instance > unref_handle(*instance_ptr, adopt_ref);
322 if (properties.timer_cb) properties.timer_cb(timer(_uv_handle));
325 if (properties.timer_cb) properties.timer_cb(timer(_uv_handle));
474 int stop()
const noexcept 523 friend class handle::uv_interface;
524 friend class handle::instance< idle >;
528 using uv_t = ::uv_idle_t;
529 using on_idle_t = std::function<
void(
idle _handle) >;
537 enum class opcmd { UNKNOWN, STOP, START };
539 struct properties :
handle::properties
541 opcmd opcmd_state = opcmd::UNKNOWN;
545 struct uv_interface :
handle::uv_handle_interface {};
554 template <
typename =
void >
static void idle_cb(::uv_idle_t*);
558 explicit idle(uv_t *_uv_handle) :
handle(
reinterpret_cast<
handle::uv_t* >(_uv_handle)) {}
564 idle(
const idle&) =
default;
565 idle& operator =(
const idle&) =
default;
567 idle(
idle&&)
noexcept =
default;
568 idle& operator =(
idle&&)
noexcept =
default;
573 uv_handle = instance::create();
575 auto uv_ret = ::uv_idle_init(
static_cast<
uv::
loop::uv_t* >(_loop),
static_cast< uv_t* >(uv_handle));
576 if (uv_status(uv_ret) < 0)
return;
578 instance::from(uv_handle)->book_loop();
583 on_idle_t&
on_idle()
const noexcept {
return instance::from(uv_handle)->properties().idle_cb; }
592 auto instance_ptr = instance::from(uv_handle);
593 auto &properties = instance_ptr->properties();
595 auto opcmd_state0 = properties.opcmd_state;
597 properties.opcmd_state = opcmd::START;
600 switch (opcmd_state0)
607 instance_ptr->unref();
612 auto uv_ret = ::uv_idle_start(
static_cast< uv_t* >(uv_handle), idle_cb);
616 properties.opcmd_state = opcmd::UNKNOWN;
617 instance_ptr->unref();
636 int start(_Cb_ &&_cb, _Args_&&... _args)
const 638 on_idle() = std::bind(std::forward< _Cb_ >(_cb), std::placeholders::_1, std::forward< _Args_ >(_args)...);
645 auto instance_ptr = instance::from(uv_handle);
646 auto &opcmd_state = instance_ptr->properties().opcmd_state;
648 auto opcmd_state0 = opcmd_state;
649 opcmd_state = opcmd::STOP;
651 auto uv_ret = uv_status(::uv_idle_stop(
static_cast< uv_t* >(uv_handle)));
653 switch (opcmd_state0)
659 instance_ptr->unref();
667 explicit operator
const uv_t*()
const noexcept {
return static_cast<
const uv_t* >(uv_handle); }
668 explicit operator uv_t*()
noexcept {
return static_cast< uv_t* >(uv_handle); }
672 void idle::idle_cb(::uv_idle_t *_uv_handle)
674 auto &idle_cb = instance::from(_uv_handle)->properties().idle_cb;
675 if (idle_cb) idle_cb(idle(_uv_handle));
684 friend class handle::uv_interface;
685 friend class handle::instance< prepare >;
689 using uv_t = ::uv_prepare_t;
690 using on_prepare_t = std::function<
void(
prepare _handle) >;
698 enum class opcmd { UNKNOWN, STOP, START };
700 struct properties :
handle::properties
702 opcmd opcmd_state = opcmd::UNKNOWN;
703 on_prepare_t prepare_cb;
706 struct uv_interface :
handle::uv_handle_interface {};
715 template <
typename =
void >
static void prepare_cb(::uv_prepare_t*);
719 explicit prepare(uv_t *_uv_handle) :
handle(
reinterpret_cast<
handle::uv_t* >(_uv_handle)) {}
723 ~prepare() =
default;
725 prepare(
const prepare&) =
default;
728 prepare(
prepare&&)
noexcept =
default;
734 uv_handle = instance::create();
736 auto uv_ret = ::uv_prepare_init(
static_cast<
uv::
loop::uv_t* >(_loop),
static_cast< uv_t* >(uv_handle));
737 if (uv_status(uv_ret) < 0)
return;
739 instance::from(uv_handle)->book_loop();
744 on_prepare_t&
on_prepare()
const noexcept {
return instance::from(uv_handle)->properties().prepare_cb; }
753 auto instance_ptr = instance::from(uv_handle);
754 auto &properties = instance_ptr->properties();
756 auto opcmd_state0 = properties.opcmd_state;
758 properties.opcmd_state = opcmd::START;
761 switch (opcmd_state0)
768 instance_ptr->unref();
773 auto uv_ret = ::uv_prepare_start(
static_cast< uv_t* >(uv_handle), prepare_cb);
777 properties.opcmd_state = opcmd::UNKNOWN;
778 instance_ptr->unref();
797 int start(_Cb_ &&_cb, _Args_&&... _args)
const 799 on_prepare() = std::bind(std::forward< _Cb_ >(_cb), std::placeholders::_1, std::forward< _Args_ >(_args)...);
806 auto instance_ptr = instance::from(uv_handle);
807 auto &opcmd_state = instance_ptr->properties().opcmd_state;
809 auto opcmd_state0 = opcmd_state;
810 opcmd_state = opcmd::STOP;
812 auto uv_ret = uv_status(::uv_prepare_stop(
static_cast< uv_t* >(uv_handle)));
814 switch (opcmd_state0)
820 instance_ptr->unref();
828 explicit operator
const uv_t*()
const noexcept {
return static_cast<
const uv_t* >(uv_handle); }
829 explicit operator uv_t*()
noexcept {
return static_cast< uv_t* >(uv_handle); }
833 void prepare::prepare_cb(::uv_prepare_t *_uv_handle)
835 auto &prepare_cb = instance::from(_uv_handle)->properties().prepare_cb;
836 if (prepare_cb) prepare_cb(prepare(_uv_handle));
845 friend class handle::uv_interface;
846 friend class handle::instance< check >;
850 using uv_t = ::uv_check_t;
851 using on_check_t = std::function<
void(
check _handle) >;
859 enum class opcmd { UNKNOWN, STOP, START };
861 struct properties :
handle::properties
863 opcmd opcmd_state = opcmd::UNKNOWN;
867 struct uv_interface :
handle::uv_handle_interface {};
876 template <
typename =
void >
static void check_cb(::uv_check_t*);
880 explicit check(uv_t *_uv_handle) :
handle(
reinterpret_cast<
handle::uv_t* >(_uv_handle)) {}
886 check(
const check&) =
default;
889 check(
check&&)
noexcept =
default;
890 check& operator =(
check&&)
noexcept =
default;
895 uv_handle = instance::create();
897 auto uv_ret = ::uv_check_init(
static_cast<
uv::
loop::uv_t* >(_loop),
static_cast< uv_t* >(uv_handle));
898 if (uv_status(uv_ret) < 0)
return;
900 instance::from(uv_handle)->book_loop();
905 on_check_t&
on_check()
const noexcept {
return instance::from(uv_handle)->properties().check_cb; }
914 auto instance_ptr = instance::from(uv_handle);
915 auto &properties = instance_ptr->properties();
917 auto opcmd_state0 = properties.opcmd_state;
919 properties.opcmd_state = opcmd::START;
922 switch (opcmd_state0)
929 instance_ptr->unref();
934 auto uv_ret = ::uv_check_start(
static_cast< uv_t* >(uv_handle), check_cb);
938 properties.opcmd_state = opcmd::UNKNOWN;
939 instance_ptr->unref();
958 int start(_Cb_ &&_cb, _Args_&&... _args)
const 960 on_check() = std::bind(std::forward< _Cb_ >(_cb), std::placeholders::_1, std::forward< _Args_ >(_args)...);
967 auto instance_ptr = instance::from(uv_handle);
968 auto &opcmd_state = instance_ptr->properties().opcmd_state;
970 auto opcmd_state0 = opcmd_state;
971 opcmd_state = opcmd::STOP;
973 auto uv_ret = uv_status(::uv_check_stop(
static_cast< uv_t* >(uv_handle)));
975 switch (opcmd_state0)
981 instance_ptr->unref();
989 explicit operator
const uv_t*()
const noexcept {
return static_cast<
const uv_t* >(uv_handle); }
990 explicit operator uv_t*()
noexcept {
return static_cast< uv_t* >(uv_handle); }
994 void check::check_cb(::uv_check_t *_uv_handle)
996 auto &check_cb = instance::from(_uv_handle)->properties().check_cb;
997 if (check_cb) check_cb(check(_uv_handle));
1012 friend class handle::uv_interface;
1013 friend class handle::instance< signal >;
1017 using uv_t = ::uv_signal_t;
1018 using on_signal_t = std::function<
void(
signal _handle,
bool _oneshot) >;
1028 enum class opcmd { UNKNOWN, STOP, START, START_ONESHOT };
1030 struct properties :
handle::properties
1032 opcmd opcmd_state = opcmd::UNKNOWN;
1034 on_signal_t signal_cb;
1037 struct uv_interface :
handle::uv_handle_interface {};
1046 template <
typename =
void >
static void signal_cb(::uv_signal_t*,
int);
1050 explicit signal(uv_t *_uv_handle) :
handle(
reinterpret_cast<
handle::uv_t* >(_uv_handle)) {}
1054 ~signal() =
default;
1056 signal(
const signal&) =
default;
1059 signal(
signal&&)
noexcept =
default;
1065 uv_handle = instance::create();
1067 auto uv_ret = ::uv_signal_init(
static_cast<
uv::
loop::uv_t* >(_loop),
static_cast< uv_t* >(uv_handle));
1068 instance::from(uv_handle)->properties().signum = _signum;
1070 if (uv_status(uv_ret) < 0)
return;
1072 instance::from(uv_handle)->book_loop();
1077 int start(opcmd _startcmd_state)
const 1079 switch (_startcmd_state)
1081 case opcmd::UNKNOWN:
1083 throw std::invalid_argument(
__PRETTY_FUNCTION__);
1086 case opcmd::START_ONESHOT:
1090 auto instance_ptr = instance::from(uv_handle);
1091 auto &properties = instance_ptr->properties();
1093 auto opcmd_state0 = properties.opcmd_state;
1095 properties.opcmd_state = _startcmd_state;
1096 instance_ptr->ref();
1098 switch (opcmd_state0)
1100 case opcmd::UNKNOWN:
1104 case opcmd::START_ONESHOT:
1106 instance_ptr->unref();
1111 auto uv_ret = ::uv_signal_start(
static_cast< uv_t* >(uv_handle), signal_cb, properties.signum);
1115 properties.opcmd_state = opcmd::UNKNOWN;
1116 instance_ptr->unref();
1127 auto signum =
static_cast< uv_t* >(uv_handle)->signum;
1128 return signum ? signum : instance::from(uv_handle)->properties().signum;
1132 on_signal_t&
on_signal()
const noexcept {
return instance::from(uv_handle)->properties().signal_cb; }
1140 int start()
const {
return start(opcmd::START); }
1155 int start(_Cb_ &&_cb, _Args_&&... _args)
const 1157 instance::from(uv_handle)->properties().signal_cb = std::bind(
1158 std::forward< _Cb_ >(_cb), std::placeholders::_1, std::placeholders::_2, std::forward< _Args_ >(_args)...
1160 return start(opcmd::START);
1178 int start(
int _signum, _Cb_ &&_cb, _Args_&&... _args)
const 1180 instance::from(uv_handle)->properties().signum = _signum;
1181 instance::from(uv_handle)->properties().signal_cb = std::bind(
1182 std::forward< _Cb_ >(_cb), std::placeholders::_1, std::placeholders::_2, std::forward< _Args_ >(_args)...
1184 return start(opcmd::START);
1187 #if (UV_VERSION_MAJOR
>= 1
) && (UV_VERSION_MINOR
>= 12
) 1202 auto instance_ptr = instance::from(uv_handle);
1203 auto &opcmd_state = instance_ptr->properties().opcmd_state;
1205 auto opcmd_state0 = opcmd_state;
1206 opcmd_state = opcmd::STOP;
1208 auto uv_ret = uv_status(::uv_signal_stop(
static_cast< uv_t* >(uv_handle)));
1210 switch (opcmd_state0)
1212 case opcmd::UNKNOWN:
1216 case opcmd::START_ONESHOT:
1217 instance_ptr->unref();
1225 explicit operator
const uv_t*()
const noexcept {
return static_cast<
const uv_t* >(uv_handle); }
1226 explicit operator uv_t*()
noexcept {
return static_cast< uv_t* >(uv_handle); }
1229 template<
typename >
1230 void signal::signal_cb(::uv_signal_t *_uv_handle,
int)
1232 auto instance_ptr = instance::from(_uv_handle);
1233 auto &signal_cb = instance_ptr->properties().signal_cb;
1235 if (instance_ptr->properties().opcmd_state == opcmd::START_ONESHOT)
1237 instance_ptr->properties().opcmd_state = opcmd::UNKNOWN;
1238 ref_guard< instance > unref_handle(*instance_ptr, adopt_ref);
1240 if (signal_cb) signal_cb(signal(_uv_handle),
true);
1243 if (signal_cb) signal_cb(signal(_uv_handle),
false);
1254 friend class handle::uv_interface;
1255 friend class handle::instance< process >;
1259 using uv_t = ::uv_process_t;
1260 using on_exit_t = std::function<
void(
process _handle, int64_t _exit_status,
int _termination_signal) >;
1269 struct properties :
handle::properties
1271 struct stdio_container : ::uv_stdio_container_t
1273 stdio_container()
noexcept 1279 struct stdio_endpoint :
io 1281 stdio_endpoint()
noexcept =
default;
1284 ::uv_process_options_t spawn_options = { 0,};
1286 std::vector< stdio_container > stdio_uv_containers;
1287 std::vector< stdio_endpoint > stdio_uvcc_endpoints;
1291 spawn_options.exit_cb = process::exit_cb;
1294 void ensure_stdio_number(
unsigned _target_fd_number)
1296 if (_target_fd_number >= stdio_uv_containers.size())
1298 stdio_uv_containers.resize(_target_fd_number + 1);
1299 stdio_uvcc_endpoints.resize(_target_fd_number + 1);
1301 spawn_options.stdio_count = stdio_uv_containers.size();
1302 spawn_options.stdio = stdio_uv_containers.data();
1307 struct uv_interface :
handle::uv_handle_interface {};
1316 template <
typename =
void >
static void exit_cb(::uv_process_t*, int64_t,
int);
1320 explicit process(uv_t *_uv_handle) :
handle(
reinterpret_cast<
handle::uv_t* >(_uv_handle)) {}
1324 ~process() =
default;
1326 process(
const process&) =
default;
1329 process(
process&&)
noexcept =
default;
1335 uv_handle = instance::create();
1336 static_cast< uv_t* >(uv_handle)->loop =
static_cast<
loop::uv_t* >(_loop);
1337 instance::from(uv_handle)->book_loop();
1347 static int kill(
int _pid,
int _signum)
noexcept {
return ::uv_kill(_pid, _signum); }
1350 int pid()
const noexcept {
return static_cast< uv_t* >(uv_handle)->pid; }
1356 on_exit_t&
on_exit()
const noexcept {
return instance::from(uv_handle)->properties().exit_cb; }
1361 auto &spawn_options = instance::from(uv_handle)->properties().spawn_options;
1362 spawn_options.env = _envp;
1368 auto &spawn_options = instance::from(uv_handle)->properties().spawn_options;
1369 spawn_options.cwd = _cwd;
1379 auto &properties = instance::from(uv_handle)->properties();
1381 properties.ensure_stdio_number(_target_fd_number);
1389 properties.stdio_uv_containers[_target_fd_number].flags = UV_INHERIT_STREAM;
1390 properties.stdio_uv_containers[_target_fd_number].data.stream =
static_cast< stream::uv_t* >(
static_cast< stream& >(_io));
1393 properties.stdio_uv_containers[_target_fd_number].flags = UV_INHERIT_FD;
1394 properties.stdio_uv_containers[_target_fd_number].data.fd =
static_cast< file& >(_io).fd();
1397 properties.stdio_uv_containers[_target_fd_number].flags = UV_IGNORE;
1398 properties.stdio_uv_containers[_target_fd_number].data.fd = -1;
1401 properties.stdio_uvcc_endpoints[_target_fd_number] =
static_cast< properties::stdio_endpoint&& >(_io);
1407 auto &properties = instance::from(uv_handle)->properties();
1409 properties.ensure_stdio_number(_target_fd_number);
1411 properties.stdio_uv_containers[_target_fd_number].flags = UV_INHERIT_FD;
1412 properties.stdio_uv_containers[_target_fd_number].data.fd = _fd;
1423 auto &properties = instance::from(uv_handle)->properties();
1425 properties.ensure_stdio_number(_target_fd_number);
1427 pipe p(_pipe_loop, _ipc);
1430 int flags = UV_CREATE_PIPE;
1431 if (_pipe_flags & UV_READABLE_PIPE) flags |= UV_READABLE_PIPE;
1432 if (_pipe_flags & UV_WRITABLE_PIPE) flags |= UV_WRITABLE_PIPE;
1433 properties.stdio_uv_containers[_target_fd_number].flags =
static_cast< ::uv_stdio_flags >(flags);
1434 properties.stdio_uv_containers[_target_fd_number].data.stream =
static_cast< stream::uv_t* >(p);
1436 properties.stdio_uvcc_endpoints[_target_fd_number] =
static_cast< properties::stdio_endpoint&& >(
static_cast< io& >(p));
1443 auto &properties = instance::from(uv_handle)->properties();
1444 return reinterpret_cast< std::vector< io >& >(properties.stdio_uvcc_endpoints);
1455 auto &spawn_options = instance::from(uv_handle)->properties().spawn_options;
1457 spawn_options.flags &= ~UV_PROCESS_SETUID;
1459 spawn_options.flags |= UV_PROCESS_SETUID;
1460 spawn_options.uid = _uid;
1471 auto &spawn_options = instance::from(uv_handle)->properties().spawn_options;
1473 spawn_options.flags &= ~UV_PROCESS_SETGID;
1475 spawn_options.flags |= UV_PROCESS_SETGID;
1476 spawn_options.gid = _gid;
1485 int spawn(
const char *_file,
char *_argv[], ::uv_process_flags _flags =
static_cast< ::uv_process_flags >(0))
const noexcept 1487 auto &properties = instance::from(uv_handle)->properties();
1489 properties.spawn_options.file = _file;
1490 properties.spawn_options.args = _argv;
1491 properties.spawn_options.flags |= _flags;
1495 ::uv_spawn(
static_cast< uv_t* >(uv_handle)->loop,
static_cast< uv_t* >(uv_handle), &properties.spawn_options)
1498 int spawn(
const char *_file,
const char *_argv[], ::uv_process_flags _flags =
static_cast< ::uv_process_flags >(0))
const noexcept 1500 return spawn(_file
, const_cast<
char** >(_argv)
, _flags
);
1504 int kill(
int _signum)
const noexcept 1506 return uv_status(::uv_process_kill(
static_cast< uv_t* >(uv_handle), _signum));
1510 explicit operator
const uv_t*()
const noexcept {
return static_cast<
const uv_t* >(uv_handle); }
1511 explicit operator uv_t*()
noexcept {
return static_cast< uv_t* >(uv_handle); }
1514 template<
typename >
1515 void process::exit_cb(::uv_process_t* _uv_handle, int64_t _exit_status,
int _termination_signal)
1517 auto &exit_cb = instance::from(_uv_handle)->properties().exit_cb;
1518 if (exit_cb) exit_cb(process(_uv_handle), _exit_status, _termination_signal);
1529 friend class handle::uv_interface;
1530 friend class handle::instance< poll >;
1534 using uv_t = ::uv_poll_t;
1535 using on_poll_t = std::function<
void(
poll _handle,
int _events) >;
1543 enum class opcmd { UNKNOWN, STOP, START };
1545 struct properties :
handle::properties
1547 opcmd opcmd_state = opcmd::UNKNOWN;
1551 struct uv_interface :
handle::uv_handle_interface {};
1560 template <
typename =
void >
static void poll_cb(::uv_poll_t*,
int,
int);
1564 explicit poll(uv_t *_uv_handle) :
handle(
reinterpret_cast<
handle::uv_t* >(_uv_handle)) {}
1570 poll(
const poll&) =
default;
1571 poll& operator =(
const poll&) =
default;
1573 poll(
poll&&)
noexcept =
default;
1574 poll& operator =(
poll&&)
noexcept =
default;
1580 uv_handle = instance::create();
1582 auto uv_ret = ::uv_poll_init(
static_cast<
uv::
loop::uv_t* >(_loop),
static_cast< uv_t* >(uv_handle), _fd);
1583 if (uv_status(uv_ret) < 0)
return;
1585 instance::from(uv_handle)->book_loop();
1604 on_poll_t&
on_poll()
const noexcept {
return instance::from(uv_handle)->properties().poll_cb; }
1613 auto instance_ptr = instance::from(uv_handle);
1614 auto &properties = instance_ptr->properties();
1616 auto opcmd_state0 = properties.opcmd_state;
1618 properties.opcmd_state = opcmd::START;
1619 instance_ptr->ref();
1621 switch (opcmd_state0)
1623 case opcmd::UNKNOWN:
1628 instance_ptr->unref();
1633 auto uv_ret = ::uv_poll_start(
static_cast< uv_t* >(uv_handle), _events, poll_cb);
1637 properties.opcmd_state = opcmd::UNKNOWN;
1638 instance_ptr->unref();
1657 int start(
int _events, _Cb_ &&_cb, _Args_&&... _args)
const 1659 on_poll() = std::bind(std::forward< _Cb_ >(_cb), std::placeholders::_1, std::placeholders::_2, std::forward< _Args_ >(_args)...);
1666 auto instance_ptr = instance::from(uv_handle);
1667 auto &opcmd_state = instance_ptr->properties().opcmd_state;
1669 auto opcmd_state0 = opcmd_state;
1670 opcmd_state = opcmd::STOP;
1672 auto uv_ret = uv_status(::uv_poll_stop(
static_cast< uv_t* >(uv_handle)));
1674 switch (opcmd_state0)
1676 case opcmd::UNKNOWN:
1680 instance_ptr->unref();
1688 explicit operator
const uv_t*()
const noexcept {
return static_cast<
const uv_t* >(uv_handle); }
1689 explicit operator uv_t*()
noexcept {
return static_cast< uv_t* >(uv_handle); }
1692 template<
typename >
1693 void poll::poll_cb(::uv_poll_t *_uv_handle,
int _status,
int _events)
1695 auto instance_ptr = instance::from(_uv_handle);
1696 instance_ptr->uv_error = _status;
1697 auto &poll_cb = instance_ptr->properties().poll_cb;
1698 if (poll_cb) poll_cb(poll(_uv_handle), _events);
Namespace for all uvcc definitions.
int stop() const noexcept
Stop the handle, the callback will no longer be called.
on_exit_t & on_exit() const noexcept
Set the callback function called when the child process exits.
int start(int _events) const
Start the handle.
int start() const
Start the handle for watching for the signal.
on_idle_t & on_idle() const noexcept
Set the handle's callback.
int start(_Cb_ &&_cb, _Args_ &&... _args) const
Start the handle with the given callback.
void set_working_dir(const char *_cwd) const noexcept
Set current working directory when spawning the child process.
int start(_Cb_ &&_cb, _Args_ &&... _args) const
Start the handle with the given signal callback.
::uv_handle_type type() const noexcept
The tag indicating the libuv type of the handle.
void set_environment(char *_envp[]) const noexcept
Set pointer to environment for the child process. If nullptr the parents environment is used...
int stop() const noexcept
Stop the handle, the callback will no longer be called.
on_timer_t & on_timer() const noexcept
Set the timer callback.
timer(uv::loop &_loop, uint64_t _repeat_interval=0)
Create a timer handle which has a given repeat interval.
int start(_Cb_ &&_cb, _Args_ &&... _args) const
Start the handle with the given callback.
int start(_Cb_ &&_cb, _Args_ &&... _args) const
Start the handle with the given callback.
poll(uv::loop &_loop, ::uv_os_sock_t _socket)
Create a poll handle for a socket descriptor. (Windows only.)
check(uv::loop &_loop)
Create an check handle.
int uv_status() const noexcept
The status value returned by the last executed libuv API function on this handle. ...
The base class for the libuv handles.
std::uintptr_t id() const noexcept
The unique ID of the instance managed by this handle variable or 0 if the handle is void...
int send() const
Wakeup the event loop and call the async callback.
process(uv::loop &_loop)
Create a process handle.
on_check_t & on_check() const noexcept
Set the handle's callback.
void repeat_interval(uint64_t _value) noexcept
Set the timer repeat interval in milliseconds.
int pid() const noexcept
The PID of the child process. It is set after calling spawn().
int start(int _events, _Cb_ &&_cb, _Args_ &&... _args) const
Start the handle with the given callback.
void inherit_stdio(unsigned _target_fd_number, io _io) const
Set the io endpoint that should be available to the child process as the target stdio file descriptor...
void set_uid(::uv_uid_t _uid) const noexcept
Set the child process' user id.
void set_gid(::uv_gid_t _gid) const noexcept
Set the child process' group id.
int start() const
Start the handle.
int start(uint64_t _timeout, _Cb_ &&_cb, _Args_ &&... _args) const
Start the timer with the given callback.
prepare(uv::loop &_loop)
Create an prepare handle.
int stop() const noexcept
Stop the handle, the callback will no longer be called.
int start(int _signum, _Cb_ &&_cb, _Args_ &&... _args) const
Start the handle with the given signal callback, watching for the given signal number.
void inherit_stdio(unsigned _target_fd_number, ::uv_file _fd) const
Set the file descriptor that should be inherited by the child process as the target stdio descriptor ...
on_send_t & on_send() const noexcept
Set the async event callback.
The I/O event loop class.
The base class for handles representing I/O endpoints: a file, TCP/UDP socket, pipe, TTY.
A scoped reference counting guard.
int start(uint64_t _timeout) const
Start the timer by scheduling a timer event after the _timeout interval expires.
on_poll_t & on_poll() const noexcept
Set the handle's callback.
int send(_Cb_ &&_cb, _Args_ &&... _args) const
Set the given async callback and send wakeup event to the target loop.
async(uv::loop &_loop)
Create an async handle.
on_signal_t & on_signal() const noexcept
Set the signal callback.
poll(uv::loop &_loop, int _fd)
Create a poll handle for a file descriptor (Windows and Unix-like systems) or for a socket descriptor...
int kill(int _signum) const noexcept
Send the specified signal to the child process.
int spawn(const char *_file, char *_argv[], ::uv_process_flags _flags=static_cast< ::uv_process_flags >(0)) const noexcept
Create and start a new child process.
uint64_t repeat_interval() const noexcept
Get the timer repeat interval in milliseconds.
on_prepare_t & on_prepare() const noexcept
Set the handle's callback.
static void disable_stdio_inheritance() noexcept
Force child processes spawned by this process not to inherit file descriptors/handles that this proce...
static int kill(int _pid, int _signum) noexcept
Send the specified signal to the given PID.
idle(uv::loop &_loop)
Create an idle handle.
signal(uv::loop &_loop, int _signum)
Create a signal handle watching for _signum signal.
int start() const
Start the handle.
int signum() const noexcept
Get the signal number being watched for by this handle.
int create_stdio_pipe(unsigned _target_fd_number, uv::loop &_pipe_loop, ::uv_stdio_flags _pipe_flags, bool _ipc=false) const
Create a pipe to the child process' stdio fd number.
int stop() const noexcept
Stop the handle, the callback will no longer be called.
int start() const
Start the handle.
std::vector< io > & stdio() const noexcept
The stdio endpoints to be set for the child process.
int stop() const noexcept
Stop the handle, the callback will no longer be called.
int stop() const noexcept
Stop the timer, the callback will not be called anymore.