Example #1
0
static tb_void_t tb_aiop_spak_wait_timeout(tb_bool_t killed, tb_cpointer_t priv)
{
    // the aico
    tb_aiop_aico_t* aico = (tb_aiop_aico_t*)priv;
    tb_assert_and_check_return(aico && aico->waiting);

    // the impl
    tb_aiop_ptor_impl_t* impl = aico->impl;
    tb_assert_and_check_return(impl && impl->aiop);

    // for sock
    if (aico->base.type == TB_AICO_TYPE_SOCK)
    {
        // check
        tb_assert_and_check_return(aico->aioo);

        // delo aioo
        tb_aiop_delo(impl->aiop, aico->aioo);
        aico->aioo = tb_null;
    }

    // have been waited ok for the spak loop? need not spak it repeatly
    tb_bool_t ok = tb_false;
    if (!aico->wait_ok)
    {
        // the priority
        tb_size_t priority = tb_aice_impl_priority(&aico->aice);
        tb_assert_and_check_return(priority < tb_arrayn(impl->spak) && impl->spak[priority]);

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

        // enter
        tb_spinlock_enter(&impl->lock);

        // spak aice
        if (!tb_queue_full(impl->spak[priority]))
        {
            // save state
            aico->aice.state = killed? TB_STATE_KILLED : TB_STATE_TIMEOUT;

            // put it
            tb_queue_put(impl->spak[priority], &aico->aice);

            // ok
            ok = tb_true;
            aico->wait_ok = 1;
        }
        else tb_assert(0);

        // leave
        tb_spinlock_leave(&impl->lock);
    }

    // work it
    if (ok) tb_aiop_spak_work(impl);
}
Example #2
0
static tb_void_t tb_aiop_ptor_kill(tb_aicp_ptor_impl_t* ptor)
{
    // check
    tb_aiop_ptor_impl_t* impl = (tb_aiop_ptor_impl_t*)ptor;
    tb_assert_and_check_return(impl && impl->timer && impl->ltimer && impl->aiop);

    // trace
    tb_trace_d("kill: ..");

    // kill aiop
    tb_aiop_kill(impl->aiop);

    // kill file
    tb_aicp_file_kill(impl); 

    // work it
    tb_aiop_spak_work(impl);
}
Example #3
0
static tb_void_t tb_aiop_spak_runtask_timeout(tb_bool_t killed, tb_cpointer_t priv)
{
    // the aico
    tb_aiop_aico_t* aico = (tb_aiop_aico_t*)priv;
    tb_assert_and_check_return(aico && aico->waiting);

    // the impl
    tb_aiop_ptor_impl_t* impl = aico->impl;
    tb_assert_and_check_return(impl);

    // the priority
    tb_size_t priority = tb_aice_impl_priority(&aico->aice);
    tb_assert_and_check_return(priority < tb_arrayn(impl->spak) && impl->spak[priority]);

    // enter
    tb_spinlock_enter(&impl->lock);

    // trace
    tb_trace_d("runtask: timeout: code: %lu, priority: %lu, size: %lu", aico->aice.code, priority, tb_queue_size(impl->spak[priority]));

    // spak aice
    tb_bool_t ok = tb_false;
    if (!tb_queue_full(impl->spak[priority]))
    {
        // save state
        aico->aice.state = killed? TB_STATE_KILLED : TB_STATE_OK;

        // put it
        tb_queue_put(impl->spak[priority], &aico->aice);

        // ok
        ok = tb_true;
    }
    else tb_assert(0);

    // leave
    tb_spinlock_leave(&impl->lock);

    // work it
    if (ok) tb_aiop_spak_work(impl);
}
Example #4
0
static tb_pointer_t tb_aiop_spak_loop(tb_cpointer_t priv)
{
    // check
    tb_aiop_ptor_impl_t*    impl = (tb_aiop_ptor_impl_t*)priv;
    tb_aicp_impl_t*         aicp = impl? impl->base.aicp : tb_null;

    // done
    do
    {
        // check
        tb_assert_and_check_break(impl && impl->aiop && impl->list && impl->timer && impl->ltimer && aicp);

        // trace
        tb_trace_d("loop: init");

        // loop
        while (!tb_atomic_get(&aicp->kill))
        {
            // the delay
            tb_size_t delay = tb_timer_delay(impl->timer);

            // the ldelay
            tb_size_t ldelay = tb_ltimer_delay(impl->ltimer);
            tb_assert_and_check_break(ldelay != -1);

            // trace
            tb_trace_d("loop: wait: ..");

            // wait aioe
            tb_long_t real = tb_aiop_wait(impl->aiop, impl->list, impl->maxn, tb_min(delay, ldelay));

            // trace
            tb_trace_d("loop: wait: %ld", real);

            // spak ctime
            tb_cache_time_spak();

            // spak timer
            if (!tb_timer_spak(impl->timer)) break;

            // spak ltimer
            if (!tb_ltimer_spak(impl->ltimer)) break;

            // killed?
            tb_check_break(real >= 0);

            // error? out of range
            tb_assert_and_check_break(real <= impl->maxn);

            // timeout?
            tb_check_continue(real);

            // grow it if aioe is full
            if (real == impl->maxn)
            {
                // grow size
                impl->maxn += (aicp->maxn >> 4) + 16;
                if (impl->maxn > aicp->maxn) impl->maxn = aicp->maxn;

                // grow list
                impl->list = tb_ralloc(impl->list, impl->maxn * sizeof(tb_aioe_t));
                tb_assert_and_check_break(impl->list);
            }

            // walk aioe list
            tb_size_t i = 0;
            tb_bool_t end = tb_false;
            for (i = 0; i < real && !end; i++)
            {
                // the aioe
                tb_aioe_ref_t aioe = &impl->list[i];
                tb_assert_and_check_break_state(aioe, end, tb_true);

                // the aice
                tb_aice_ref_t aice = (tb_aice_ref_t)aioe->priv;
                tb_assert_and_check_break_state(aice, end, tb_true);

                // the aico
                tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
                tb_assert_and_check_break_state(aico, end, tb_true);

                // have wait?
                tb_check_continue(aice->code);

                // have been waited ok for the timer timeout/killed func? need not spak it repeatly
                tb_check_continue(!aico->wait_ok);

                // sock?
                if (aico->base.type == TB_AICO_TYPE_SOCK)
                {
                    // push the acpt aice
                    if (aice->code == TB_AICE_CODE_ACPT) end = tb_aiop_push_acpt(impl, aice)? tb_false : tb_true;
                    // push the sock aice
                    else end = tb_aiop_push_sock(impl, aice)? tb_false : tb_true;
                }
                else if (aico->base.type == TB_AICO_TYPE_FILE)
                {
                    // poll file
                    tb_aicp_file_poll(impl);
                }
                else tb_assert(0);
            }

            // end?
            tb_check_break(!end);

            // work it
            tb_aiop_spak_work(impl);
        }

    } while (0);

    // trace
    tb_trace_d("loop: exit");

    // kill
    tb_aicp_kill((tb_aicp_ref_t)aicp);

    // exit
    tb_thread_return(tb_null);
    return tb_null;
}
Example #5
0
static tb_bool_t tb_aiop_ptor_post(tb_aicp_ptor_impl_t* ptor, tb_aice_t const* aice)
{
    // check
    tb_aiop_ptor_impl_t* impl = (tb_aiop_ptor_impl_t*)ptor;
    tb_assert_and_check_return_val(impl && aice && aice->aico, tb_false);

    // optimizate to spak the clos aice 
    if (aice->code == TB_AICE_CODE_CLOS)
    {
        // spak the clos
        tb_aice_t resp = *aice;
        if (tb_aiop_spak_clos(impl, &resp) <= 0) return tb_false;

        // done the aice response function
        aice->func(&resp);

        // post ok
        return tb_true;
    }
    
    // the priority
    tb_size_t priority = tb_aice_impl_priority(aice);
    tb_assert_and_check_return_val(priority < tb_arrayn(impl->spak) && impl->spak[priority], tb_false);

    // done
    tb_bool_t           ok = tb_true;
    tb_aico_impl_t*     aico = (tb_aico_impl_t*)aice->aico;
    switch (aico->type)
    {
    case TB_AICO_TYPE_SOCK:
    case TB_AICO_TYPE_TASK:
        {
            // enter 
            tb_spinlock_enter(&impl->lock);

            // post aice
            if (!tb_queue_full(impl->spak[priority])) 
            {
                // put
                tb_queue_put(impl->spak[priority], aice);

                // trace
                tb_trace_d("post: code: %lu, priority: %lu, size: %lu", aice->code, priority, tb_queue_size(impl->spak[priority]));
            }
            else
            {
                // failed
                ok = tb_false;

                // trace
                tb_trace_e("post: code: %lu, priority: %lu, size: %lu: failed", aice->code, priority, tb_queue_size(impl->spak[priority]));
            }

            // leave 
            tb_spinlock_leave(&impl->lock);
        }
        break;
    case TB_AICO_TYPE_FILE:
        {
            // post file
            ok = tb_aicp_file_post(impl, aice);
        }
        break;
    default:
        ok = tb_false;
        break;
    }

    // work it 
    if (ok) tb_aiop_spak_work(impl);

    // ok?
    return ok;
}