static tb_void_t tb_demo_coroutine_client(tb_cpointer_t priv) { // check tb_socket_ref_t sock = (tb_socket_ref_t)priv; tb_assert_and_check_return(sock); // done tb_demo_http_session_t session; do { // init session if (!tb_demo_http_session_init(&session, sock)) break; // read the request header if (!tb_demo_http_session_head_recv(&session)) break; // trace tb_trace_d("path: %s", session.path); // get file or data? tb_char_t const* data = tb_null; if (session.method == TB_HTTP_METHOD_GET) { // only send data? if (g_onlydata) data = g_rootdir; else { // make full path tb_long_t size = tb_snprintf((tb_char_t*)session.data, sizeof(session.data), "%s%s%s", g_rootdir, session.path[0] != '/'? "/" : "", session.path); if (size > 0) session.data[size] = 0; // init file session.file = tb_file_init((tb_char_t*)session.data, TB_FILE_MODE_RO | TB_FILE_MODE_BINARY); // not found? if (!session.file) session.code = TB_HTTP_CODE_NOT_FOUND; } } // send the response if (!tb_demo_http_session_resp_send(&session, data)) break; // exit file if (session.file) tb_file_exit(session.file); session.file = tb_null; // trace tb_trace_d("ok!"); } while (session.keep_alive); // exit session tb_demo_http_session_exit(&session); }
tb_bool_t tb_file_create(tb_char_t const* path) { // check tb_assert_and_check_return_val(path, tb_false); // make it tb_file_ref_t file = tb_file_init(path, TB_FILE_MODE_CREAT | TB_FILE_MODE_WO | TB_FILE_MODE_TRUNC); if (file) tb_file_exit(file); // ok? return file? tb_true : tb_false; }
static tb_void_t tb_demo_http_session_exit(tb_demo_http_session_ref_t session) { // check tb_assert(session); // exit socket if (session->sock) tb_socket_exit(session->sock); session->sock = tb_null; // exit file if (session->file) tb_file_exit(session->file); session->file = tb_null; }
tb_bool_t tb_aico_open_file_from_path(tb_aico_ref_t aico, tb_char_t const* path, tb_size_t mode) { // check tb_aico_impl_t* impl = (tb_aico_impl_t*)aico; tb_aicp_impl_t* aicp_impl = (tb_aicp_impl_t*)impl->aicp; tb_assert_and_check_return_val(impl && path && aicp_impl && aicp_impl->ptor && aicp_impl->ptor->addo, tb_false); // done tb_bool_t ok = tb_false; tb_file_ref_t file = tb_null; do { // closed? tb_assert_and_check_break(tb_atomic_get(&impl->state) == TB_STATE_CLOSED); tb_assert_and_check_break(!impl->type && !impl->handle); // init file file = tb_file_init(path, mode | TB_FILE_MODE_ASIO); tb_assert_and_check_break(file); // bind type and handle impl->type = TB_AICO_TYPE_FILE; impl->handle = (tb_handle_t)file; // addo aico ok = aicp_impl->ptor->addo(aicp_impl->ptor, impl); tb_assert_and_check_break(ok); // opened tb_atomic_set(&impl->state, TB_STATE_OPENED); } while (0); // failed? if (!ok) { // exit it if (file) tb_file_exit(file); file = tb_null; } // ok? return ok; }
tb_bool_t tb_trace_file_set(tb_file_ref_t file) { // check tb_check_return_val(file, tb_false); // enter tb_spinlock_enter_without_profiler(&g_lock); // exit the previous file if (g_file && !g_bref) tb_file_exit(g_file); // set the file g_file = file; g_bref = tb_true; // leave tb_spinlock_leave(&g_lock); // ok return tb_true; }
tb_void_t tb_trace_exit() { // sync trace tb_trace_sync(); // enter tb_spinlock_enter_without_profiler(&g_lock); // clear mode g_mode = TB_TRACE_MODE_PRINT; // clear file if (g_file && !g_bref) tb_file_exit(g_file); g_file = tb_null; g_bref = tb_false; // leave tb_spinlock_leave(&g_lock); // exit lock tb_spinlock_exit(&g_lock); }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ static tb_void_t tb_demo_context_exit(tb_aiop_ref_t aiop, tb_demo_context_t* context) { if (context) { // exit aioo if (context->aioo) tb_aiop_delo(aiop, context->aioo); context->aioo = tb_null; // exit sock if (context->sock) tb_socket_exit(context->sock); context->sock = tb_null; // exit file if (context->file) tb_file_exit(context->file); context->file = tb_null; // exit data if (context->data) tb_free(context->data); context->data = tb_null; // exit it tb_free(context); } }
tb_bool_t tb_trace_file_set_path(tb_char_t const* path, tb_bool_t bappend) { // check tb_check_return_val(path, tb_false); // enter tb_spinlock_enter_without_profiler(&g_lock); // exit the previous file if (g_file && !g_bref) tb_file_exit(g_file); // set the file g_file = tb_file_init(path, TB_FILE_MODE_RW | TB_FILE_MODE_BINARY | TB_FILE_MODE_CREAT | (bappend? TB_FILE_MODE_APPEND : TB_FILE_MODE_TRUNC)); g_bref = tb_false; // ok? tb_bool_t ok = g_file? tb_true : tb_false; // leave tb_spinlock_leave(&g_lock); // ok? return ok; }
/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t main(tb_int_t argc, tb_char_t** argv) { // init tbox #if 0 if (!tb_init(tb_null, (tb_byte_t*)malloc(300 * 1024 * 1024), 300 * 1024 * 1024)) return 0; #else if (!tb_init(tb_null, tb_null, 0)) return 0; #endif // init tb_int_t ok = 0; tb_char_t const* name = tb_null; // find the main func from the .demo file if (!name) { // init file tb_file_ref_t file = tb_file_init(".demo", TB_FILE_MODE_RO); if (file) { // read line tb_char_t line[8192] = {0}; if (tb_file_read(file, (tb_byte_t*)line, sizeof(line) - 1)) { tb_size_t i = 0; tb_size_t n = tb_arrayn(g_demo); for (i = 0; i < n; i++) { // find it? if (g_demo[i].name && !tb_strnicmp(g_demo[i].name, line, tb_strlen(g_demo[i].name))) { // save name name = g_demo[i].name; // done main ok = g_demo[i].main(argc, argv); break; } } } // exit file tb_file_exit(file); } } // find the main func from the first argument if (!name && argc > 1 && argv[1]) { tb_size_t i = 0; tb_size_t n = tb_arrayn(g_demo); for (i = 0; i < n; i++) { // find it? if (g_demo[i].name && !tb_stricmp(g_demo[i].name, argv[1])) { // save name name = g_demo[i].name; // done main ok = g_demo[i].main(argc - 1, argv + 1); break; } } } // no this demo? help it if (!name) { tb_trace_i("======================================================================"); tb_trace_i("help: echo \"name\" > ./.demo"); tb_trace_i("help: ./demo.b args ..."); tb_trace_i("help: or"); tb_trace_i("help: ./demo.b name args ..."); tb_trace_i("help: "); tb_trace_i("help: example: echo \"stream\" > ./.demo"); tb_trace_i("help: example: ./demo.b --help"); tb_trace_i("help: example: ./demo.b http://www.xxxxx.com /tmp/a"); tb_trace_i("help: example: or"); tb_trace_i("help: example: ./demo.b stream http://www.xxxxx.com /tmp/a"); tb_trace_i("help: "); // walk name tb_size_t i = 0; tb_size_t n = tb_arrayn(g_demo); for (i = 0; i < n; i++) tb_trace_i("help: name: %s", g_demo[i].name); } // exit tbox tb_exit(); // ok? return ok; }
static tb_long_t tb_aiop_spak_clos(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice) { // check tb_assert_and_check_return_val(impl && impl->aiop && impl->ltimer && impl->timer && aice, -1); tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_CLOS, -1); // the aico tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico; tb_assert_and_check_return_val(aico, -1); // trace tb_trace_d("clos: aico: %p, code: %u: %s", aico, aice->code, tb_state_cstr(tb_atomic_get(&aico->base.state))); // exit the timer task if (aico->task) { if (aico->bltimer) tb_ltimer_task_exit(impl->ltimer, aico->task); else tb_timer_task_exit(impl->timer, aico->task); aico->bltimer = 0; } aico->task = tb_null; // exit the sock if (aico->base.type == TB_AICO_TYPE_SOCK) { // remove aioo if (aico->aioo) tb_aiop_delo(impl->aiop, aico->aioo); aico->aioo = tb_null; // close the socket handle if (aico->base.handle) tb_socket_exit((tb_socket_ref_t)aico->base.handle); aico->base.handle = tb_null; } // exit file else if (aico->base.type == TB_AICO_TYPE_FILE) { // exit the file handle if (aico->base.handle) tb_file_exit((tb_file_ref_t)aico->base.handle); aico->base.handle = tb_null; } // clear waiting state aico->waiting = 0; aico->wait_ok = 0; aico->aice.code = TB_AICE_CODE_NONE; // clear type aico->base.type = TB_AICO_TYPE_NONE; // clear timeout tb_size_t i = 0; tb_size_t n = tb_arrayn(aico->base.timeout); for (i = 0; i < n; i++) aico->base.timeout[i] = -1; // closed tb_atomic_set(&aico->base.state, TB_STATE_CLOSED); // ok aice->state = TB_STATE_OK; return 1; }