Mirror of :pserver:anonymous@cvs.schmorp.de/schmorpforge libev http://software.schmorp.de/pkg/libev.html
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

819 lines
20 KiB

  1. /*
  2. * libev simple C++ wrapper classes
  3. *
  4. * Copyright (c) 2007,2008,2010,2018,2020 Marc Alexander Lehmann <libev@schmorp.de>
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without modifica-
  8. * tion, are permitted provided that the following conditions are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright notice,
  11. * this list of conditions and the following disclaimer.
  12. *
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  18. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
  19. * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  20. * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
  21. * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  22. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  23. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  24. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
  25. * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  26. * OF THE POSSIBILITY OF SUCH DAMAGE.
  27. *
  28. * Alternatively, the contents of this file may be used under the terms of
  29. * the GNU General Public License ("GPL") version 2 or any later version,
  30. * in which case the provisions of the GPL are applicable instead of
  31. * the above. If you wish to allow the use of your version of this file
  32. * only under the terms of the GPL and not to allow others to use your
  33. * version of this file under the BSD license, indicate your decision
  34. * by deleting the provisions above and replace them with the notice
  35. * and other provisions required by the GPL. If you do not delete the
  36. * provisions above, a recipient may use your version of this file under
  37. * either the BSD or the GPL.
  38. */
  39. #ifndef EVPP_H__
  40. #define EVPP_H__
  41. #ifdef EV_H
  42. # include EV_H
  43. #else
  44. # include "ev.h"
  45. #endif
  46. #ifndef EV_USE_STDEXCEPT
  47. # define EV_USE_STDEXCEPT 1
  48. #endif
  49. #if EV_USE_STDEXCEPT
  50. # include <stdexcept>
  51. #endif
  52. namespace ev {
  53. typedef ev_tstamp tstamp;
  54. enum {
  55. UNDEF = EV_UNDEF,
  56. NONE = EV_NONE,
  57. READ = EV_READ,
  58. WRITE = EV_WRITE,
  59. #if EV_COMPAT3
  60. TIMEOUT = EV_TIMEOUT,
  61. #endif
  62. TIMER = EV_TIMER,
  63. PERIODIC = EV_PERIODIC,
  64. SIGNAL = EV_SIGNAL,
  65. CHILD = EV_CHILD,
  66. STAT = EV_STAT,
  67. IDLE = EV_IDLE,
  68. CHECK = EV_CHECK,
  69. PREPARE = EV_PREPARE,
  70. FORK = EV_FORK,
  71. ASYNC = EV_ASYNC,
  72. EMBED = EV_EMBED,
  73. # undef ERROR // some systems stupidly #define ERROR
  74. ERROR = EV_ERROR
  75. };
  76. enum
  77. {
  78. AUTO = EVFLAG_AUTO,
  79. NOENV = EVFLAG_NOENV,
  80. FORKCHECK = EVFLAG_FORKCHECK,
  81. SELECT = EVBACKEND_SELECT,
  82. POLL = EVBACKEND_POLL,
  83. EPOLL = EVBACKEND_EPOLL,
  84. KQUEUE = EVBACKEND_KQUEUE,
  85. DEVPOLL = EVBACKEND_DEVPOLL,
  86. PORT = EVBACKEND_PORT
  87. };
  88. enum
  89. {
  90. #if EV_COMPAT3
  91. NONBLOCK = EVLOOP_NONBLOCK,
  92. ONESHOT = EVLOOP_ONESHOT,
  93. #endif
  94. NOWAIT = EVRUN_NOWAIT,
  95. ONCE = EVRUN_ONCE
  96. };
  97. enum how_t
  98. {
  99. ONE = EVBREAK_ONE,
  100. ALL = EVBREAK_ALL
  101. };
  102. struct bad_loop
  103. #if EV_USE_STDEXCEPT
  104. : std::exception
  105. #endif
  106. {
  107. #if EV_USE_STDEXCEPT
  108. const char *what () const EV_NOEXCEPT
  109. {
  110. return "libev event loop cannot be initialized, bad value of LIBEV_FLAGS?";
  111. }
  112. #endif
  113. };
  114. #ifdef EV_AX
  115. # undef EV_AX
  116. #endif
  117. #ifdef EV_AX_
  118. # undef EV_AX_
  119. #endif
  120. #if EV_MULTIPLICITY
  121. # define EV_AX raw_loop
  122. # define EV_AX_ raw_loop,
  123. #else
  124. # define EV_AX
  125. # define EV_AX_
  126. #endif
  127. struct loop_ref
  128. {
  129. loop_ref (EV_P) EV_NOEXCEPT
  130. #if EV_MULTIPLICITY
  131. : EV_AX (EV_A)
  132. #endif
  133. {
  134. }
  135. bool operator == (const loop_ref &other) const EV_NOEXCEPT
  136. {
  137. #if EV_MULTIPLICITY
  138. return EV_AX == other.EV_AX;
  139. #else
  140. return true;
  141. #endif
  142. }
  143. bool operator != (const loop_ref &other) const EV_NOEXCEPT
  144. {
  145. #if EV_MULTIPLICITY
  146. return ! (*this == other);
  147. #else
  148. return false;
  149. #endif
  150. }
  151. #if EV_MULTIPLICITY
  152. bool operator == (const EV_P) const EV_NOEXCEPT
  153. {
  154. return this->EV_AX == EV_A;
  155. }
  156. bool operator != (const EV_P) const EV_NOEXCEPT
  157. {
  158. return ! (*this == EV_A);
  159. }
  160. operator struct ev_loop * () const EV_NOEXCEPT
  161. {
  162. return EV_AX;
  163. }
  164. operator const struct ev_loop * () const EV_NOEXCEPT
  165. {
  166. return EV_AX;
  167. }
  168. bool is_default () const EV_NOEXCEPT
  169. {
  170. return EV_AX == ev_default_loop (0);
  171. }
  172. #endif
  173. #if EV_COMPAT3
  174. void loop (int flags = 0)
  175. {
  176. ev_run (EV_AX_ flags);
  177. }
  178. void unloop (how_t how = ONE) EV_NOEXCEPT
  179. {
  180. ev_break (EV_AX_ how);
  181. }
  182. #endif
  183. void run (int flags = 0)
  184. {
  185. ev_run (EV_AX_ flags);
  186. }
  187. void break_loop (how_t how = ONE) EV_NOEXCEPT
  188. {
  189. ev_break (EV_AX_ how);
  190. }
  191. void post_fork () EV_NOEXCEPT
  192. {
  193. ev_loop_fork (EV_AX);
  194. }
  195. unsigned int backend () const EV_NOEXCEPT
  196. {
  197. return ev_backend (EV_AX);
  198. }
  199. tstamp now () const EV_NOEXCEPT
  200. {
  201. return ev_now (EV_AX);
  202. }
  203. void ref () EV_NOEXCEPT
  204. {
  205. ev_ref (EV_AX);
  206. }
  207. void unref () EV_NOEXCEPT
  208. {
  209. ev_unref (EV_AX);
  210. }
  211. #if EV_FEATURE_API
  212. unsigned int iteration () const EV_NOEXCEPT
  213. {
  214. return ev_iteration (EV_AX);
  215. }
  216. unsigned int depth () const EV_NOEXCEPT
  217. {
  218. return ev_depth (EV_AX);
  219. }
  220. void set_io_collect_interval (tstamp interval) EV_NOEXCEPT
  221. {
  222. ev_set_io_collect_interval (EV_AX_ interval);
  223. }
  224. void set_timeout_collect_interval (tstamp interval) EV_NOEXCEPT
  225. {
  226. ev_set_timeout_collect_interval (EV_AX_ interval);
  227. }
  228. #endif
  229. // function callback
  230. void once (int fd, int events, tstamp timeout, void (*cb)(int, void *), void *arg = 0) EV_NOEXCEPT
  231. {
  232. ev_once (EV_AX_ fd, events, timeout, cb, arg);
  233. }
  234. // method callback
  235. template<class K, void (K::*method)(int)>
  236. void once (int fd, int events, tstamp timeout, K *object) EV_NOEXCEPT
  237. {
  238. once (fd, events, timeout, method_thunk<K, method>, object);
  239. }
  240. // default method == operator ()
  241. template<class K>
  242. void once (int fd, int events, tstamp timeout, K *object) EV_NOEXCEPT
  243. {
  244. once (fd, events, timeout, method_thunk<K, &K::operator ()>, object);
  245. }
  246. template<class K, void (K::*method)(int)>
  247. static void method_thunk (int revents, void *arg)
  248. {
  249. (static_cast<K *>(arg)->*method)
  250. (revents);
  251. }
  252. // no-argument method callback
  253. template<class K, void (K::*method)()>
  254. void once (int fd, int events, tstamp timeout, K *object) EV_NOEXCEPT
  255. {
  256. once (fd, events, timeout, method_noargs_thunk<K, method>, object);
  257. }
  258. template<class K, void (K::*method)()>
  259. static void method_noargs_thunk (int revents, void *arg)
  260. {
  261. (static_cast<K *>(arg)->*method)
  262. ();
  263. }
  264. // simpler function callback
  265. template<void (*cb)(int)>
  266. void once (int fd, int events, tstamp timeout) EV_NOEXCEPT
  267. {
  268. once (fd, events, timeout, simpler_func_thunk<cb>);
  269. }
  270. template<void (*cb)(int)>
  271. static void simpler_func_thunk (int revents, void *arg)
  272. {
  273. (*cb)
  274. (revents);
  275. }
  276. // simplest function callback
  277. template<void (*cb)()>
  278. void once (int fd, int events, tstamp timeout) EV_NOEXCEPT
  279. {
  280. once (fd, events, timeout, simplest_func_thunk<cb>);
  281. }
  282. template<void (*cb)()>
  283. static void simplest_func_thunk (int revents, void *arg)
  284. {
  285. (*cb)
  286. ();
  287. }
  288. void feed_fd_event (int fd, int revents) EV_NOEXCEPT
  289. {
  290. ev_feed_fd_event (EV_AX_ fd, revents);
  291. }
  292. void feed_signal_event (int signum) EV_NOEXCEPT
  293. {
  294. ev_feed_signal_event (EV_AX_ signum);
  295. }
  296. #if EV_MULTIPLICITY
  297. struct ev_loop* EV_AX;
  298. #endif
  299. };
  300. #if EV_MULTIPLICITY
  301. struct dynamic_loop : loop_ref
  302. {
  303. dynamic_loop (unsigned int flags = AUTO)
  304. : loop_ref (ev_loop_new (flags))
  305. {
  306. if (!EV_AX)
  307. throw bad_loop ();
  308. }
  309. ~dynamic_loop () EV_NOEXCEPT
  310. {
  311. ev_loop_destroy (EV_AX);
  312. EV_AX = 0;
  313. }
  314. private:
  315. dynamic_loop (const dynamic_loop &);
  316. dynamic_loop & operator= (const dynamic_loop &);
  317. };
  318. #endif
  319. struct default_loop : loop_ref
  320. {
  321. default_loop (unsigned int flags = AUTO)
  322. #if EV_MULTIPLICITY
  323. : loop_ref (ev_default_loop (flags))
  324. #endif
  325. {
  326. if (
  327. #if EV_MULTIPLICITY
  328. !EV_AX
  329. #else
  330. !ev_default_loop (flags)
  331. #endif
  332. )
  333. throw bad_loop ();
  334. }
  335. private:
  336. default_loop (const default_loop &);
  337. default_loop &operator = (const default_loop &);
  338. };
  339. inline loop_ref get_default_loop () EV_NOEXCEPT
  340. {
  341. #if EV_MULTIPLICITY
  342. return ev_default_loop (0);
  343. #else
  344. return loop_ref ();
  345. #endif
  346. }
  347. #undef EV_AX
  348. #undef EV_AX_
  349. #undef EV_PX
  350. #undef EV_PX_
  351. #if EV_MULTIPLICITY
  352. # define EV_PX loop_ref EV_A
  353. # define EV_PX_ loop_ref EV_A_
  354. #else
  355. # define EV_PX
  356. # define EV_PX_
  357. #endif
  358. template<class ev_watcher, class watcher>
  359. struct base : ev_watcher
  360. {
  361. // scoped pause/unpause of a watcher
  362. struct freeze_guard
  363. {
  364. watcher &w;
  365. bool active;
  366. freeze_guard (watcher *self) EV_NOEXCEPT
  367. : w (*self), active (w.is_active ())
  368. {
  369. if (active) w.stop ();
  370. }
  371. ~freeze_guard ()
  372. {
  373. if (active) w.start ();
  374. }
  375. };
  376. #if EV_MULTIPLICITY
  377. EV_PX;
  378. // loop set
  379. void set (EV_P) EV_NOEXCEPT
  380. {
  381. this->EV_A = EV_A;
  382. }
  383. #endif
  384. base (EV_PX) EV_NOEXCEPT
  385. #if EV_MULTIPLICITY
  386. : EV_A (EV_A)
  387. #endif
  388. {
  389. ev_init (this, 0);
  390. }
  391. void set_ (const void *data, void (*cb)(EV_P_ ev_watcher *w, int revents)) EV_NOEXCEPT
  392. {
  393. this->data = (void *)data;
  394. ev_set_cb (static_cast<ev_watcher *>(this), cb);
  395. }
  396. // function callback
  397. template<void (*function)(watcher &w, int)>
  398. void set (void *data = 0) EV_NOEXCEPT
  399. {
  400. set_ (data, function_thunk<function>);
  401. }
  402. template<void (*function)(watcher &w, int)>
  403. static void function_thunk (EV_P_ ev_watcher *w, int revents)
  404. {
  405. function
  406. (*static_cast<watcher *>(w), revents);
  407. }
  408. // method callback
  409. template<class K, void (K::*method)(watcher &w, int)>
  410. void set (K *object) EV_NOEXCEPT
  411. {
  412. set_ (object, method_thunk<K, method>);
  413. }
  414. // default method == operator ()
  415. template<class K>
  416. void set (K *object) EV_NOEXCEPT
  417. {
  418. set_ (object, method_thunk<K, &K::operator ()>);
  419. }
  420. template<class K, void (K::*method)(watcher &w, int)>
  421. static void method_thunk (EV_P_ ev_watcher *w, int revents)
  422. {
  423. (static_cast<K *>(w->data)->*method)
  424. (*static_cast<watcher *>(w), revents);
  425. }
  426. // no-argument callback
  427. template<class K, void (K::*method)()>
  428. void set (K *object) EV_NOEXCEPT
  429. {
  430. set_ (object, method_noargs_thunk<K, method>);
  431. }
  432. template<class K, void (K::*method)()>
  433. static void method_noargs_thunk (EV_P_ ev_watcher *w, int revents)
  434. {
  435. (static_cast<K *>(w->data)->*method)
  436. ();
  437. }
  438. void operator ()(int events = EV_UNDEF)
  439. {
  440. return
  441. ev_cb (static_cast<ev_watcher *>(this))
  442. (static_cast<ev_watcher *>(this), events);
  443. }
  444. bool is_active () const EV_NOEXCEPT
  445. {
  446. return ev_is_active (static_cast<const ev_watcher *>(this));
  447. }
  448. bool is_pending () const EV_NOEXCEPT
  449. {
  450. return ev_is_pending (static_cast<const ev_watcher *>(this));
  451. }
  452. void feed_event (int revents) EV_NOEXCEPT
  453. {
  454. ev_feed_event (EV_A_ static_cast<ev_watcher *>(this), revents);
  455. }
  456. };
  457. inline tstamp now (EV_P) EV_NOEXCEPT
  458. {
  459. return ev_now (EV_A);
  460. }
  461. inline void delay (tstamp interval) EV_NOEXCEPT
  462. {
  463. ev_sleep (interval);
  464. }
  465. inline int version_major () EV_NOEXCEPT
  466. {
  467. return ev_version_major ();
  468. }
  469. inline int version_minor () EV_NOEXCEPT
  470. {
  471. return ev_version_minor ();
  472. }
  473. inline unsigned int supported_backends () EV_NOEXCEPT
  474. {
  475. return ev_supported_backends ();
  476. }
  477. inline unsigned int recommended_backends () EV_NOEXCEPT
  478. {
  479. return ev_recommended_backends ();
  480. }
  481. inline unsigned int embeddable_backends () EV_NOEXCEPT
  482. {
  483. return ev_embeddable_backends ();
  484. }
  485. inline void set_allocator (void *(*cb)(void *ptr, long size) EV_NOEXCEPT) EV_NOEXCEPT
  486. {
  487. ev_set_allocator (cb);
  488. }
  489. inline void set_syserr_cb (void (*cb)(const char *msg) EV_NOEXCEPT) EV_NOEXCEPT
  490. {
  491. ev_set_syserr_cb (cb);
  492. }
  493. #if EV_MULTIPLICITY
  494. #define EV_CONSTRUCT(cppstem,cstem) \
  495. (EV_PX = get_default_loop ()) EV_NOEXCEPT \
  496. : base<ev_ ## cstem, cppstem> (EV_A) \
  497. { \
  498. }
  499. #else
  500. #define EV_CONSTRUCT(cppstem,cstem) \
  501. () EV_NOEXCEPT \
  502. { \
  503. }
  504. #endif
  505. /* using a template here would require quite a few more lines,
  506. * so a macro solution was chosen */
  507. #define EV_BEGIN_WATCHER(cppstem,cstem) \
  508. \
  509. struct cppstem : base<ev_ ## cstem, cppstem> \
  510. { \
  511. void start () EV_NOEXCEPT \
  512. { \
  513. ev_ ## cstem ## _start (EV_A_ static_cast<ev_ ## cstem *>(this)); \
  514. } \
  515. \
  516. void stop () EV_NOEXCEPT \
  517. { \
  518. ev_ ## cstem ## _stop (EV_A_ static_cast<ev_ ## cstem *>(this)); \
  519. } \
  520. \
  521. cppstem EV_CONSTRUCT(cppstem,cstem) \
  522. \
  523. ~cppstem () EV_NOEXCEPT \
  524. { \
  525. stop (); \
  526. } \
  527. \
  528. using base<ev_ ## cstem, cppstem>::set; \
  529. \
  530. private: \
  531. \
  532. cppstem (const cppstem &o); \
  533. \
  534. cppstem &operator =(const cppstem &o); \
  535. \
  536. public:
  537. #define EV_END_WATCHER(cppstem,cstem) \
  538. };
  539. EV_BEGIN_WATCHER (io, io)
  540. void set (int fd, int events) EV_NOEXCEPT
  541. {
  542. freeze_guard freeze (this);
  543. ev_io_set (static_cast<ev_io *>(this), fd, events);
  544. }
  545. void set (int events) EV_NOEXCEPT
  546. {
  547. freeze_guard freeze (this);
  548. ev_io_modify (static_cast<ev_io *>(this), events);
  549. }
  550. void start (int fd, int events) EV_NOEXCEPT
  551. {
  552. set (fd, events);
  553. start ();
  554. }
  555. EV_END_WATCHER (io, io)
  556. EV_BEGIN_WATCHER (timer, timer)
  557. void set (ev_tstamp after, ev_tstamp repeat = 0.) EV_NOEXCEPT
  558. {
  559. freeze_guard freeze (this);
  560. ev_timer_set (static_cast<ev_timer *>(this), after, repeat);
  561. }
  562. void start (ev_tstamp after, ev_tstamp repeat = 0.) EV_NOEXCEPT
  563. {
  564. set (after, repeat);
  565. start ();
  566. }
  567. void again () EV_NOEXCEPT
  568. {
  569. ev_timer_again (EV_A_ static_cast<ev_timer *>(this));
  570. }
  571. ev_tstamp remaining ()
  572. {
  573. return ev_timer_remaining (EV_A_ static_cast<ev_timer *>(this));
  574. }
  575. EV_END_WATCHER (timer, timer)
  576. #if EV_PERIODIC_ENABLE
  577. EV_BEGIN_WATCHER (periodic, periodic)
  578. void set (ev_tstamp at, ev_tstamp interval = 0.) EV_NOEXCEPT
  579. {
  580. freeze_guard freeze (this);
  581. ev_periodic_set (static_cast<ev_periodic *>(this), at, interval, 0);
  582. }
  583. void start (ev_tstamp at, ev_tstamp interval = 0.) EV_NOEXCEPT
  584. {
  585. set (at, interval);
  586. start ();
  587. }
  588. void again () EV_NOEXCEPT
  589. {
  590. ev_periodic_again (EV_A_ static_cast<ev_periodic *>(this));
  591. }
  592. EV_END_WATCHER (periodic, periodic)
  593. #endif
  594. #if EV_SIGNAL_ENABLE
  595. EV_BEGIN_WATCHER (sig, signal)
  596. void set (int signum) EV_NOEXCEPT
  597. {
  598. freeze_guard freeze (this);
  599. ev_signal_set (static_cast<ev_signal *>(this), signum);
  600. }
  601. void start (int signum) EV_NOEXCEPT
  602. {
  603. set (signum);
  604. start ();
  605. }
  606. EV_END_WATCHER (sig, signal)
  607. #endif
  608. #if EV_CHILD_ENABLE
  609. EV_BEGIN_WATCHER (child, child)
  610. void set (int pid, int trace = 0) EV_NOEXCEPT
  611. {
  612. freeze_guard freeze (this);
  613. ev_child_set (static_cast<ev_child *>(this), pid, trace);
  614. }
  615. void start (int pid, int trace = 0) EV_NOEXCEPT
  616. {
  617. set (pid, trace);
  618. start ();
  619. }
  620. EV_END_WATCHER (child, child)
  621. #endif
  622. #if EV_STAT_ENABLE
  623. EV_BEGIN_WATCHER (stat, stat)
  624. void set (const char *path, ev_tstamp interval = 0.) EV_NOEXCEPT
  625. {
  626. freeze_guard freeze (this);
  627. ev_stat_set (static_cast<ev_stat *>(this), path, interval);
  628. }
  629. void start (const char *path, ev_tstamp interval = 0.) EV_NOEXCEPT
  630. {
  631. stop ();
  632. set (path, interval);
  633. start ();
  634. }
  635. void update () EV_NOEXCEPT
  636. {
  637. ev_stat_stat (EV_A_ static_cast<ev_stat *>(this));
  638. }
  639. EV_END_WATCHER (stat, stat)
  640. #endif
  641. #if EV_IDLE_ENABLE
  642. EV_BEGIN_WATCHER (idle, idle)
  643. void set () EV_NOEXCEPT { }
  644. EV_END_WATCHER (idle, idle)
  645. #endif
  646. #if EV_PREPARE_ENABLE
  647. EV_BEGIN_WATCHER (prepare, prepare)
  648. void set () EV_NOEXCEPT { }
  649. EV_END_WATCHER (prepare, prepare)
  650. #endif
  651. #if EV_CHECK_ENABLE
  652. EV_BEGIN_WATCHER (check, check)
  653. void set () EV_NOEXCEPT { }
  654. EV_END_WATCHER (check, check)
  655. #endif
  656. #if EV_EMBED_ENABLE
  657. EV_BEGIN_WATCHER (embed, embed)
  658. void set_embed (struct ev_loop *embedded_loop) EV_NOEXCEPT
  659. {
  660. freeze_guard freeze (this);
  661. ev_embed_set (static_cast<ev_embed *>(this), embedded_loop);
  662. }
  663. void start (struct ev_loop *embedded_loop) EV_NOEXCEPT
  664. {
  665. set (embedded_loop);
  666. start ();
  667. }
  668. void sweep ()
  669. {
  670. ev_embed_sweep (EV_A_ static_cast<ev_embed *>(this));
  671. }
  672. EV_END_WATCHER (embed, embed)
  673. #endif
  674. #if EV_FORK_ENABLE
  675. EV_BEGIN_WATCHER (fork, fork)
  676. void set () EV_NOEXCEPT { }
  677. EV_END_WATCHER (fork, fork)
  678. #endif
  679. #if EV_ASYNC_ENABLE
  680. EV_BEGIN_WATCHER (async, async)
  681. void send () EV_NOEXCEPT
  682. {
  683. ev_async_send (EV_A_ static_cast<ev_async *>(this));
  684. }
  685. bool async_pending () EV_NOEXCEPT
  686. {
  687. return ev_async_pending (static_cast<ev_async *>(this));
  688. }
  689. EV_END_WATCHER (async, async)
  690. #endif
  691. #undef EV_PX
  692. #undef EV_PX_
  693. #undef EV_CONSTRUCT
  694. #undef EV_BEGIN_WATCHER
  695. #undef EV_END_WATCHER
  696. }
  697. #endif