/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t tb_demo_coroutine_http_server_main(tb_int_t argc, tb_char_t** argv) { // done tb_socket_ref_t sock = tb_null; do { // init socket sock = tb_socket_init(TB_SOCKET_TYPE_TCP, TB_IPADDR_FAMILY_IPV4); tb_assert_and_check_break(sock); // bind socket tb_ipaddr_t addr; tb_ipaddr_set(&addr, tb_null, TB_DEMO_PORT, TB_IPADDR_FAMILY_IPV4); if (!tb_socket_bind(sock, &addr)) break; // listen socket if (!tb_socket_listen(sock, 1000)) break; // init the root directory if (argv[1]) tb_strlcpy(g_rootdir, argv[1], sizeof(g_rootdir)); else tb_directory_current(g_rootdir, sizeof(g_rootdir)); // only data? if (!tb_file_info(g_rootdir, tb_null)) g_onlydata = tb_true; // trace tb_trace_i("%s: %s", g_onlydata? "data" : "rootdir", g_rootdir); #if TB_DEMO_CPU > 1 // start workers for multi-threads tb_size_t count = TB_DEMO_CPU - 1; while (count--) tb_thread_init(tb_null, tb_demo_coroutine_worker, sock, 0); #endif // start worker tb_demo_coroutine_worker(sock); } while (0); // exit socket if (sock) tb_socket_exit(sock); sock = tb_null; // ok return 0; }
/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t tb_demo_asio_aiopd_main(tb_int_t argc, tb_char_t** argv) { // check tb_assert_and_check_return_val(argv[1], 0); // done tb_socket_ref_t sock = tb_null; tb_aiop_ref_t aiop = tb_null; do { // init sock sock = tb_socket_init(TB_SOCKET_TYPE_TCP); tb_assert_and_check_break(sock); // init aiop aiop = tb_aiop_init(16); tb_assert_and_check_break(aiop); // bind if (!tb_socket_bind(sock, tb_null, 9090)) break; // listen sock if (!tb_socket_listen(sock, 20)) break; // addo sock if (!tb_aiop_addo(aiop, sock, TB_AIOE_CODE_ACPT, tb_null)) break; // accept tb_aioe_t list[16]; while (1) { // wait tb_long_t objn = tb_aiop_wait(aiop, list, 16, -1); tb_assert_and_check_break(objn >= 0); // walk list tb_size_t i = 0; for (i = 0; i < objn; i++) { // the aioo tb_aioo_ref_t aioo = list[i].aioo; // check tb_assert_and_check_break(aioo && tb_aioo_sock(aioo)); // acpt? if (list[i].code & TB_AIOE_CODE_ACPT) { // done acpt tb_bool_t ok = tb_false; tb_demo_context_t* context = tb_null; do { // make context context = tb_malloc0_type(tb_demo_context_t); tb_assert_and_check_break(context); // init sock context->sock = tb_socket_accept(tb_aioo_sock(aioo), tb_null, tb_null); tb_assert_and_check_break(context->sock); // init file context->file = tb_file_init(argv[1], TB_FILE_MODE_RO); tb_assert_and_check_break(context->file); // init data context->data = tb_malloc_bytes(TB_DEMO_FILE_READ_MAXN); tb_assert_and_check_break(context->data); // addo sock context->aioo = tb_aiop_addo(aiop, context->sock, TB_AIOE_CODE_SEND, context); tb_assert_and_check_break(context->aioo); // trace tb_trace_i("acpt[%p]: ok", context->sock); // init left context->left = tb_file_size(context->file); // done read tb_long_t real = tb_file_read(context->file, context->data, tb_min((tb_size_t)context->left, TB_DEMO_FILE_READ_MAXN)); tb_assert_and_check_break(real > 0); // save size context->left -= real; // trace // tb_trace_i("read[%p]: real: %ld", context->file, real); // done send context->send = real; real = tb_socket_send(context->sock, context->data + context->real, context->send - context->real); if (real >= 0) { // save real context->real += real; // trace // tb_trace_i("send[%p]: real: %ld", context->sock, real); } else { // trace tb_trace_i("send[%p]: closed", context->sock); break; } // ok ok = tb_true; } while (0); // failed or closed? if (!ok) { // exit context tb_demo_context_exit(aiop, context); break; } } // writ? else if (list[i].code & TB_AIOE_CODE_SEND) { // the context tb_demo_context_t* context = (tb_demo_context_t*)list[i].priv; tb_assert_and_check_break(context); // continue to send it if not finished if (context->real < context->send) { // done send tb_long_t real = tb_socket_send(tb_aioo_sock(aioo), context->data + context->real, context->send - context->real); if (real > 0) { // save real context->real += real; // trace // tb_trace_i("send[%p]: real: %ld", tb_aioo_sock(aioo), real); } else { // trace tb_trace_i("send[%p]: closed", tb_aioo_sock(aioo)); // exit context tb_demo_context_exit(aiop, context); break; } } // finished? read file else if (context->left) { // init context->real = 0; context->send = 0; // done read tb_size_t tryn = 1; tb_long_t real = 0; while (!(real = tb_file_read(context->file, context->data, tb_min((tb_size_t)context->left, TB_DEMO_FILE_READ_MAXN))) && tryn--); if (real > 0) { // save left context->left -= real; // trace // tb_trace_i("read[%p]: real: %ld", context->file, real); // done send context->send = real; real = tb_socket_send(tb_aioo_sock(aioo), context->data, context->send); if (real >= 0) { // save real context->real += real; // trace // tb_trace_i("send[%p]: real: %ld", tb_aioo_sock(aioo), real); } else { // trace tb_trace_i("send[%p]: closed", tb_aioo_sock(aioo)); // exit context tb_demo_context_exit(aiop, context); break; } } else { // trace tb_trace_i("read[%p]: closed", tb_aioo_sock(aioo)); // exit context tb_demo_context_exit(aiop, context); break; } } else { // trace tb_trace_i("read[%p]: closed", tb_aioo_sock(aioo)); // exit context tb_demo_context_exit(aiop, context); break; } } // error? else { tb_trace_i("aioe[%p]: unknown code: %lu", tb_aioo_sock(aioo), list[i].code); break; } } } } while (0); // trace tb_trace_i("end"); // exit socket if (sock) tb_socket_exit(sock); // exit aiop if (aiop) tb_aiop_exit(aiop); // end return 0; }
/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t tb_demo_asio_aicpd_main(tb_int_t argc, tb_char_t** argv) { // check tb_assert_and_check_return_val(argv[1], 0); // init tb_aicp_ref_t aicp = tb_null; tb_aico_ref_t aico = tb_null; // tb_aico_ref_t task = tb_null; tb_thread_ref_t loop[16] = {tb_null}; do { // init aicp aicp = tb_aicp_init(16); tb_assert_and_check_break(aicp); // init sock aico aico = tb_aico_init(aicp); tb_assert_and_check_break(aico); // init addr tb_ipaddr_t addr; tb_ipaddr_set(&addr, tb_null, 9090, TB_IPADDR_FAMILY_IPV4); // open sock aico if (!tb_aico_open_sock_from_type(aico, TB_SOCKET_TYPE_TCP, tb_ipaddr_family(&addr))) break; // bind port if (!tb_socket_bind(tb_aico_sock(aico), &addr)) break; // listen sock if (!tb_socket_listen(tb_aico_sock(aico), 20)) break; #if 0 // init task aico task = tb_aico_init(aicp); tb_assert_and_check_break(task); // open task aico if (!tb_aico_open_task(task, tb_false)) break; // run task if (!tb_aico_task_run(task, 0, tb_demo_task_func, tb_null)) break; if (!tb_aico_task_run(aico, 0, tb_demo_task_func, tb_null)) break; #endif // post acpt if (!tb_aico_acpt(aico, tb_demo_sock_acpt_func, argv[1])) break; // done loop loop[0] = tb_thread_init(tb_null, tb_demo_loop, aicp, 0); loop[1] = tb_thread_init(tb_null, tb_demo_loop, aicp, 0); loop[2] = tb_thread_init(tb_null, tb_demo_loop, aicp, 0); loop[3] = tb_thread_init(tb_null, tb_demo_loop, aicp, 0); // wait exit getchar(); } while (0); // trace tb_trace_i("end"); #if 1 if (aicp) { // kill all tb_aicp_kill_all(aicp); // wait all tb_aicp_wait_all(aicp, -1); // kill aicp tb_aicp_kill(aicp); } // wait exit { // exit loop tb_thread_ref_t* l = loop; for (; *l; l++) { tb_thread_wait(*l, -1, tb_null); tb_thread_exit(*l); } } #endif // exit aicp if (aicp) tb_aicp_exit(aicp); return 0; }