@@ -355,7 +355,7 @@ namespace manapi::ev::internal {
355355 // std::move_only_function<void()> adding_curl_async_cb{nullptr};
356356 // std::queue<std::shared_ptr<ev::io>> curl_fds{};
357357 std::map<CURL*, curl_res_value_t > curl_res{};
358- std::shared_ptr<ev:: timer> timeout_watcher{nullptr };
358+ manapi:: timer timeout_watcher{nullptr };
359359 std::map<socket_t , std::shared_ptr<ev::io>> watchers;
360360 };
361361#endif
@@ -655,7 +655,10 @@ void manapi::ev::callback_close_cb(uv_handle_t *s) MANAPIHTTP_NOEXCEPT {
655655 }
656656}
657657
658- manapi::event_loop::event_loop () = default ;
658+ manapi::event_loop::event_loop () {
659+ this ->deps_ = 0 ;
660+ this ->flags = 0 ;
661+ }
659662
660663manapi::ev::status_or<std::shared_ptr<manapi::event_loop>> manapi::event_loop::create (std::shared_ptr<threadpool> taskpool, std::shared_ptr<manapi::logger> logger) {
661664 auto ev = std::make_shared<manapi::event_loop>();
@@ -714,6 +717,7 @@ manapi::ev::status_or<std::shared_ptr<manapi::event_loop>> manapi::event_loop::c
714717 }
715718
716719 ev->callback_watcher_ ->adding_async = adding_async_res.unwrap ();
720+ ev->callback_watcher_ ->adding_async ->unref ();
717721 ev->callback_watcher_ ->adding_async_cb = [ev = ev.get ()] ()
718722 -> void { ev->callback_watcher_ ->adding_async ->send (); };
719723
@@ -740,30 +744,6 @@ manapi::ev::status_or<std::shared_ptr<manapi::event_loop>> manapi::event_loop::c
740744 goto err;
741745 }
742746
743- #if MANAPIHTTP_CURL_DEPENDENCY
744-
745- /* curl fetch timeout */
746- auto timeout_watcher_res = ev->create_watcher_timer ([ev = ev.get ()] (const std::shared_ptr<ev::timer> &w) -> void {
747- ev->handle_curl_exec_connections ();
748- ev->handle_curl_check_connections ();
749-
750- w->repeat (50 );
751- w->again ();
752- });
753-
754- if (!timeout_watcher_res) {
755- status = timeout_watcher_res.err ();
756- goto err;
757- }
758-
759- ev->curl_watcher ->timeout_watcher = timeout_watcher_res.unwrap ();
760-
761- if (auto rhs = ev->curl_watcher ->timeout_watcher ->start (50 , 0 )) {
762- status = manapi::ev::status_internal (" timeout_watcher::start" , rhs);
763- goto err;
764- }
765- #endif
766-
767747 /* interrupted */
768748 auto interrupt_watcher_res = ev->create_watcher_async ([ev = ev.get ()] (const std::shared_ptr<ev::async> &w)
769749 -> void { async::run (ev->stop ()); });
@@ -783,30 +763,25 @@ manapi::ev::status_or<std::shared_ptr<manapi::event_loop>> manapi::event_loop::c
783763 }
784764
785765 err: {
786- if (ev) {
787- if (ev->callback_watcher_ ) {
788- std::lock_guard<std::mutex> lk (ev->callback_watcher_ ->adding_mx );
789- ev->stop_watcher (std::move (ev->callback_watcher_ ->adding_async ));
790- ev->callback_watcher_ ->adding_async_cb = nullptr ;
791- }
792- #if MANAPIHTTP_CURL_DEPENDENCY
793- if (ev->curl_watcher ) {
794- ev->stop_watcher (std::move (ev->curl_watcher ->timeout_watcher ));
795- }
796- #endif
797- ev->stop_watcher (std::move (ev->interrupted_watcher_ ));
798- ev->stop_watcher (std::move (ev->prepare_tasks_ ));
799- ev->stop_watcher (std::move (ev->idle_tasks_ ));
800- }
801766 return std::move (status);
802767 }
803768}
804769
805770manapi::event_loop::~event_loop () {
771+ if (this ->callback_watcher_ ) {
772+ std::lock_guard<std::mutex> lk (this ->callback_watcher_ ->adding_mx );
773+ this ->stop_watcher (std::move (this ->callback_watcher_ ->adding_async ));
774+ this ->callback_watcher_ ->adding_async_cb = nullptr ;
775+ }
776+ this ->stop_watcher (std::move (this ->interrupted_watcher_ ));
777+ this ->stop_watcher (std::move (this ->prepare_tasks_ ));
778+ this ->stop_watcher (std::move (this ->idle_tasks_ ));
779+
806780#if MANAPIHTTP_CURL_DEPENDENCY
807781 this ->curl_watcher ->curl_multi .reset ();
808782#endif
809783 this ->etaskpool_ .reset ();
784+
810785}
811786
812787void manapi::event_loop::setup_handle_interrupt () MANAPIHTTP_NOEXCEPT {
@@ -849,19 +824,9 @@ void manapi::event_loop::wait_all_(bool shutdown) MANAPIHTTP_NOEXCEPT {
849824 }
850825
851826 this ->stop_watcher (std::move (this ->interrupted_watcher_ ));
852- this ->stop_watcher (std::move (this ->callback_watcher_ ->adding_async ));
853827 this ->stop_watcher (std::move (this ->idle_tasks_ ));
854828 this ->stop_watcher (std::move (this ->prepare_tasks_ ));
855- #if MANAPIHTTP_CURL_DEPENDENCY
856- this ->stop_watcher (std::move (this ->curl_watcher ->timeout_watcher ));
857- #endif
858- manapi::timer checker;
859- MANAPIHTTP_MUST_ALLOC_START
860- checker = manapi::async::current ()->timerpool ()->append_interval_sync (500 , [this ] (const manapi::timer &) -> void {
861- this ->handle_curl_exec_connections ();
862- this ->handle_curl_check_connections ();
863- }).unwrap ();
864- MANAPIHTTP_MUST_ALLOC_END
829+
865830 if (this ->loop_ ) {
866831 auto etaskpool = dynamic_cast <ethreadpool *>(this ->etaskpool_ .get ());
867832
@@ -909,6 +874,7 @@ void manapi::event_loop::wait_all_(bool shutdown) MANAPIHTTP_NOEXCEPT {
909874 });
910875 MANAPIHTTP_MUST_ALLOC_END
911876
877+ this ->flags |= EVENT_LOOP_FLAG_ACTIVE;
912878 while (etaskpool->try_task ()) {}
913879
914880 etaskpool->set_notify ();
@@ -918,24 +884,38 @@ void manapi::event_loop::wait_all_(bool shutdown) MANAPIHTTP_NOEXCEPT {
918884
919885 manapi::async::current ()->timerpool ()->stop ();
920886
921- this ->flags |= EVENT_LOOP_FLAG_ACTIVE;
922887 auto const rhs = ::uv_run (this ->loop (), UV_RUN_DEFAULT);
923888 if (this ->flags & EVENT_LOOP_FLAG_ACTIVE) {
924889 this ->flags ^= EVENT_LOOP_FLAG_ACTIVE;
925890 }
891+
926892 if (!rhs && !::uv_loop_alive (this ->loop ()) && !this ->etaskpool_ ->tasks_size ()) {
927- manapi_log_trace (manapi::debug::LOG_TRACE_HIGH,
928- " %s:%s" , " eventloop" , " uv_loop_alive has returned 0" );
929- break ;
893+
894+ std::lock_guard<std::mutex> lk (this ->callback_watcher_ ->adding_mx );
895+ if (shutdown && this ->callback_watcher_ ->adding_async ) {
896+ if (!uv_has_ref ((uv_handle_t *)this ->callback_watcher_ ->adding_async ->custom ())) {
897+ this ->callback_watcher_ ->adding_async ->ref ();
898+ }
899+ if (!this ->deps_ ) {
900+ this ->stop_watcher (std::move (this ->callback_watcher_ ->adding_async ));
901+ }
902+ }
903+ else {
904+ manapi_log_trace (manapi::debug::LOG_TRACE_HIGH,
905+ " %s:%s" , " eventloop" , " uv_loop_alive has returned 0" );
906+ break ;
907+ }
930908 }
931909 }
932910
933- checker.stop ();
934911 etaskpool->set_notify_cb (nullptr );
935912
936913 if (shutdown) {
937914 manapi_log_trace (manapi::debug::LOG_TRACE_MEDIUM, " eventloop:well done" );
938915
916+ if (this ->curl_watcher ->timeout_watcher )
917+ this ->curl_watcher ->timeout_watcher .stop ();
918+
939919 if (auto rhs = ::uv_loop_close (this ->loop_ .get ())) {
940920#ifndef MANAPIHTTP_DISABLE_TRACE_HARD
941921 ::uv_print_all_handles (this ->loop (), stderr);
@@ -956,6 +936,16 @@ void manapi::event_loop::wait_all_(bool shutdown) MANAPIHTTP_NOEXCEPT {
956936 }
957937}
958938
939+ void manapi::event_loop::timerpool_init_ (std::shared_ptr<manapi::timerpool> tp) {
940+ #if MANAPIHTTP_CURL_DEPENDENCY
941+ /* curl fetch timeout */
942+ this ->curl_watcher ->timeout_watcher = tp->append_interval_sync (200 , [this ] (manapi::timer t) -> void {
943+ this ->handle_curl_exec_connections ();
944+ this ->handle_curl_check_connections ();
945+ }).unwrap ();
946+ #endif
947+ }
948+
959949size_t manapi::event_loop::subscribe_finish (int priority, std::move_only_function<manapi::future<void >()> cb) {
960950 auto id = *reinterpret_cast <const std::size_t *> (&cb);
961951
@@ -1145,6 +1135,7 @@ manapi::status manapi::event_loop::custom_callback(std::move_only_function<void(
11451135 }
11461136 this ->callback_watcher_ ->callback_data .push_back ({nullptr });
11471137 this ->callback_watcher_ ->callback_data .back ().cb = std::move (*cb);
1138+ this ->deps_ ++;
11481139 lk.unlock ();
11491140 this ->callback_watcher_ ->adding_mcv .unlock ();
11501141 this ->callback_watcher_ ->adding_async_cb ();
@@ -1201,6 +1192,8 @@ void manapi::event_loop::custom_watcher_callback_async(const std::shared_ptr<ev:
12011192 auto data = std::move (list.front ());
12021193 list.pop_front ();
12031194
1195+ this ->decrease_deps ();
1196+
12041197 try {
12051198 data.cb (this );
12061199 }
@@ -1615,6 +1608,20 @@ void manapi::event_loop::custom_event_loop(std::move_only_function<void()> block
16151608 this ->custom_event_loop_ = std::move (block_cb);
16161609}
16171610
1611+ void manapi::event_loop::increase_deps () MANAPIHTTP_NOEXCEPT {
1612+ std::lock_guard<std::mutex> lk (this ->callback_watcher_ ->adding_mx );
1613+ assert (this ->callback_watcher_ ->adding_async );
1614+ this ->deps_ ++;
1615+ }
1616+
1617+ void manapi::event_loop::decrease_deps () MANAPIHTTP_NOEXCEPT {
1618+ std::lock_guard<std::mutex> lk (this ->callback_watcher_ ->adding_mx );
1619+ assert (this ->callback_watcher_ ->adding_async );
1620+ if (!--this ->deps_ && uv_has_ref ((uv_handle_t *)this ->callback_watcher_ ->adding_async ->custom ())) {
1621+ this ->callback_watcher_ ->adding_async ->unref ();
1622+ }
1623+ }
1624+
16181625manapi::ev::status_or<std::shared_ptr<manapi::ev::io>> manapi::event_loop::create_watcher_fd (int fd, ev::io_cb callback) MANAPIHTTP_NOEXCEPT {
16191626 try {
16201627 auto w = std::make_shared<ev::io>();
0 commit comments