tb_lo_scheduler_io_ref_t tb_lo_scheduler_io_self() { // get the current scheduler tb_lo_scheduler_t* scheduler = (tb_lo_scheduler_t*)tb_lo_scheduler_self_(); // get the current io scheduler return scheduler? (tb_lo_scheduler_io_ref_t)scheduler->scheduler_io : tb_null; }
tb_lo_scheduler_io_ref_t tb_lo_scheduler_io_need(tb_lo_scheduler_t* scheduler) { // get the current scheduler if (!scheduler) scheduler = (tb_lo_scheduler_t*)tb_lo_scheduler_self_(); if (scheduler) { // init io scheduler first if (!scheduler->scheduler_io) scheduler->scheduler_io = tb_lo_scheduler_io_init(scheduler); tb_assert(scheduler->scheduler_io); // get the current io scheduler return (tb_lo_scheduler_io_ref_t)scheduler->scheduler_io; } return tb_null; }
tb_bool_t tb_lo_scheduler_start(tb_lo_scheduler_t* scheduler, tb_lo_coroutine_func_t func, tb_cpointer_t priv, tb_lo_coroutine_free_t free) { // check tb_assert(func); // done tb_bool_t ok = tb_false; tb_lo_coroutine_t* coroutine = tb_null; do { // trace tb_trace_d("start .."); // get the current scheduler if (!scheduler) scheduler = (tb_lo_scheduler_t*)tb_lo_scheduler_self_(); tb_assert_and_check_break(scheduler); // have been stopped? do not continue to start new coroutines tb_check_break(!scheduler->stopped); // reuses dead coroutines in init function if (tb_list_entry_size(&scheduler->coroutines_dead)) { // get the next entry from head tb_list_entry_ref_t entry = tb_list_entry_head(&scheduler->coroutines_dead); tb_assert_and_check_break(entry); // remove it from the ready coroutines tb_list_entry_remove_head(&scheduler->coroutines_dead); // get the dead coroutine coroutine = (tb_lo_coroutine_t*)tb_list_entry(&scheduler->coroutines_dead, entry); // reinit this coroutine tb_lo_coroutine_reinit(coroutine, func, priv, free); } // init coroutine if (!coroutine) coroutine = tb_lo_coroutine_init((tb_lo_scheduler_ref_t)scheduler, func, priv, free); tb_assert_and_check_break(coroutine); // ready coroutine tb_lo_scheduler_make_ready(scheduler, coroutine); // the dead coroutines is too much? free some coroutines while (tb_list_entry_size(&scheduler->coroutines_dead) > TB_SCHEDULER_DEAD_CACHE_MAXN) { // get the next entry from head tb_list_entry_ref_t entry = tb_list_entry_head(&scheduler->coroutines_dead); tb_assert(entry); // remove it from the ready coroutines tb_list_entry_remove_head(&scheduler->coroutines_dead); // exit this coroutine tb_lo_coroutine_exit((tb_lo_coroutine_t*)tb_list_entry(&scheduler->coroutines_dead, entry)); } // ok ok = tb_true; } while (0); // trace tb_trace_d("start %s", ok? "ok" : "no"); // ok? return ok; }