Example #1
0
static 
void do_udp_peer_onwrite(void *userdata)
{
    struct udp_peer_notify *notify;
    udp_peer_t* peer;
    
    notify = (struct udp_peer_notify *)userdata;
    peer = notify->peer;
    
    peer->writecb = notify->writecb;
    peer->write_userdata = notify->write_userdata;
    free(notify);
    
    if (atomic_dec(&peer->ref_count) > 1)
    {
        if (NULL == peer->writecb)
        {
            channel_clearevent(peer->channel, POLLOUT);
            peer->message_userdata = NULL;
        }
        else
        {
            channel_setevent(peer->channel, POLLOUT);
        }    
    }
    else
    {
        delete_udp_peer(peer);
    }

    return;
}
Example #2
0
static
void do_tcp_connection_destroy(void *userdata)
{
    tcp_connection_t* connection = (tcp_connection_t*)userdata;

    if (buffer_readablebytes(connection->out_buffer) > 0)
    {
        channel_clearevent(connection->channel, EPOLLIN);
        channel_setevent(connection->channel, EPOLLOUT);

        connection->need_closed_after_sent_done = 1;
    }
    else
    {
        if (connection->is_in_callback)
        {
            connection->is_alive = 0;
        }
        else
        {
            delete_connection(connection);
        }
    }

    return;
}
Example #3
0
tcp_connection_t* tcp_connection_new
(
    loop_t *loop, int fd, on_data_f datacb, on_close_f closecb, void* userdata, const inetaddr_t *peer_addr
)
{
    tcp_connection_t *connection;
    struct sockaddr_in addr;
    socklen_t addr_len;
    
    struct linger linger_info;
    int flag;

    if (NULL == loop || fd < 0 || NULL == datacb || NULL == closecb || NULL == peer_addr)
    {
        log_error("tcp_connection_new: bad loop(%p) or bad fd(%d) or bad datacb(%p) or bad closecb(%p) or bad peer_addr(%p)", 
            loop, fd, datacb, closecb, peer_addr);
        return NULL;
    }

    connection = (tcp_connection_t*)malloc(sizeof(*connection));
	memset(connection, 0, sizeof(*connection));

    flag = 1;
    setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &flag, sizeof(flag));
    
    memset(&linger_info, 0, sizeof(linger_info));
    linger_info.l_onoff = 1;
    linger_info.l_linger = 3;
    setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger_info, sizeof(linger_info));

    connection->loop = loop;
    connection->fd = fd;
    connection->datacb = datacb;
    connection->closecb = closecb;
    connection->userdata = userdata;

    connection->channel = channel_new(fd, loop, connection_onevent, connection);

    connection->in_buffer = buffer_new(4096);
    connection->out_buffer = buffer_new(4096);

    connection->is_in_callback = 0;
    connection->is_alive = 1;
    connection->is_connected = 1;
    connection->need_closed_after_sent_done = 0;
    connection->peer_addr = *peer_addr;

    memset(&addr, 0, sizeof(addr));
    addr_len = sizeof(addr);
    getsockname(fd, (struct sockaddr*)&addr, &addr_len);
    inetaddr_init(&connection->local_addr, &addr);

    channel_setevent(connection->channel, EPOLLIN);

    return connection;
}
Example #4
0
static
void init_udp_peer_event(void *userdata)
{
    udp_peer_t* peer = (udp_peer_t*)userdata;
    short event;
    
    event = POLLIN;
    if (NULL != peer->writecb)
    {
        event |= POLLOUT;
    }
    channel_setevent(peer->channel, event);

    return;
}
Example #5
0
async_task_queue_t* async_task_queue_create(loop_t* loop)
{
    async_task_queue_t* task_queue = (async_task_queue_t*)malloc(sizeof(async_task_queue_t));
    memset(task_queue, 0, sizeof(*task_queue));

    task_queue->loop = loop;

    socketpair(task_queue->fds);
    
    task_queue->channel = channel_new(task_queue->fds[0], loop, async_task_event, task_queue);
    channel_setevent(task_queue->channel, POLLIN);

    task_queue->async_task = NULL;
    task_queue->async_task_end = NULL;
    lock_init(&task_queue->task_lock);

    return task_queue;
}
Example #6
0
static
void do_tcp_server_start(void* userdata)
{
    tcp_server_t *server = (tcp_server_t*)userdata;

    do
    {
        server->fd = create_server_socket(server->addr.port, server->addr.ip);
        if (server->fd < 0)
        {
            log_error("do_tcp_server_start: create_server_socket() failed, local addr: %s:%u", server->addr.ip, server->addr.port);
            break;
        }

        server->channel = channel_new(server->fd, server->loop, server_onevent, server);

        if (listen(server->fd, 512) != 0)
        {
            log_error("do_tcp_server_start: listen() failed, errno: %d, local addr: %s:%u", errno, server->addr.ip, server->addr.port);
            break;
        }
        if (channel_setevent(server->channel, EPOLLIN))
        {
            log_error("do_tcp_server_start: channel_setevent() failed, local addr: %s:%u", server->addr.ip, server->addr.port);
            break;
        }

        return;
    } while(0);

    if (server->fd >= 0)
    {
        close(server->fd);
        server->fd = -1;
    }
    channel_destroy(server->channel);
    server->channel = NULL;
    server->is_started = 0;

    return;
}
Example #7
0
static 
int tcp_connection_sendInLoop(tcp_connection_t* connection, const void* data, unsigned size)
{
	inetaddr_t *peer_addr = &connection->peer_addr;
	
    int fd;
    void* buffer_data;
    channel_t *channel;
    buffer_t* out_buffer;
    int written;
    unsigned buffer_left_data_size;
    struct iovec vecs[2];

    int error;

    out_buffer = connection->out_buffer;
    channel = connection->channel;
    fd = connection->fd;

    buffer_left_data_size = buffer_readablebytes(out_buffer);

    if (buffer_left_data_size > 0)
    {
        buffer_data = buffer_peek(out_buffer);
        vecs[0].iov_base = buffer_data;
        vecs[0].iov_len = buffer_left_data_size;
        vecs[1].iov_base = (void*)data;
        vecs[1].iov_len = size;
        
        written = writev(fd, vecs, 2);
        if (written < 0)
        {
            error = errno;
            
            if (error != EAGAIN)
            {
                log_error("tcp_connection_sendInLoop: writev() failed, errno: %d, peer addr: %s:%u", errno, peer_addr->ip, peer_addr->port);
                return -1;
            }
        }
        else if (written == (buffer_left_data_size+size))
        {
            /* 当前所有的数据都发送完毕,一切安好则去除EPOLLOUT事件 */
            channel_clearevent(channel, EPOLLOUT);
        }
        else if (written < buffer_left_data_size)
        {
            /* out_buffer中的数据尚未发送完毕,则将本次的数据放入out_buffer后再发送 */
            buffer_retrieve(out_buffer, written);
            buffer_append(out_buffer, data, size);
            channel_setevent(channel, EPOLLOUT);
        }
        else if (written < (buffer_left_data_size+size))
        {
            buffer_retrieveall(out_buffer);
            buffer_append(out_buffer, ((const char*)data+written-buffer_left_data_size), ((buffer_left_data_size+size)-written));
            channel_setevent(channel, EPOLLOUT);
        }
    }
    else
    {
        written = write(fd, data, size);
        if (written < 0)
        {
            log_error("tcp_connection_sendInLoop: write() failed, errno: %d, peer addr: %s:%u", errno, peer_addr->ip, peer_addr->port);
            return -1;
        }
        else if (written < size)
        {
            buffer_append(out_buffer, ((const char*)data+written), (size-written));
            channel_setevent(channel, EPOLLOUT);
        }
    }

    return 0;
}