Пример #1
0
Файл: aiop.c Проект: cdrr/tbox
tb_aioo_ref_t tb_aiop_addo(tb_aiop_ref_t aiop, tb_socket_ref_t sock, tb_size_t code, tb_cpointer_t priv)
{
    // check
    tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
    tb_assert_and_check_return_val(impl && impl->rtor && impl->rtor->addo && sock, tb_null);
    tb_assert(tb_aiop_have(aiop, code));

    // done
    tb_bool_t       ok = tb_false;
    tb_aioo_ref_t   aioo = tb_null;
    do
    {
        // init aioo
        aioo = tb_aiop_aioo_init(impl, sock, code, priv);
        tb_assert_and_check_break(aioo);
        
        // addo aioo
        if (!impl->rtor->addo(impl->rtor, (tb_aioo_impl_t*)aioo)) break;

        // ok
        ok = tb_true;

    } while (0);

    // failed? remove aioo
    if (!ok && aioo) 
    {
        tb_aiop_aioo_exit(impl, aioo);
        aioo = tb_null;
    }

    // ok?
    return aioo;
}
Пример #2
0
Файл: aiop.c Проект: cdrr/tbox
tb_bool_t tb_aiop_post(tb_aiop_ref_t aiop, tb_aioe_ref_t aioe)
{
    // check
    tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
    tb_assert_and_check_return_val(impl && impl->rtor && impl->rtor->post && aioe, tb_false);
    tb_assert(tb_aiop_have(aiop, aioe->code));

    // post
    return impl->rtor->post(impl->rtor, aioe);
}
Пример #3
0
static tb_bool_t tb_aiop_spak_wait(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
{
    // check
    tb_assert_and_check_return_val(impl && impl->aiop && impl->ltimer && aice, tb_false);

    // the aico
    tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
    tb_assert_and_check_return_val(aico && aico->base.handle && !aico->task, tb_false);

    // the aioe code
    tb_size_t code = tb_aiop_aioe_code(aice);
    tb_assert_and_check_return_val(code != TB_AIOE_CODE_NONE, tb_false);

    // trace
    tb_trace_d("wait: aico: %p, code: %lu: time: %lld: ..", aico, aice->code, tb_cache_time_mclock());

    // done
    tb_bool_t ok = tb_false;
    tb_aice_t prev = aico->aice;
    do
    {
        // wait it
        aico->aice = *aice;
        aico->waiting = 1;
        aico->wait_ok = 0;

        // wait once if not accept
        if (aice->code != TB_AICE_CODE_ACPT) code |= TB_AIOE_CODE_ONESHOT;

        // using the edge triggered mode
        if (tb_aiop_have(impl->aiop, TB_AIOE_CODE_CLEAR))
            code |= TB_AIOE_CODE_CLEAR;

        // have aioo?
        if (!aico->aioo)
        {
            // addo wait
            if (!(aico->aioo = tb_aiop_addo(impl->aiop, aico->base.handle, code, &aico->aice))) break;
        }
        else
        {
            // sete wait
            if (!tb_aiop_sete(impl->aiop, aico->aioo, code, &aico->aice)) break;
        }

        // add timeout task
        tb_long_t timeout = tb_aico_impl_timeout_from_code((tb_aico_impl_t*)aico, aice->code);
        if (timeout >= 0)
        {
            // add it
            aico->task = tb_ltimer_task_init(impl->ltimer, timeout, tb_false, tb_aiop_spak_wait_timeout, aico);
            tb_assert_and_check_break(aico->task);
            aico->bltimer = 1;
        }

        // ok
        ok = tb_true;

    } while (0);

    // failed? restore it
    if (!ok)
    {
        // trace
        tb_trace_d("wait: aico: %p, code: %lu: failed", aico, aice->code);

        // restore it
        aico->aice = prev;
        aico->waiting = 0;
    }

    // ok?
    return ok;
}
Пример #4
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * interfaces
 */
static tb_aicp_ptor_impl_t* tb_aiop_ptor_init(tb_aicp_impl_t* aicp)
{
    // check
    tb_assert_and_check_return_val(aicp && aicp->maxn, tb_null);

    // done
    tb_bool_t               ok = tb_false;
    tb_aiop_ptor_impl_t*    impl = tb_null;
    do
    {
        // make ptor
        impl = tb_malloc0_type(tb_aiop_ptor_impl_t);
        tb_assert_and_check_break(impl);

        // init base
        impl->base.aicp         = aicp;
        impl->base.step         = sizeof(tb_aiop_aico_t);
        impl->base.kill         = tb_aiop_ptor_kill;
        impl->base.exit         = tb_aiop_ptor_exit;
        impl->base.addo         = tb_aiop_ptor_addo;
        impl->base.kilo         = tb_aiop_ptor_kilo;
        impl->base.post         = tb_aiop_ptor_post;
        impl->base.loop_spak    = tb_aiop_ptor_spak;

        // init lock
        if (!tb_spinlock_init(&impl->lock)) break;

        // init wait
        impl->wait = tb_semaphore_init(0);
        tb_assert_and_check_break(impl->wait);

        // init aiop
        impl->aiop = tb_aiop_init(aicp->maxn);
        tb_assert_and_check_break(impl->aiop);

        // check 
        tb_assert_and_check_break(tb_aiop_have(impl->aiop, TB_AIOE_CODE_EALL | TB_AIOE_CODE_ONESHOT));

        // init spak
        impl->spak[0] = tb_queue_init((aicp->maxn >> 4) + 16, tb_item_func_mem(sizeof(tb_aice_t), tb_null, tb_null));
        impl->spak[1] = tb_queue_init((aicp->maxn >> 4) + 16, tb_item_func_mem(sizeof(tb_aice_t), tb_null, tb_null));
        tb_assert_and_check_break(impl->spak[0] && impl->spak[1]);

        // init file
        if (!tb_aicp_file_init(impl)) break;

        // init list
        impl->maxn = (aicp->maxn >> 4) + 16;
        impl->list = tb_nalloc0(impl->maxn, sizeof(tb_aioe_t));
        tb_assert_and_check_break(impl->list);

        // init timer and using cache time
        impl->timer = tb_timer_init((aicp->maxn >> 4) + 16, tb_true);
        tb_assert_and_check_break(impl->timer);

        // init ltimer and using cache time
        impl->ltimer = tb_ltimer_init(aicp->maxn, TB_LTIMER_TICK_S, tb_true);
        tb_assert_and_check_break(impl->ltimer);

        // register lock profiler
#ifdef TB_LOCK_PROFILER_ENABLE
        tb_lock_profiler_register(tb_lock_profiler(), (tb_pointer_t)&impl->lock, "aicp_aiop");
#endif

        // init loop
        impl->loop = tb_thread_init(tb_null, tb_aiop_spak_loop, impl, 0);
        tb_assert_and_check_break(impl->loop);

        // ok
        ok = tb_true;

    } while (0);

    // failed?
    if (!ok)
    {
        // exit it
        if (impl) tb_aiop_ptor_exit((tb_aicp_ptor_impl_t*)impl);
        return tb_null;
    }

    // ok?
    return (tb_aicp_ptor_impl_t*)impl;
}