static tb_long_t tb_aiop_spak_sendf(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice) { // check tb_assert_and_check_return_val(impl && aice, -1); tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_SENDF, -1); tb_assert_and_check_return_val(aice->u.sendf.file && aice->u.sendf.size, -1); // the aico tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico; tb_assert_and_check_return_val(aico && aico->base.handle, -1); // try to send it tb_long_t real = 0; tb_hize_t send = 0; tb_hize_t seek = aice->u.sendf.seek; tb_hize_t size = aice->u.sendf.size; tb_handle_t file = aice->u.sendf.file; while (send < size) { // send it real = tb_socket_sendf(aico->base.handle, file, seek + send, size - send); // save send if (real > 0) send += real; else break; } // trace tb_trace_d("sendf[%p]: %llu", aico, send); // no send? if (!send) { // wait it if (!real && !aico->waiting) { // wait ok? if (tb_aiop_spak_wait(impl, aice)) return 0; // wait failed else aice->state = TB_STATE_FAILED; } // closed else aice->state = TB_STATE_CLOSED; } else { // ok or closed? aice->state = TB_STATE_OK; // save the send size aice->u.sendf.real = send; } // reset wait aico->waiting = 0; aico->aice.code = TB_AICE_CODE_NONE; // ok return 1; }
static tb_bool_t tb_demo_http_session_file_send(tb_socket_ref_t sock, tb_file_ref_t file) { // check tb_assert_and_check_return_val(sock && file, tb_false); // send data tb_hize_t send = 0; tb_hize_t size = tb_file_size(file); tb_long_t wait = 0; while (send < size) { // send it tb_hong_t real = tb_socket_sendf(sock, file, send, size - send); // has data? if (real > 0) { send += real; wait = 0; } // no data? wait it else if (!real && !wait) { // wait it wait = tb_socket_wait(sock, TB_SOCKET_EVENT_SEND, TB_DEMO_TIMEOUT); tb_assert_and_check_break(wait >= 0); } // failed or end? else break; } // ok? return send == size; }