Beispiel #1
0
tb_void_t tb_poller_clear(tb_poller_ref_t self)
{
    // check
    tb_poller_poll_ref_t poller = (tb_poller_poll_ref_t)self;
    tb_assert_and_check_return(poller);

    // clear hash
    if (poller->hash) tb_memset(poller->hash, 0, poller->hash_size * sizeof(tb_cpointer_t));

    // clear pfds
    if (poller->pfds) tb_vector_clear(poller->pfds);

    // clear cfds
    if (poller->cfds) tb_vector_clear(poller->cfds);

    // spak it
    if (poller->pair[0]) tb_socket_send(poller->pair[0], (tb_byte_t const*)"p", 1);
}
Beispiel #2
0
static tb_void_t tb_aiop_rtor_poll_cler(tb_aiop_rtor_impl_t* rtor)
{
    tb_aiop_rtor_poll_impl_t* impl = (tb_aiop_rtor_poll_impl_t*)rtor;
    if (impl)
    {
        // clear pfds
        tb_spinlock_enter(&impl->lock.pfds);
        if (impl->pfds) tb_vector_clear(impl->pfds);
        tb_spinlock_leave(&impl->lock.pfds);

        // clear hash
        tb_spinlock_enter(&impl->lock.hash);
        if (impl->hash) tb_hash_clear(impl->hash);
        tb_spinlock_leave(&impl->lock.hash);

        // spak it
        if (rtor->aiop && rtor->aiop->spak[0])
            tb_socket_send(rtor->aiop->spak[0], (tb_byte_t const*)"p", 1);
    }
}
Beispiel #3
0
static tb_bool_t tb_aiop_rtor_poll_addo(tb_aiop_rtor_impl_t* rtor, tb_aioo_impl_t const* aioo)
{
    // check
    tb_aiop_rtor_poll_impl_t* impl = (tb_aiop_rtor_poll_impl_t*)rtor;
    tb_assert_and_check_return_val(impl && impl->pfds && impl->cfds && aioo && aioo->sock, tb_false);

    // the aiop
    tb_aiop_impl_t* aiop = rtor->aiop;
    tb_assert_and_check_return_val(aiop, tb_false);

    // add sock => aioo
    tb_bool_t ok = tb_false;
    tb_spinlock_enter(&impl->lock.hash);
    if (impl->hash) 
    {
        tb_hash_set(impl->hash, aioo->sock, aioo);
        ok = tb_true;
    }
    tb_spinlock_leave(&impl->lock.hash);
    tb_assert_and_check_return_val(ok, tb_false);

    // the code
    tb_size_t code = aioo->code;

    // init pfd
    struct pollfd pfd = {0};
    pfd.fd = ((tb_long_t)aioo->sock) - 1;
    if (code & TB_AIOE_CODE_RECV || code & TB_AIOE_CODE_ACPT) pfd.events |= POLLIN;
    if (code & TB_AIOE_CODE_SEND || code & TB_AIOE_CODE_CONN) pfd.events |= POLLOUT;

    // add pfd, TODO: addo by binary search
    tb_spinlock_enter(&impl->lock.pfds);
    tb_vector_insert_tail(impl->pfds, &pfd);
    tb_spinlock_leave(&impl->lock.pfds);

    // spak it
    if (aiop->spak[0] && code) tb_socket_send(aiop->spak[0], (tb_byte_t const*)"p", 1);

    // ok?
    return ok;
}
Beispiel #4
0
Datei: aiop.c Projekt: cdrr/tbox
tb_void_t tb_aiop_spak(tb_aiop_ref_t aiop)
{
    // check
    tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
    tb_assert_and_check_return(impl);

    // spak it
    if (impl->spak[0]) 
    {
        // post: 'p'
        tb_long_t ok = tb_socket_send(impl->spak[0], (tb_byte_t const*)"p", 1);
        if (ok != 1)
        {
            // trace
            tb_trace_e("spak: failed!");

            // abort it
            tb_assert(0);
        }
    }
}
Beispiel #5
0
static tb_bool_t tb_aiop_rtor_select_post(tb_aiop_rtor_impl_t* rtor, tb_aioe_t const* aioe)
{
    // check
    tb_aiop_rtor_select_impl_t* impl = (tb_aiop_rtor_select_impl_t*)rtor;
    tb_assert_and_check_return_val(impl && aioe, tb_false);

    // the aiop
    tb_aiop_impl_t* aiop = rtor->aiop;
    tb_assert_and_check_return_val(aiop, tb_false);

    // the aioo
    tb_aioo_impl_t* aioo = (tb_aioo_impl_t*)aioe->aioo;
    tb_assert_and_check_return_val(aioo && aioo->sock, tb_false);

    // save aioo
    aioo->code = aioe->code;
    aioo->priv = aioe->priv;

    // fd
    tb_long_t fd = tb_sock2fd(aioo->sock);

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

    // set fds
    if (aioe->code & (TB_AIOE_CODE_RECV | TB_AIOE_CODE_ACPT)) FD_SET(fd, &impl->rfdi);
    else FD_CLR(fd, &impl->rfdi);
    if (aioe->code & (TB_AIOE_CODE_SEND | TB_AIOE_CODE_CONN)) FD_SET(fd, &impl->wfdi);
    else FD_CLR(fd, &impl->wfdi);

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

    // spak it
    if (aiop->spak[0]) tb_socket_send(aiop->spak[0], (tb_byte_t const*)"p", 1);

    // ok
    return tb_true;
}
Beispiel #6
0
static tb_void_t tb_aiop_rtor_select_cler(tb_aiop_rtor_impl_t* rtor)
{
    tb_aiop_rtor_select_impl_t* impl = (tb_aiop_rtor_select_impl_t*)rtor;
    if (impl)
    {
        // free fds
        tb_spinlock_enter(&impl->lock.pfds);
        impl->sfdm = 0;
        FD_ZERO(&impl->rfdi);
        FD_ZERO(&impl->wfdi);
        FD_ZERO(&impl->rfdo);
        FD_ZERO(&impl->wfdo);
        tb_spinlock_leave(&impl->lock.pfds);

        // clear hash
        tb_spinlock_enter(&impl->lock.hash);
        if (impl->hash) tb_hash_map_clear(impl->hash);
        tb_spinlock_leave(&impl->lock.hash);

        // spak it
        if (rtor->aiop && rtor->aiop->spak[0]) tb_socket_send(rtor->aiop->spak[0], (tb_byte_t const*)"p", 1);
    }
}
Beispiel #7
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;
}