@@ -99,33 +99,24 @@ stream_outlet_impl::~stream_outlet_impl() {
9999 for (auto &udp_server : udp_servers_) udp_server->end_serving ();
100100 for (auto &responder : responders_) responder->end_serving ();
101101
102- // In theory, an io context should end quickly, but in practice it
103- // might take a while. So we
104- // 1. ask them to stop after they've finished their current task
105- // 2. wait a bit
106- // 3. stop the io contexts from our thread. Not ideal, but better than
107- // 4. waiting a bit and
108- // 5. detaching thread, i.e. letting it hang and continue tearing down
109- // the outlet
110102 asio::post (*io_ctx_data_, [io = io_ctx_data_]() { io->stop (); });
111103 asio::post (*io_ctx_service_, [io = io_ctx_service_]() { io->stop (); });
112104 const char *name = this ->info ().name ().c_str ();
113- for (int try_nr = 0 ; try_nr <= 100 ; ++try_nr) {
105+ for (int try_nr = 0 ; try_nr <= 400 ; ++try_nr) {
114106 switch (try_nr) {
115107 case 0 : DLOG_F (INFO, " Trying to join IO threads for %s" , name); break ;
116108 case 20 : LOG_F (INFO, " Waiting for %s's IO threads to end" , name); break ;
117- case 80 :
118- LOG_F (WARNING , " Stopping io_contexts for %s" , name);
109+ case 40 :
110+ DLOG_F ( 1 , " Calling stop() directly for %s's IO contexts " , name);
119111 io_ctx_data_->stop ();
120112 io_ctx_service_->stop ();
121- for (std::size_t k = 0 ; k < io_threads_.size (); k++) {
122- if (!io_threads_[k]->joinable ()) {
123- LOG_F (ERROR, " %s's io thread #%lu still running" , name, k);
124- }
125- }
126113 break ;
127- case 100 :
128- LOG_F (ERROR, " Detaching io_threads for %s" , name);
114+ case 200 :
115+ LOG_F (WARNING, " IO threads for %s taking longer than expected to finish" , name);
116+ break ;
117+ case 400 :
118+ LOG_F (ERROR, " Detaching io_threads for %s after 10 second timeout. "
119+ " This may cause undefined behavior." , name);
129120 for (auto &thread : io_threads_) thread->detach ();
130121 return ;
131122 default : break ;
0 commit comments