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