Esempio n. 1
0
File: aicp.c Progetto: DonkeyWs/tbox
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * 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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}