Esempio n. 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);
}
Esempio n. 2
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);
}
Esempio n. 3
0
static tb_bool_t tb_aiop_push_sock(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
{
    // check
    tb_assert_and_check_return_val(impl && aice && aice->aico, tb_false);

    // 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);

    // this aico is killed? post to higher priority queue
    if (tb_aico_impl_is_killed((tb_aico_impl_t*)aice->aico)) priority = 0;

    // trace
    tb_trace_d("push: aico: %p, handle: %p, code: %lu, priority: %lu", aice->aico, tb_aico_sock(aice->aico), aice->code, priority);

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

    // not full?
    if (!tb_queue_full(impl->spak[priority]))
    {
        // push aice to the spak queue
        tb_queue_put(impl->spak[priority], aice);

        // wait ok if be not acpt aice
        if (aice->code != TB_AICE_CODE_ACPT) ((tb_aiop_aico_t*)aice->aico)->wait_ok = 1;
    }
    else
    {
        // trace
        tb_trace_e("push: failed, the spak queue is full!");
    }

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

    // ok
    return tb_true;
}
Esempio n. 4
0
static tb_bool_t tb_aiop_push_acpt(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
{
    // check
    tb_assert_and_check_return_val(impl && aice, tb_false);
    tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_ACPT, 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, tb_false);

    // 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);

    // init the acpt aice
    tb_aice_t acpt_aice = *aice;
    acpt_aice.state = TB_STATE_OK;

    // done
    tb_size_t       list_indx = 0;
    tb_size_t       list_size = 0;
    tb_socket_ref_t list_sock[2048];
    tb_ipaddr_t       list_addr[2048];
    tb_size_t       list_maxn = tb_arrayn(list_sock);
    tb_socket_ref_t acpt = (tb_socket_ref_t)aico->base.handle;
    tb_queue_ref_t  spak = impl->spak[priority];
    tb_socket_ref_t sock = tb_null;
    do
    {
        // accept it
        for (list_size = 0; list_size < list_maxn && (list_sock[list_size] = tb_socket_accept(acpt, list_addr + list_size)); list_size++) ;

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

        // push some acpt aice
        for (list_indx = 0; list_indx < list_size && (sock = list_sock[list_indx]); list_indx++)
        {
            // init aico
            acpt_aice.u.acpt.aico = tb_aico_init(aico->base.aicp);

            // trace
            tb_trace_d("push: acpt[%p]: sock: %p, aico: %p", aico->base.handle, sock, acpt_aice.u.acpt.aico);

            // open aico and push the acpt aice if not full?
            if (    acpt_aice.u.acpt.aico
                    &&  tb_aico_open_sock(acpt_aice.u.acpt.aico, sock)
                    &&  !tb_queue_full(spak))
            {
                // save addr
                tb_ipaddr_copy(&acpt_aice.u.acpt.addr, list_addr + list_indx);

                // push to the spak queue
                tb_queue_put(spak, &acpt_aice);
            }
            else
            {
                // close the left sock
                tb_size_t i;
                for (i = list_indx; i < list_size; i++)
                {
                    // close it
                    if (list_sock[i]) tb_socket_exit(list_sock[i]);
                    list_sock[i] = tb_null;
                }

                // exit aico
                if (acpt_aice.u.acpt.aico) tb_aico_exit(acpt_aice.u.acpt.aico);
                acpt_aice.u.acpt.aico = tb_null;

                // trace
                tb_trace_e("push: acpt failed!");
                break;
            }
        }

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

    } while (list_indx == list_maxn);

    // ok
    return tb_true;
}
Esempio n. 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;
}