static tb_void_t tb_aiop_rtor_select_exit(tb_aiop_rtor_impl_t* rtor) { tb_aiop_rtor_select_impl_t* impl = (tb_aiop_rtor_select_impl_t*)rtor; if (impl) { // free fds tb_spinlock_enter(&impl->lock.pfds); FD_ZERO(&impl->rfdi); FD_ZERO(&impl->wfdi); FD_ZERO(&impl->rfdo); FD_ZERO(&impl->wfdo); tb_spinlock_leave(&impl->lock.pfds); // exit hash tb_spinlock_enter(&impl->lock.hash); if (impl->hash) tb_hash_map_exit(impl->hash); impl->hash = tb_null; tb_spinlock_leave(&impl->lock.hash); // exit lock tb_spinlock_exit(&impl->lock.pfds); tb_spinlock_exit(&impl->lock.hash); // free it tb_free(impl); } }
static tb_void_t tb_aiop_rtor_poll_exit(tb_aiop_rtor_impl_t* rtor) { tb_aiop_rtor_poll_impl_t* impl = (tb_aiop_rtor_poll_impl_t*)rtor; if (impl) { // exit pfds tb_spinlock_enter(&impl->lock.pfds); if (impl->pfds) tb_vector_exit(impl->pfds); impl->pfds = tb_null; tb_spinlock_leave(&impl->lock.pfds); // exit cfds if (impl->cfds) tb_vector_exit(impl->cfds); impl->cfds = tb_null; // exit hash tb_spinlock_enter(&impl->lock.hash); if (impl->hash) tb_hash_exit(impl->hash); impl->hash = tb_null; tb_spinlock_leave(&impl->lock.hash); // exit lock tb_spinlock_exit(&impl->lock.pfds); tb_spinlock_exit(&impl->lock.hash); // free it tb_free(impl); } }
tb_void_t tb_aiop_exit(tb_aiop_ref_t aiop) { // check tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop; tb_assert_and_check_return(impl); // exit reactor if (impl->rtor && impl->rtor->exit) impl->rtor->exit(impl->rtor); // exit spak if (impl->spak[0]) tb_socket_exit(impl->spak[0]); if (impl->spak[1]) tb_socket_exit(impl->spak[1]); impl->spak[0] = tb_null; impl->spak[1] = tb_null; // exit pool tb_spinlock_enter(&impl->lock); if (impl->pool) tb_fixed_pool_exit(impl->pool); impl->pool = tb_null; tb_spinlock_leave(&impl->lock); // exit lock tb_spinlock_exit(&impl->lock); // free impl tb_free(impl); }
tb_void_t tb_pool_exit(tb_pool_ref_t pool) { // check tb_pool_impl_t* impl = (tb_pool_impl_t*)pool; tb_assert_and_check_return(impl); // uses allocator? if (impl->allocator) { // exit it tb_allocator_free(impl->allocator, impl); return ; } // enter tb_spinlock_enter(&impl->lock); // exit small pool if (impl->small_pool) tb_small_pool_exit(impl->small_pool); impl->small_pool = tb_null; // leave tb_spinlock_leave(&impl->lock); // exit lock tb_spinlock_exit(&impl->lock); // exit pool if (impl->large_pool) tb_large_pool_free(impl->large_pool, impl); }
static tb_void_t tb_aiop_ptor_exit(tb_aicp_ptor_impl_t* ptor) { // check tb_aiop_ptor_impl_t* impl = (tb_aiop_ptor_impl_t*)ptor; tb_assert_and_check_return(impl); // trace tb_trace_d("exit"); // exit file tb_aicp_file_exit(impl); // exit loop if (impl->loop) { tb_long_t wait = 0; if ((wait = tb_thread_wait(impl->loop, 5000)) <= 0) { // trace tb_trace_e("loop[%p]: wait failed: %ld!", impl->loop, wait); } tb_thread_exit(impl->loop); impl->loop = tb_null; } // exit spak tb_spinlock_enter(&impl->lock); if (impl->spak[0]) tb_queue_exit(impl->spak[0]); if (impl->spak[1]) tb_queue_exit(impl->spak[1]); impl->spak[0] = tb_null; impl->spak[1] = tb_null; tb_spinlock_leave(&impl->lock); // exit aiop if (impl->aiop) tb_aiop_exit(impl->aiop); impl->aiop = tb_null; // exit list if (impl->list) tb_free(impl->list); impl->list = tb_null; // exit wait if (impl->wait) tb_semaphore_exit(impl->wait); impl->wait = tb_null; // exit timer if (impl->timer) tb_timer_exit(impl->timer); impl->timer = tb_null; // exit ltimer if (impl->ltimer) tb_ltimer_exit(impl->ltimer); impl->ltimer = tb_null; // exit lock tb_spinlock_exit(&impl->lock); // exit it tb_free(impl); }
tb_bool_t tb_transfer_pool_exit(tb_transfer_pool_ref_t pool) { // check tb_transfer_pool_impl_t* impl = (tb_transfer_pool_impl_t*)pool; tb_assert_and_check_return_val(impl, tb_false); // trace tb_trace_d("exit: .."); // kill it first tb_transfer_pool_kill(pool); // wait all if (tb_transfer_pool_wait_all(pool, 5000) <= 0) { // trace tb_trace_e("exit: wait failed!"); return tb_false; } // enter tb_spinlock_enter(&impl->lock); // check tb_assert(!tb_list_entry_size(&impl->work)); // exit the work list tb_list_entry_exit(&impl->work); // exit the idle list tb_list_entry_exit(&impl->idle); // exit pool if (impl->pool) { // exit all task tb_fixed_pool_walk(impl->pool, tb_transfer_pool_walk_exit, tb_null); // exit it tb_fixed_pool_exit(impl->pool); impl->pool = tb_null; } // leave tb_spinlock_leave(&impl->lock); // exit lock tb_spinlock_exit(&impl->lock); // exit it tb_free(pool); // trace tb_trace_d("exit: ok"); // ok return tb_true; }
static tb_void_t tb_demo_spider_exit(tb_demo_spider_t* spider) { // check tb_assert_and_check_return(spider); // trace tb_trace_d("exit: .."); // kill it tb_atomic_set(&spider->state, TB_STATE_KILLING); // kill all transfer tasks tb_transfer_pool_kill_all(tb_transfer_pool()); // kill all parser tasks tb_thread_pool_task_kill_all(tb_thread_pool()); // wait all transfer tasks exiting tb_transfer_pool_wait_all(tb_transfer_pool(), -1); // wait all parser tasks exiting tb_thread_pool_task_wait_all(tb_thread_pool(), -1); // enter tb_spinlock_enter(&spider->lock); // exit filter if (spider->filter) tb_bloom_filter_exit(spider->filter); spider->filter = tb_null; // exit pool if (spider->pool) tb_fixed_pool_exit(spider->pool); spider->pool = tb_null; // leave tb_spinlock_leave(&spider->lock); // exit lock tb_spinlock_exit(&spider->lock); // exit home tb_url_exit(&spider->home); // exit option #ifdef TB_CONFIG_MODULE_HAVE_OBJECT if (spider->option) tb_option_exit(spider->option); spider->option = tb_null; #endif // trace tb_trace_d("exit: ok"); }
tb_bool_t tb_aicp_exit(tb_aicp_ref_t aicp) { // check tb_aicp_impl_t* impl = (tb_aicp_impl_t*)aicp; tb_assert_and_check_return_val(impl, tb_false); // kill all first tb_aicp_kill_all((tb_aicp_ref_t)impl); // wait all exiting if (tb_aicp_wait_all((tb_aicp_ref_t)impl, 5000) <= 0) { // wait failed, trace left aicos tb_spinlock_enter(&impl->lock); if (impl->pool) tb_fixed_pool_walk(impl->pool, tb_aicp_walk_wait, tb_null); tb_spinlock_leave(&impl->lock); return tb_false; } // kill loop tb_aicp_kill((tb_aicp_ref_t)impl); // wait workers exiting tb_hong_t time = tb_mclock(); while (tb_atomic_get(&impl->work) && (tb_mclock() < time + 5000)) tb_msleep(500); // exit proactor if (impl->ptor) { tb_assert(impl->ptor && impl->ptor->exit); impl->ptor->exit(impl->ptor); impl->ptor = tb_null; } // exit aico pool tb_spinlock_enter(&impl->lock); if (impl->pool) tb_fixed_pool_exit(impl->pool); impl->pool = tb_null; tb_spinlock_leave(&impl->lock); // exit lock tb_spinlock_exit(&impl->lock); // free impl tb_free(impl); // ok return tb_true; }
tb_void_t tb_native_memory_exit() { // enter tb_spinlock_enter_without_profiler(&g_lock); // exit heap if (g_heap) HeapDestroy(g_heap); g_heap = tb_null; // leave tb_spinlock_leave(&g_lock); // exit lock tb_spinlock_exit(&g_lock); }
tb_void_t tb_mutex_exit(tb_mutex_ref_t mutex) { // check tb_assert_and_check_return(mutex); // exit it tb_spinlock_ref_t lock = (tb_spinlock_ref_t)mutex; if (lock) { // exit lock tb_spinlock_exit(lock); // free it tb_free(lock); } }
tb_void_t tb_timer_exit(tb_timer_ref_t timer) { // check tb_timer_impl_t* impl = (tb_timer_impl_t*)timer; tb_assert_and_check_return(impl); // stop it tb_atomic_set(&impl->stop, 1); // wait loop exit tb_size_t tryn = 10; while (tb_atomic_get(&impl->work) && tryn--) tb_msleep(500); // warning if (!tryn && tb_atomic_get(&impl->work)) tb_trace_w("[timer]: the loop has been not exited now!"); // post event tb_spinlock_enter(&impl->lock); tb_event_ref_t event = impl->event; tb_spinlock_leave(&impl->lock); if (event) tb_event_post(event); // enter tb_spinlock_enter(&impl->lock); // exit heap if (impl->heap) tb_heap_exit(impl->heap); impl->heap = tb_null; // exit pool if (impl->pool) tb_fixed_pool_exit(impl->pool); impl->pool = tb_null; // exit event if (impl->event) tb_event_exit(impl->event); impl->event = tb_null; // leave tb_spinlock_leave(&impl->lock); // exit lock tb_spinlock_exit(&impl->lock); // exit it tb_free(impl); }
/* ////////////////////////////////////////////////////////////////////////////////////// * private implementation */ static tb_void_t tb_default_allocator_exit(tb_allocator_ref_t self) { // check tb_default_allocator_ref_t allocator = (tb_default_allocator_ref_t)self; tb_assert_and_check_return(allocator); // enter tb_spinlock_enter(&allocator->base.lock); // exit small allocator if (allocator->small_allocator) tb_allocator_exit(allocator->small_allocator); allocator->small_allocator = tb_null; // leave tb_spinlock_leave(&allocator->base.lock); // exit lock tb_spinlock_exit(&allocator->base.lock); // exit allocator if (allocator->large_allocator) tb_allocator_large_free(allocator->large_allocator, allocator); }
tb_void_t tb_trace_exit() { // sync trace tb_trace_sync(); // enter tb_spinlock_enter_without_profiler(&g_lock); // clear mode g_mode = TB_TRACE_MODE_PRINT; // clear file if (g_file && !g_bref) tb_file_exit(g_file); g_file = tb_null; g_bref = tb_false; // leave tb_spinlock_leave(&g_lock); // exit lock tb_spinlock_exit(&g_lock); }
tb_bool_t tb_thread_pool_exit(tb_thread_pool_ref_t pool) { // check tb_thread_pool_impl_t* impl = (tb_thread_pool_impl_t*)pool; tb_assert_and_check_return_val(impl, tb_false); // trace tb_trace_d("exit: .."); // kill it first tb_thread_pool_kill(pool); // wait all if (tb_thread_pool_task_wait_all(pool, 5000) <= 0) { // trace tb_trace_e("exit: wait failed!"); return tb_false; } /* exit all workers * need not lock it because the worker size will not be increase d */ tb_size_t i = 0; tb_size_t n = impl->worker_size; for (i = 0; i < n; i++) { // the worker tb_thread_pool_worker_t* worker = &impl->worker_list[i]; // exit loop if (worker->loop) { // wait it tb_long_t wait = 0; if ((wait = tb_thread_wait(worker->loop, 5000)) <= 0) { // trace tb_trace_e("worker[%lu]: wait failed: %ld!", i, wait); } // exit it tb_thread_exit(worker->loop); worker->loop = tb_null; } } impl->worker_size = 0; // enter tb_spinlock_enter(&impl->lock); // exit pending jobs tb_list_entry_exit(&impl->jobs_pending); // exit waiting jobs tb_list_entry_exit(&impl->jobs_waiting); // exit urgent jobs tb_list_entry_exit(&impl->jobs_urgent); // exit jobs pool if (impl->jobs_pool) tb_fixed_pool_exit(impl->jobs_pool); impl->jobs_pool = tb_null; // leave tb_spinlock_leave(&impl->lock); // exit lock tb_spinlock_exit(&impl->lock); // exit semaphore if (impl->semaphore) tb_semaphore_exit(impl->semaphore); impl->semaphore = tb_null; // exit it tb_free(impl); // trace tb_trace_d("exit: ok"); // ok return tb_true; }