| 405 | extern int stop_and_join_epoll_threads(); |
| 406 | |
| 407 | void TaskControl::stop_and_join() { |
| 408 | // Close epoll threads so that worker threads are not waiting on epoll( |
| 409 | // which cannot be woken up by signal_task below) |
| 410 | CHECK_EQ(0, stop_and_join_epoll_threads()); |
| 411 | |
| 412 | // Stop workers |
| 413 | { |
| 414 | BAIDU_SCOPED_LOCK(_modify_group_mutex); |
| 415 | _stop = true; |
| 416 | std::for_each( |
| 417 | _tagged_ngroup.begin(), _tagged_ngroup.end(), |
| 418 | [](butil::atomic<size_t>& index) { index.store(0, butil::memory_order_relaxed); }); |
| 419 | } |
| 420 | for (int i = 0; i < FLAGS_task_group_ntags; ++i) { |
| 421 | for (auto& pl : _tagged_pl[i]) { |
| 422 | pl.stop(); |
| 423 | } |
| 424 | } |
| 425 | |
| 426 | for (auto worker: _workers) { |
| 427 | // Interrupt blocking operations. |
| 428 | #ifdef BRPC_BTHREAD_TRACER |
| 429 | pthread_kill(worker, _task_tracer.get_trace_signal()); |
| 430 | #else |
| 431 | interrupt_pthread(worker); |
| 432 | #endif // BRPC_BTHREAD_TRACER |
| 433 | } |
| 434 | // Join workers |
| 435 | for (auto worker : _workers) { |
| 436 | pthread_join(worker, NULL); |
| 437 | } |
| 438 | } |
| 439 | |
| 440 | TaskControl::~TaskControl() { |
| 441 | // NOTE: g_task_control is not destructed now because the situation |
nothing calls this directly
no test coverage detected