Example #1
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
static tb_long_t tb_aioo_rtor_select_wait(tb_socket_ref_t sock, tb_size_t code, tb_long_t timeout)
{
    // check
    tb_assert_and_check_return_val(sock, -1);

    // fd
    tb_long_t fd = tb_sock2fd(sock);
    tb_assert_and_check_return_val(fd >= 0, -1);
    
    // init time
    struct timeval t = {0};
    if (timeout > 0)
    {
#ifdef TB_CONFIG_OS_WINDOWS
        t.tv_sec = (LONG)(timeout / 1000);
#else
        t.tv_sec = (timeout / 1000);
#endif
        t.tv_usec = (timeout % 1000) * 1000;
    }

    // init fds
    fd_set  rfds;
    fd_set  wfds;
    fd_set* prfds = (code & TB_AIOE_CODE_RECV || code & TB_AIOE_CODE_ACPT)? &rfds : tb_null;
    fd_set* pwfds = (code & TB_AIOE_CODE_SEND || code & TB_AIOE_CODE_CONN)? &wfds : tb_null;

    if (prfds)
    {
        FD_ZERO(prfds);
        FD_SET(fd, prfds);
    }

    if (pwfds)
    {
        FD_ZERO(pwfds);
        FD_SET(fd, pwfds);
    }
   
    // select
#ifdef TB_CONFIG_OS_WINDOWS
    tb_long_t r = tb_ws2_32()->select((tb_int_t)fd + 1, prfds, pwfds, tb_null, timeout >= 0? &t : tb_null);
#else
    tb_long_t r = select(fd + 1, prfds, pwfds, tb_null, timeout >= 0? &t : tb_null);
#endif
    tb_assert_and_check_return_val(r >= 0, -1);

    // timeout?
    tb_check_return_val(r, 0);

    // error?
    tb_int_t o = 0;
#ifdef TB_CONFIG_OS_WINDOWS
    tb_int_t n = sizeof(tb_int_t);
    tb_ws2_32()->getsockopt(fd, SOL_SOCKET, SO_ERROR, (tb_char_t*)&o, &n);
#else
    socklen_t n = sizeof(socklen_t);
    getsockopt(fd, SOL_SOCKET, SO_ERROR, (tb_char_t*)&o, &n);
#endif
    if (o) return -1;

    // ok
    tb_long_t e = 0;
    if (prfds && FD_ISSET(fd, &rfds)) 
    {
        e |= TB_AIOE_CODE_RECV;
        if (code & TB_AIOE_CODE_ACPT) e |= TB_AIOE_CODE_ACPT;
    }
    if (pwfds && FD_ISSET(fd, &wfds)) 
    {
        e |= TB_AIOE_CODE_SEND;
        if (code & TB_AIOE_CODE_CONN) e |= TB_AIOE_CODE_CONN;
    }
    return e;
}
Example #2
0
static tb_long_t tb_aiop_rtor_select_wait(tb_aiop_rtor_impl_t* rtor, tb_aioe_ref_t list, tb_size_t maxn, tb_long_t timeout)
{   
    // check
    tb_aiop_rtor_select_impl_t* impl = (tb_aiop_rtor_select_impl_t*)rtor;
    tb_assert_and_check_return_val(impl && rtor->aiop && list && maxn, -1);

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

    // init time
    struct timeval t = {0};
    if (timeout > 0)
    {
#ifdef TB_CONFIG_OS_WINDOWS
        t.tv_sec = (LONG)(timeout / 1000);
#else
        t.tv_sec = (timeout / 1000);
#endif
        t.tv_usec = (timeout % 1000) * 1000;
    }

    // loop
    tb_long_t wait = 0;
    tb_bool_t stop = tb_false;
    tb_hong_t time = tb_mclock();
    while (!wait && !stop && (timeout < 0 || tb_mclock() < time + timeout))
    {
        // enter
        tb_spinlock_enter(&impl->lock.pfds);

        // init fdo
        tb_size_t sfdm = impl->sfdm;
        tb_memcpy(&impl->rfdo, &impl->rfdi, sizeof(fd_set));
        tb_memcpy(&impl->wfdo, &impl->wfdi, sizeof(fd_set));

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

        // wait
#ifdef TB_CONFIG_OS_WINDOWS
        tb_long_t sfdn = tb_ws2_32()->select((tb_int_t)sfdm + 1, &impl->rfdo, &impl->wfdo, tb_null, timeout >= 0? &t : tb_null);
#else
        tb_long_t sfdn = select(sfdm + 1, &impl->rfdo, &impl->wfdo, tb_null, timeout >= 0? &t : tb_null);
#endif
        tb_assert_and_check_return_val(sfdn >= 0, -1);

        // timeout?
        tb_check_return_val(sfdn, 0);
        
        // enter
        tb_spinlock_enter(&impl->lock.hash);

        // sync
        tb_size_t itor = tb_iterator_head(impl->hash);
        tb_size_t tail = tb_iterator_tail(impl->hash);
        for (; itor != tail && wait >= 0 && (tb_size_t)wait < maxn; itor = tb_iterator_next(impl->hash, itor))
        {
            tb_hash_map_item_ref_t item = (tb_hash_map_item_ref_t)tb_iterator_item(impl->hash, itor);
            if (item)
            {
                // the sock
                tb_socket_ref_t sock = (tb_socket_ref_t)item->name;
                tb_assert_and_check_return_val(sock, -1);

                // spak?
                if (sock == aiop->spak[1] && FD_ISSET(((tb_long_t)aiop->spak[1] - 1), &impl->rfdo))
                {
                    // read spak
                    tb_char_t spak = '\0';
                    if (1 != tb_socket_recv(aiop->spak[1], (tb_byte_t*)&spak, 1)) wait = -1;

                    // killed?
                    if (spak == 'k') wait = -1;
                    tb_check_break(wait >= 0);

                    // stop to wait
                    stop = tb_true;

                    // continue it
                    continue ;
                }

                // filter spak
                tb_check_continue(sock != aiop->spak[1]);

                // the fd
                tb_long_t fd = (tb_long_t)item->name - 1;

                // the aioo
                tb_aioo_impl_t* aioo = (tb_aioo_impl_t*)item->data;
                tb_assert_and_check_return_val(aioo && aioo->sock == sock, -1);

                // init aioe
                tb_aioe_t aioe = {0};
                aioe.priv   = aioo->priv;
                aioe.aioo   = (tb_aioo_ref_t)aioo;
                if (FD_ISSET(fd, &impl->rfdo)) 
                {
                    aioe.code |= TB_AIOE_CODE_RECV;
                    if (aioo->code & TB_AIOE_CODE_ACPT) aioe.code |= TB_AIOE_CODE_ACPT;
                }
                if (FD_ISSET(fd, &impl->wfdo)) 
                {
                    aioe.code |= TB_AIOE_CODE_SEND;
                    if (aioo->code & TB_AIOE_CODE_CONN) aioe.code |= TB_AIOE_CODE_CONN;
                }
                    
                // ok?
                if (aioe.code) 
                {
                    // save aioe
                    list[wait++] = aioe;

                    // oneshot? clear it
                    if (aioo->code & TB_AIOE_CODE_ONESHOT)
                    {
                        // clear aioo
                        aioo->code = TB_AIOE_CODE_NONE;
                        aioo->priv = tb_null;

                        // clear events
                        tb_spinlock_enter(&impl->lock.pfds);
                        FD_CLR(fd, &impl->rfdi);
                        FD_CLR(fd, &impl->wfdi);
                        tb_spinlock_leave(&impl->lock.pfds);
                    }
                }
            }
        }

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

    // ok
    return wait;
}
Example #3
0
tb_bool_t tb_hostname(tb_char_t* name, tb_size_t size)
{
    return !tb_ws2_32()->gethostname(name, (DWORD)size)? tb_true : tb_false;
}
Example #4
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
static tb_bool_t tb_mswsock_instance_init(tb_handle_t instance)
{
    // check
    tb_mswsock_ref_t mswsock = (tb_mswsock_ref_t)instance;
    tb_assert_and_check_return_val(mswsock, tb_false);

    // done
    tb_socket_ref_t sock = tb_null;
    do
    {
        // init sock
        sock = tb_socket_init(TB_SOCKET_TYPE_TCP);
        tb_assert_and_check_break(sock);

        // init AcceptEx
        DWORD   AcceptEx_real = 0;
        GUID    AcceptEx_guid = TB_MSWSOCK_WSAID_ACCEPTEX;
        tb_ws2_32()->WSAIoctl(  (SOCKET)sock - 1
                                ,   SIO_GET_EXTENSION_FUNCTION_POINTER
                                ,   &AcceptEx_guid
                                ,   sizeof(GUID)
                                ,   &mswsock->AcceptEx
                                ,   sizeof(tb_mswsock_AcceptEx_t)
                                ,   &AcceptEx_real
                                ,   tb_null
                                ,   tb_null);

        // init ConnectEx
        DWORD   ConnectEx_real = 0;
        GUID    ConnectEx_guid = TB_MSWSOCK_WSAID_CONNECTEX;
        tb_ws2_32()->WSAIoctl(  (SOCKET)sock - 1
                                ,   SIO_GET_EXTENSION_FUNCTION_POINTER
                                ,   &ConnectEx_guid
                                ,   sizeof(GUID)
                                ,   &mswsock->ConnectEx
                                ,   sizeof(tb_mswsock_ConnectEx_t)
                                ,   &ConnectEx_real
                                ,   tb_null
                                ,   tb_null);

        // init DisconnectEx
        DWORD   DisconnectEx_real = 0;
        GUID    DisconnectEx_guid = TB_MSWSOCK_WSAID_DISCONNECTEX;
        tb_ws2_32()->WSAIoctl(  (SOCKET)sock - 1
                                ,   SIO_GET_EXTENSION_FUNCTION_POINTER
                                ,   &DisconnectEx_guid
                                ,   sizeof(GUID)
                                ,   &mswsock->DisconnectEx
                                ,   sizeof(tb_mswsock_DisconnectEx_t)
                                ,   &DisconnectEx_real
                                ,   tb_null
                                ,   tb_null);

        // init TransmitFile
        DWORD   TransmitFile_real = 0;
        GUID    TransmitFile_guid = TB_MSWSOCK_WSAID_TRANSMITFILE;
        tb_ws2_32()->WSAIoctl(  (SOCKET)sock - 1
                                ,   SIO_GET_EXTENSION_FUNCTION_POINTER
                                ,   &TransmitFile_guid
                                ,   sizeof(GUID)
                                ,   &mswsock->TransmitFile
                                ,   sizeof(tb_mswsock_TransmitFile_t)
                                ,   &TransmitFile_real
                                ,   tb_null
                                ,   tb_null);

        // init GetAcceptExSockaddrs
        DWORD   GetAcceptExSockaddrs_real = 0;
        GUID    GetAcceptExSockaddrs_guid = TB_MSWSOCK_WSAID_GETACCEPTEXSOCKADDRS;
        tb_ws2_32()->WSAIoctl(  (SOCKET)sock - 1
                                ,   SIO_GET_EXTENSION_FUNCTION_POINTER
                                ,   &GetAcceptExSockaddrs_guid
                                ,   sizeof(GUID)
                                ,   &mswsock->GetAcceptExSockaddrs
                                ,   sizeof(tb_mswsock_GetAcceptExSockaddrs_t)
                                ,   &GetAcceptExSockaddrs_real
                                ,   tb_null
                                ,   tb_null);
    } while (0);

    // exit sock
    if (sock) tb_socket_exit(sock);

    // ok
    return tb_true;
}