static tb_void_t tb_aicp_instance_exit(tb_handle_t handle, tb_cpointer_t priv) { // check tb_assert_and_check_return(handle); // wait all if (!tb_aicp_wait_all((tb_aicp_ref_t)handle, 5000)) return ; // kill aicp tb_aicp_kill((tb_aicp_ref_t)handle); // exit loop tb_thread_ref_t loop = (tb_thread_ref_t)priv; if (loop) { // wait it if (!tb_thread_wait(loop, 5000)) return ; // exit it tb_thread_exit(loop); } // exit it tb_aicp_exit((tb_aicp_ref_t)handle); }
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); }
/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t tb_demo_platform_semaphore_main(tb_int_t argc, tb_char_t** argv) { // init loop tb_demo_loop_t loop[10]; tb_size_t i = 0; tb_size_t n = tb_arrayn(loop); for (i = 0; i < n; i++) { // init semaphore loop[i].semaphore = tb_semaphore_init(0); tb_assert_and_check_break(loop[i].semaphore); // post semaphore tb_semaphore_post(loop[i].semaphore, 1); // init index loop[i].index = i; // init stoped loop[i].bstoped = 0; // init loop loop[i].loop = tb_thread_init(tb_null, tb_demo_loop, loop + i, 0); tb_assert_and_check_break(loop[i].loop); } // check tb_assert_and_check_return_val(i == n, 0); // wait some time tb_msleep(100); // post tb_char_t line[256]; tb_bool_t stop = tb_false; while (!stop) { // get line tb_char_t const* p = tb_demo_gets(line, sizeof(line)); tb_assert_and_check_break(p); // trace tb_trace_i("post: %s", p); // done while (*p && !stop) { tb_char_t ch = *p++; switch (ch) { case 'q': stop = tb_true; break; default: { if (ch >= '0' && ch <= '9') { // the index tb_size_t index = ch - '0'; tb_assert_and_check_break(index < n && index == loop[index].index); // post semaphore if (loop[index].semaphore) tb_semaphore_post(loop[index].semaphore, 1); } } break; } } } // post loop for (i = 0; i < n; i++) { // quit thread tb_atomic_set(&loop[i].bstoped, 1); // post semaphore if (loop[i].semaphore) tb_semaphore_post(loop[i].semaphore, 1); } // exit loop for (i = 0; i < n; i++) { // exit loop if (loop[i].loop) { // wait it if (!tb_thread_wait(loop[i].loop, 5000)) { // trace tb_trace_e("wait loop[%lu]: timeout", i); } // exit it tb_thread_exit(loop[i].loop); } // exit semaphore if (loop[i].semaphore) tb_semaphore_exit(loop[i].semaphore); } // exit tb_trace_i("exit"); return 0; }
/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t tb_demo_asio_aicpd_main(tb_int_t argc, tb_char_t** argv) { // check tb_assert_and_check_return_val(argv[1], 0); // init tb_aicp_ref_t aicp = tb_null; tb_aico_ref_t aico = tb_null; // tb_aico_ref_t task = tb_null; tb_thread_ref_t loop[16] = {tb_null}; do { // init aicp aicp = tb_aicp_init(16); tb_assert_and_check_break(aicp); // init sock aico aico = tb_aico_init(aicp); tb_assert_and_check_break(aico); // init addr tb_ipaddr_t addr; tb_ipaddr_set(&addr, tb_null, 9090, TB_IPADDR_FAMILY_IPV4); // open sock aico if (!tb_aico_open_sock_from_type(aico, TB_SOCKET_TYPE_TCP, tb_ipaddr_family(&addr))) break; // bind port if (!tb_socket_bind(tb_aico_sock(aico), &addr)) break; // listen sock if (!tb_socket_listen(tb_aico_sock(aico), 20)) break; #if 0 // init task aico task = tb_aico_init(aicp); tb_assert_and_check_break(task); // open task aico if (!tb_aico_open_task(task, tb_false)) break; // run task if (!tb_aico_task_run(task, 0, tb_demo_task_func, tb_null)) break; if (!tb_aico_task_run(aico, 0, tb_demo_task_func, tb_null)) break; #endif // post acpt if (!tb_aico_acpt(aico, tb_demo_sock_acpt_func, argv[1])) break; // done loop loop[0] = tb_thread_init(tb_null, tb_demo_loop, aicp, 0); loop[1] = tb_thread_init(tb_null, tb_demo_loop, aicp, 0); loop[2] = tb_thread_init(tb_null, tb_demo_loop, aicp, 0); loop[3] = tb_thread_init(tb_null, tb_demo_loop, aicp, 0); // wait exit getchar(); } while (0); // trace tb_trace_i("end"); #if 1 if (aicp) { // kill all tb_aicp_kill_all(aicp); // wait all tb_aicp_wait_all(aicp, -1); // kill aicp tb_aicp_kill(aicp); } // wait exit { // exit loop tb_thread_ref_t* l = loop; for (; *l; l++) { tb_thread_wait(*l, -1, tb_null); tb_thread_exit(*l); } } #endif // exit aicp if (aicp) tb_aicp_exit(aicp); return 0; }
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; }