tb_void_t tb_timer_loop(tb_timer_ref_t timer) { // check tb_timer_impl_t* impl = (tb_timer_impl_t*)timer; tb_assert_and_check_return(impl); // work++ tb_atomic_fetch_and_inc(&impl->work); // init event tb_spinlock_enter(&impl->lock); if (!impl->event) impl->event = tb_event_init(); tb_spinlock_leave(&impl->lock); // loop while (!tb_atomic_get(&impl->stop)) { // the delay tb_size_t delay = tb_timer_delay(timer); if (delay) { // the event tb_spinlock_enter(&impl->lock); tb_event_ref_t event = impl->event; tb_spinlock_leave(&impl->lock); tb_check_break(event); // wait some time if (tb_event_wait(event, delay) < 0) break; } // spak ctime if (impl->ctime) tb_cache_time_spak(); // spak it if (!tb_timer_spak(timer)) break; } // work-- tb_atomic_fetch_and_dec(&impl->work); }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_bool_t xm_init_(tb_size_t mode, tb_hize_t build) { // is inited? if (tb_atomic_fetch_and_inc(&g_init)) return tb_true; // trace tb_trace_d("init: .."); // check mode if (!xm_check_mode(mode)) return tb_false; // check version xm_version_check(build); // init tbox if (!tb_init(tb_null, tb_null)) return tb_false; // trace tb_trace_d("init: ok"); // ok return tb_true; }
tb_void_t tb_aicp_loop_util(tb_aicp_ref_t aicp, tb_bool_t (*stop)(tb_cpointer_t priv), tb_cpointer_t priv) { // check tb_aicp_impl_t* impl = (tb_aicp_impl_t*)aicp; tb_assert_and_check_return(impl); // the ptor tb_aicp_ptor_impl_t* ptor = impl->ptor; tb_assert_and_check_return(ptor && ptor->loop_spak); // the loop spak tb_long_t (*loop_spak)(tb_aicp_ptor_impl_t* , tb_handle_t, tb_aice_ref_t , tb_long_t ) = ptor->loop_spak; // worker++ tb_atomic_fetch_and_inc(&impl->work); // init loop tb_handle_t loop = ptor->loop_init? ptor->loop_init(ptor) : tb_null; // trace tb_trace_d("loop[%p]: init", loop); // spak ctime tb_cache_time_spak(); // loop while (1) { // spak tb_aice_t resp = {0}; tb_long_t ok = loop_spak(ptor, loop, &resp, -1); // spak ctime tb_cache_time_spak(); // failed? tb_check_break(ok >= 0); // timeout? tb_check_continue(ok); // check aico tb_aico_impl_t* aico = (tb_aico_impl_t*)resp.aico; tb_assert_and_check_continue(aico); // trace tb_trace_d("loop[%p]: spak: code: %lu, aico: %p, state: %s: %ld", loop, resp.code, aico, aico? tb_state_cstr(tb_atomic_get(&aico->state)) : "null", ok); // pending? clear state if be not accept or accept failed tb_size_t state = TB_STATE_OPENED; state = (resp.code != TB_AICE_CODE_ACPT || resp.state != TB_STATE_OK)? tb_atomic_fetch_and_pset(&aico->state, TB_STATE_PENDING, state) : tb_atomic_get(&aico->state); // killed or killing? if (state == TB_STATE_KILLED || state == TB_STATE_KILLING) { // update the aice state resp.state = TB_STATE_KILLED; // killing? update to the killed state tb_atomic_fetch_and_pset(&aico->state, TB_STATE_KILLING, TB_STATE_KILLED); } // done func, @note maybe the aico exit will be called if (resp.func && !resp.func(&resp)) { // trace #ifdef __tb_debug__ tb_trace_e("loop[%p]: done aice func failed with code: %lu at line: %lu, func: %s, file: %s!", loop, resp.code, aico->line, aico->func, aico->file); #else tb_trace_e("loop[%p]: done aice func failed with code: %lu!", loop, resp.code); #endif } // killing? update to the killed state tb_atomic_fetch_and_pset(&aico->state, TB_STATE_KILLING, TB_STATE_KILLED); // stop it? if (stop && stop(priv)) tb_aicp_kill(aicp); } // exit loop if (ptor->loop_exit) ptor->loop_exit(ptor, loop); // worker-- tb_atomic_fetch_and_dec(&impl->work); // trace tb_trace_d("loop[%p]: exit", loop); }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_bool_t tb_init_(tb_handle_t priv, tb_allocator_ref_t allocator, tb_byte_t* data, tb_size_t size, tb_size_t mode, tb_hize_t build) { // is inited? if (tb_atomic_fetch_and_inc(&g_init)) return tb_true; // init trace if (!tb_trace_init()) return tb_false; // trace tb_trace_d("init: %p %lu", data, size); // check mode if (!tb_check_mode(mode)) return tb_false; // check types tb_assert_static(sizeof(tb_byte_t) == 1); tb_assert_static(sizeof(tb_uint_t) == 4); tb_assert_static(sizeof(tb_uint8_t) == 1); tb_assert_static(sizeof(tb_uint16_t) == 2); tb_assert_static(sizeof(tb_uint32_t) == 4); tb_assert_static(sizeof(tb_hize_t) == 8); tb_assert_static(sizeof(tb_wchar_t) == sizeof(L'w')); tb_assert_static(TB_CPU_BITSIZE == (sizeof(tb_size_t) << 3)); tb_assert_static(TB_CPU_BITSIZE == (sizeof(tb_long_t) << 3)); tb_assert_static(TB_CPU_BITSIZE == (sizeof(tb_pointer_t) << 3)); tb_assert_static(TB_CPU_BITSIZE == (sizeof(tb_handle_t) << 3)); // check byteorder tb_assert_and_check_return_val(tb_check_order_word(), tb_false); tb_assert_and_check_return_val(tb_check_order_double(), tb_false); // init singleton if (!tb_singleton_init()) return tb_false; // init memory if (!tb_memory_init(allocator, data, size)) return tb_false; // init platform if (!tb_platform_init(priv)) return tb_false; // init libc if (!tb_libc_init()) return tb_false; // init math if (!tb_math_init()) return tb_false; // init libm if (!tb_libm_init()) return tb_false; // init network if (!tb_network_init()) return tb_false; // init object #ifdef TB_CONFIG_MODULE_HAVE_OBJECT if (!tb_object_context_init()) return tb_false; #endif // check version tb_version_check(build); // trace tb_trace_d("init: ok"); // ok return tb_true; }