Ejemplo n.º 1
0
static tb_long_t tb_aiop_ptor_spak(tb_aicp_ptor_impl_t* ptor, tb_handle_t loop, tb_aice_t* resp, tb_long_t timeout)
{
    // check
    tb_aiop_ptor_impl_t* impl = (tb_aiop_ptor_impl_t*)ptor;
    tb_aicp_impl_t*      aicp = impl? impl->base.aicp : tb_null;
    tb_assert_and_check_return_val(impl && impl->wait && aicp && resp, -1);

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

    // done
    tb_long_t ok = -1;
    tb_bool_t null = tb_false;
    do
    {
        // check
        tb_assert_and_check_break(impl->spak[0] && impl->spak[1]);

        // clear ok
        ok = 0;

        // spak aice from the higher priority spak first
        if (!(null = tb_queue_null(impl->spak[0]))) 
        {
            // get resp
            tb_aice_t const* aice = tb_queue_get(impl->spak[0]);
            if (aice) 
            {
                // save resp
                *resp = *aice;

                // trace
                tb_trace_d("spak[%u]: code: %lu, priority: 0, size: %lu", (tb_uint16_t)tb_thread_self(), aice->code, tb_queue_size(impl->spak[0]));

                // pop it
                tb_queue_pop(impl->spak[0]);

                // ok
                ok = 1;
            }
        }

        // no aice? spak aice from the lower priority spak next
        if (!ok && !(null = tb_queue_null(impl->spak[1]))) 
        {
            // get resp
            tb_aice_t const* aice = tb_queue_get(impl->spak[1]);
            if (aice) 
            {
                // save resp
                *resp = *aice;

                // trace
                tb_trace_d("spak[%u]: code: %lu, priority: 1, size: %lu", (tb_uint16_t)tb_thread_self(), aice->code, tb_queue_size(impl->spak[1]));

                // pop it
                tb_queue_pop(impl->spak[1]);

                // ok
                ok = 1;
            }
        }

    } while (0);

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

    // done it
    if (ok) ok = tb_aiop_spak_done(impl, resp);

    // null? wait it
    tb_check_return_val(!ok && null, ok);
    
    // killed? break it
    tb_check_return_val(!tb_atomic_get(&aicp->kill), -1);

    // trace
    tb_trace_d("wait[%u]: ..", (tb_uint16_t)tb_thread_self());

    // wait some time
    if (tb_semaphore_wait(impl->wait, timeout) < 0) return -1;

    // timeout 
    return 0;
}
Ejemplo 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);
}
Ejemplo n.º 3
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;
}