/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_lo_scheduler_io_ref_t tb_lo_scheduler_io_init(tb_lo_scheduler_t* scheduler) { // done tb_bool_t ok = tb_false; tb_lo_scheduler_io_ref_t scheduler_io = tb_null; do { // init io scheduler scheduler_io = tb_malloc0_type(tb_lo_scheduler_io_t); tb_assert_and_check_break(scheduler_io); // save scheduler scheduler_io->scheduler = (tb_lo_scheduler_t*)scheduler; // init poller scheduler_io->poller = tb_poller_init(tb_null); tb_assert_and_check_break(scheduler_io->poller); #ifndef TB_CONFIG_MICRO_ENABLE // init timer and using cache time scheduler_io->timer = tb_timer_init(TB_SCHEDULER_IO_TIMER_GROW, tb_true); tb_assert_and_check_break(scheduler_io->timer); // init ltimer and using cache time scheduler_io->ltimer = tb_ltimer_init(TB_SCHEDULER_IO_LTIMER_GROW, TB_LTIMER_TICK_S, tb_true); tb_assert_and_check_break(scheduler_io->ltimer); #endif // start the io loop coroutine if (!tb_lo_coroutine_start((tb_lo_scheduler_ref_t)scheduler, tb_lo_scheduler_io_loop, scheduler_io, tb_null)) break; // ok ok = tb_true; } while (0); // failed? if (!ok) { // exit io scheduler if (scheduler_io) tb_lo_scheduler_io_exit(scheduler_io); scheduler_io = tb_null; } // ok? return scheduler_io; }
tb_void_t tb_lo_scheduler_exit(tb_lo_scheduler_ref_t self) { // check tb_lo_scheduler_t* scheduler = (tb_lo_scheduler_t*)self; tb_assert_and_check_return(scheduler); // must be stopped tb_assert(scheduler->stopped); // exit io scheduler first if (scheduler->scheduler_io) tb_lo_scheduler_io_exit(scheduler->scheduler_io); scheduler->scheduler_io = tb_null; // check coroutines tb_assert(!tb_list_entry_size(&scheduler->coroutines_ready)); tb_assert(!tb_list_entry_size(&scheduler->coroutines_suspend)); // free all dead coroutines tb_lo_scheduler_free(&scheduler->coroutines_dead); // free all ready coroutines tb_lo_scheduler_free(&scheduler->coroutines_ready); // free all suspend coroutines tb_lo_scheduler_free(&scheduler->coroutines_suspend); // exit dead coroutines tb_list_entry_exit(&scheduler->coroutines_dead); // exit ready coroutines tb_list_entry_exit(&scheduler->coroutines_ready); // exit suspend coroutines tb_list_entry_exit(&scheduler->coroutines_suspend); // exit the scheduler tb_free(scheduler); }