static tb_bool_t tb_aicp_post_after_func(tb_aice_t const* aice) { // check tb_assert_and_check_return_val(aice && aice->aico && aice->code == TB_AICE_CODE_RUNTASK, tb_false); // the posted aice tb_aice_t* posted_aice = (tb_aice_t*)aice->priv; tb_assert_and_check_return_val(posted_aice && posted_aice->aico, tb_false); // the impl tb_aicp_impl_t* impl = (tb_aicp_impl_t*)tb_aico_aicp(aice->aico); tb_assert_and_check_return_val(impl && impl->ptor && impl->ptor->post, tb_false); // ok? tb_bool_t ok = tb_true; tb_bool_t posted = tb_true; if (aice->state == TB_STATE_OK) { // post it #ifdef __tb_debug__ if (!tb_aicp_post_((tb_aicp_ref_t)impl, posted_aice, ((tb_aico_impl_t*)aice->aico)->func, ((tb_aico_impl_t*)aice->aico)->line, ((tb_aico_impl_t*)aice->aico)->file)) #else if (!tb_aicp_post_((tb_aicp_ref_t)impl, posted_aice)) #endif { // not posted posted = tb_false; // failed posted_aice->state = TB_STATE_FAILED; } } // failed? else { // not posted posted = tb_false; // save state posted_aice->state = aice->state; } // not posted? done func now if (!posted) { // done func: notify failed if (posted_aice->func && !posted_aice->func(posted_aice)) ok = tb_false; } // exit the posted aice tb_free(posted_aice); // ok? return ok; }
static tb_bool_t tb_aicp_dns_reqt_func(tb_aice_ref_t aice) { // check tb_assert_and_check_return_val(aice && aice->aico && aice->code == TB_AICE_CODE_USEND, tb_false); // the aicp tb_aicp_ref_t aicp = (tb_aicp_ref_t)tb_aico_aicp(aice->aico); tb_assert_and_check_return_val(aicp, tb_false); // the impl tb_aicp_dns_impl_t* impl = (tb_aicp_dns_impl_t*)aice->priv; tb_assert_and_check_return_val(impl && impl->done.func, tb_false); // done tb_bool_t ok = tb_false; if (aice->state == TB_STATE_OK) { // trace tb_trace_d("reqt[%s]: aico: %p, server: %{ipaddr}, real: %lu", impl->host, impl->aico, &aice->u.usend.addr, aice->u.usend.real); // check tb_assert_and_check_return_val(aice->u.usend.real, tb_false); // post resp ok = tb_aico_urecv(aice->aico, impl->data, sizeof(impl->data), tb_aicp_dns_resp_func, (tb_pointer_t)impl); } // timeout or failed? else { // trace tb_trace_d("reqt[%s]: aico: %p, server: %{ipaddr}, state: %s", impl->host, impl->aico, &aice->u.usend.addr, tb_state_cstr(aice->state)); // the next server tb_ipaddr_ref_t server = &impl->list[impl->indx + 1]; if (!tb_ipaddr_is_empty(server)) { // indx++ impl->indx++; // init reqt tb_size_t size = tb_aicp_dns_reqt_init(impl); if (size) { // post reqt ok = tb_aico_usend(aice->aico, server, impl->data, size, tb_aicp_dns_reqt_func, (tb_pointer_t)impl); } } } // failed? done func if (!ok) impl->done.func((tb_aicp_dns_ref_t)impl, impl->host, tb_null, impl->done.priv); // continue return tb_true; }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ static tb_bool_t tb_demo_sock_aico_clos(tb_aice_t const* aice) { // check tb_assert_and_check_return_val(aice && aice->aico && aice->code == TB_AICE_CODE_CLOS, tb_false); // trace tb_trace_d("aico[%p]: clos: %s", aice->aico, tb_state_cstr(aice->state)); // exit aico tb_aico_exit(aice->aico); // kill aicp tb_aicp_kill(tb_aico_aicp(aice->aico)); // ok return tb_true; }
static tb_bool_t tb_demo_sock_acpt_func(tb_aice_ref_t aice) { // check tb_assert_and_check_return_val(aice && aice->code == TB_AICE_CODE_ACPT, tb_false); // the file path tb_char_t const* path = (tb_char_t const*)aice->priv; tb_assert_and_check_return_val(path, tb_false); // the aicp tb_aicp_ref_t aicp = tb_aico_aicp(aice->aico); tb_assert_and_check_return_val(aicp, tb_false); // acpt ok? if (aice->state == TB_STATE_OK) { // trace tb_trace_i("acpt[%p]: %p", aice->aico, aice->u.acpt.aico); // done tb_bool_t ok = tb_false; tb_demo_context_t* context = tb_null; do { // make context context = tb_malloc0_type(tb_demo_context_t); tb_assert_and_check_break(context); #ifdef TB_DEMO_MODE_SENDF // init file context->file = tb_file_init(path, TB_FILE_MODE_RO | TB_FILE_MODE_ASIO); tb_assert_and_check_break(context->file); // init sock aico context->aico[0] = aice->u.acpt.aico; tb_assert_and_check_break(context->aico[0]); // post sendf from file if (!tb_aico_sendf(context->aico[0], context->file, 0ULL, tb_file_size(context->file), tb_demo_sock_sendf_func, context)) break; #else // init data context->data = tb_malloc_bytes(TB_DEMO_FILE_READ_MAXN); tb_assert_and_check_break(context->file && context->data); // init sock aico context->aico[0] = aice->u.acpt.aico; tb_assert_and_check_break(context->aico[0]); // init file aico context->aico[1] = tb_aico_init(aicp); tb_assert_and_check_break(context->aico[1]); // open file aico if (!tb_aico_open_file_from_path(context->aico[1], path, TB_FILE_MODE_RO)) break; // post read from file if (!tb_aico_read(context->aico[1], context->size, context->data, TB_DEMO_FILE_READ_MAXN, tb_demo_file_read_func, context)) break; #endif // ok ok = tb_true; } while (0); // failed? if (!ok) { // exit context if (context) tb_demo_context_exit(context); } } // failed? else { // exit loop tb_trace_i("acpt[%p]: state: %s", aice->aico, tb_state_cstr(aice->state)); // clos aico if (aice->aico) tb_aico_clos(aice->aico, tb_demo_aico_clos, tb_null); } // ok return tb_true; }
static tb_bool_t tb_aicp_dns_resp_func(tb_aice_ref_t aice) { // check tb_assert_and_check_return_val(aice && aice->aico && aice->code == TB_AICE_CODE_URECV, tb_false); // the aicp tb_aicp_ref_t aicp = (tb_aicp_ref_t)tb_aico_aicp(aice->aico); tb_assert_and_check_return_val(aicp, tb_false); // the impl tb_aicp_dns_impl_t* impl = (tb_aicp_dns_impl_t*)aice->priv; tb_assert_and_check_return_val(impl, tb_false); // done tb_ipaddr_t addr = {0}; if (aice->state == TB_STATE_OK) { // trace tb_trace_d("resp[%s]: aico: %p, server: %{ipaddr}, real: %lu", impl->host, impl->aico, &aice->u.urecv.addr, aice->u.urecv.real); // check tb_assert_and_check_return_val(aice->u.urecv.real, tb_false); // done resp tb_aicp_dns_resp_done(impl, aice->u.urecv.real, &addr); } // timeout or failed? else { // trace tb_trace_d("resp[%s]: aico: %p, state: %s", impl->host, impl->aico, tb_state_cstr(aice->state)); } // ok or try to get ok from cache again if failed or timeout? tb_bool_t from_cache = tb_false; if (!tb_ipaddr_ip_is_empty(&addr) || (from_cache = tb_dns_cache_get(impl->host, &addr))) { // save to cache if (!from_cache) tb_dns_cache_set(impl->host, &addr); // done func impl->done.func((tb_aicp_dns_ref_t)impl, impl->host, &addr, impl->done.priv); return tb_true; } // try next server? tb_bool_t ok = tb_false; tb_ipaddr_ref_t server = &impl->list[impl->indx + 1]; if (!tb_ipaddr_is_empty(server)) { // indx++ impl->indx++; // init reqt tb_size_t size = tb_aicp_dns_reqt_init(impl); if (size) { // post reqt ok = tb_aico_usend(aice->aico, server, impl->data, size, tb_aicp_dns_reqt_func, (tb_pointer_t)impl); } } // failed? done func if (!ok) impl->done.func((tb_aicp_dns_ref_t)impl, impl->host, tb_null, impl->done.priv); // continue return tb_true; }