static void
reactor_proc_sendmsg(struct net_reactor* reactor, struct net_session_s* session, struct nrmgr_send_msg_data* data)
{
    if(session->active)
    {
        struct pending_send_msg_s* pending = (struct pending_send_msg_s*)malloc(sizeof *pending);

        if(pending != NULL)
        {
            /*  直接放入链表  */
            pending->node.next = pending->node.prior = NULL;
            pending->msg = data;
            pending->left_len = data->data_len;
            double_link_push_back(&(session->packet_list), (struct double_link_node_s*)pending);

            /*	添加到待send列表	*/
            if (session->can_send)
            {
                add_session_to_waitsendlist(reactor, session);
            }
        }
        else
        {
            ox_rwlist_push(reactor->free_sendmsg_list, &data);
        }
    }
    else
    {
        ox_rwlist_push(reactor->free_sendmsg_list, &data);
    }
}
/*  移除已经发送的数据   */
static void
session_remove_sended_data(struct net_reactor* reactor, struct net_session_s* session, int sendbytes)
{
    struct double_link_node_s* current = double_link_begin(&session->packet_list);
    struct double_link_node_s* end = double_link_end(&session->packet_list);

    while (current != end && sendbytes > 0)
    {
        struct pending_send_msg_s* node = (struct pending_send_msg_s*)current;
        struct double_link_node_s* next = current->next;
        if (node->left_len <= sendbytes)
        {
            /*  当前packet已经发送完毕  */
            double_link_erase(&session->packet_list, current);
            sendbytes -= node->left_len;
            ox_rwlist_push(reactor->free_sendmsg_list, &(node->msg));
            free(node);
        }
        else
        {
            node->left_len -= sendbytes;
            break;
        }

        current = next;
    }
}
static int
reactor_logic_on_recved_callback(struct server_s* self, void* ud, const char* buffer, int len)
{
    struct net_reactor* reactor = (struct net_reactor*)server_getext(self);
    struct net_session_s* session = (struct net_session_s*)ud;

    int proc_len = 0;
    int left_len = len;
    const char* check_buffer = buffer;
    struct rwlist_s*    logic_msglist = reactor->logic_msglist;

    while(left_len > 0)
    {
        int check_len = (reactor->check_packet)(session->ud, check_buffer, left_len);
        if(check_len > 0)
        {
            struct nrmgr_net_msg* msg = make_logicmsg(reactor, nrmgr_net_msg_data, session, check_buffer, check_len);
            if(msg != NULL)
            {
                ox_rwlist_push(logic_msglist, &msg);
            }

            check_buffer += check_len;
            left_len -= check_len;
            proc_len += check_len;
        }
        else
        {
            break;
        }
    }

    return proc_len;
}
static void
reactor_logicmsg_handle(struct net_reactor* reactor, pfn_nrmgr_logicmsg callback, int64_t timeout)
{
    struct nrmgr_net_msg** msg_pp = NULL;
    struct nr_mgr* mgr = reactor->mgr;
    struct rwlist_s*    logic_msglist = reactor->logic_msglist;
    int64_t current_time = ox_getnowtime();
    const int64_t end_time = current_time+timeout;
    struct rwlist_msg_data msg;
    struct rwlist_s*    rwlist = reactor->fromlogic_rwlist;
    msg.msg_type = RMT_REQUEST_FREENETMSG;

    while(true)
    {
        msg_pp = (struct nrmgr_net_msg**)ox_rwlist_pop(logic_msglist, end_time-current_time);
        current_time = ox_getnowtime();
        if(msg_pp != NULL)
        {
            (callback)(mgr, *msg_pp);

            msg.data.free.msg = *msg_pp;
            ox_rwlist_push(rwlist, &msg);
        }
        else
        {
            if(current_time >= end_time)
            {
                break;
            }
        }
    }
}
void
ox_nrmgr_sendmsg(struct nr_mgr* mgr, struct nrmgr_send_msg_data* data, struct net_session_s* session)
{
    struct rwlist_msg_data msg;
    msg.msg_type = RMT_SENDMSG;
    msg.data.send.data = data;
    msg.data.send.session = session;

    data->ref += 1;
    ox_rwlist_push(session->reactor->fromlogic_rwlist, &msg);
}
void
ox_nrmgr_closesession(struct nr_mgr* mgr, struct net_session_s* session)
{
    struct net_reactor* reactor = session->reactor;
    struct rwlist_msg_data msg;
    msg.msg_type = RMT_CLOSE;
    msg.data.close.session = session;

    ox_rwlist_push(reactor->fromlogic_rwlist, &msg);
    ox_rwlist_force_flush(reactor->fromlogic_rwlist);
}
void
ox_connection_send_close(struct connection_s* self)
{
    struct msg_data_s* msg = (struct msg_data_s*)malloc(sizeof(struct msg_data_s));
    if(msg != NULL)
    {
        msg->type = send_msg_close;
        msg->len = 0;
        ox_rwlist_push(self->proc_list, &msg);
        ox_rwlist_force_flush(self->proc_list);
    }
}
void
ox_connection_send(struct connection_s* self, struct msg_data_s* msg)
{
    /*  逻辑层请求网络层发送数据(投递消息给网络层)  */
    msg->type = send_msg_data;

    #ifdef CONNECTION_SEND_CHECK
    self->current_msg_id++;
    msg->msg_id = self->current_msg_id;
    #endif

    ox_rwlist_push(self->sendmsg_list, &msg);
}
static void
reactor_logic_on_enter_callback(struct server_s* self, void* ud, void* handle)
{
    struct net_session_s* session = (struct net_session_s*)ud;
    struct net_reactor* reactor = (struct net_reactor*)server_getext(self);
    struct nrmgr_net_msg* msg = make_logicmsg(reactor, nrmgr_net_msg_connect, session, NULL, 0);
    session->handle = handle;

    if(msg != NULL)
    {
        session->active = true;
        reactor->active_num ++;
        ox_rwlist_push(reactor->logic_msglist, &msg);
    }
}
static void
reactor_logic_on_disconnection_callback(struct server_s* self, void* ud)
{
    struct net_session_s* session = (struct net_session_s*)ud;
    struct net_reactor* reactor = (struct net_reactor*)server_getext(self);
    if(session->active)
    {
        struct nrmgr_net_msg* msg = make_logicmsg(reactor, nrmgr_net_msg_close, session, NULL, 0);
        /*  设置网络已断开,并告诉上层 */
        session->active = false;

        if(msg != NULL)
        {
            ox_rwlist_push(reactor->logic_msglist, &msg);
        }
    }
}
Beispiel #11
0
void
ox_connection_send_connect(struct connection_s* self, const char* ip, int port, int timeout)
{
    struct msg_data_s* msg = (struct msg_data_s*)malloc(sizeof(struct msg_data_s)+sizeof(struct connect_msg));
    if(msg != NULL)
    {
        struct connect_msg* connect_data = (struct connect_msg*)msg->data;
        msg->type = send_msg_connect;
        msg->len = 0;

        memcpy(connect_data->ip, ip, strlen(ip)+1);
        connect_data->port = port;
        connect_data->timeout = timeout;

        ox_rwlist_push(self->proc_list, &msg);
        ox_rwlist_force_flush(self->proc_list);
    }
}
Beispiel #12
0
static void
connection_send_logicmsg(struct connection_s* self, enum net_msg_type type, const char* data, int data_len)
{
    struct msg_data_s* msg = (struct msg_data_s*)malloc(data_len+sizeof(struct msg_data_s));
    assert(msg != NULL);

    if(msg != NULL)
    {
        /*  网络层投递消息给逻辑层 */
        msg->type = type;
        msg->len = data_len;

        if(data != NULL)
        {
            memcpy(msg->data, data, data_len);
        }

        ox_rwlist_push(self->netmsg_list, &msg);
    }
}
Beispiel #13
0
void
ox_connection_logicpoll(struct connection_s* self, int64_t millisecond)
{
    /*  逻辑层调度函数:处理来自网络层投递的网络消息,以及释放逻辑层投递出的消息  */
    struct rwlist_s* logicmsg_list = self->netmsg_list;
    struct msg_data_s** msg_p = NULL;
    struct msg_data_s* msg = NULL;
    pfn_packet_handle handle = self->handle;
    void* ext = self->ext;
    struct rwlist_s*    free_netmsg_list = self->free_netmsg_list;
    int64_t current_time = ox_getnowtime();
    int64_t end_time = current_time;
    if(millisecond < 0)
    {
        millisecond = 0;
    }

    end_time += millisecond;

    do 
    {
        msg_p = (struct msg_data_s**)ox_rwlist_pop(logicmsg_list, end_time-current_time);
        if(msg_p != NULL)
        {
            msg = *msg_p;
            (handle)(self, msg, ext);
            ox_rwlist_push(free_netmsg_list, msg_p);

            current_time = ox_getnowtime();
        }
        else
        {
            break;
        }
    }while(end_time > current_time);

    ox_rwlist_flush(self->sendmsg_list);
    connection_free_sendmsglist(self);
}
static void
session_destroy(struct net_reactor* reactor, struct net_session_s* session)
{
    struct double_link_node_s* current = double_link_begin(&session->packet_list);
    struct double_link_node_s* end = double_link_end(&session->packet_list);

    while(current != end)
    {
        struct pending_send_msg_s* node = (struct pending_send_msg_s*)current;
        struct double_link_node_s* next = current->next;
        double_link_erase(&session->packet_list, current);
        ox_rwlist_push(reactor->free_sendmsg_list, &(node->msg));
        free(node);
        current = next;
    }

    double_link_init(&session->packet_list);

    session->active = false;
    session->wait_flush = false;
    free(session);
    reactor->active_num--;
}
void
ox_nrmgr_addfd(struct nr_mgr* mgr, void* ud, int fd)
{
    struct net_reactor* nr = mgr->reactors+0;
    int i = 1;
    for(; i < mgr->reactor_num; ++i)
    {
        struct net_reactor* temp = mgr->reactors+i;
        if(temp->active_num < nr->active_num)
        {
            nr = temp;
        }
    }

    {
        struct rwlist_entermsg_data msg;
        msg.ud = ud;
        msg.fd = fd;

        ox_rwlist_push(nr->enter_list, &msg);
        ox_rwlist_force_flush(nr->enter_list);
    }
}
Beispiel #16
0
static void
connection_sendmsg_handle(struct connection_s* self)
{
    if(self->status == connection_establish)
    {
        struct buffer_s* send_buffer = self->send_buffer;
        int send_len = 0;

proc_send:
        {
            struct rwlist_s* free_sendmsg_list = self->free_sendmsg_list;
            struct rwlist_s* sendmsg_list = self->sendmsg_list;
            struct msg_data_s** msg = NULL;

            while((msg = (struct msg_data_s**)ox_rwlist_front(sendmsg_list, 0)) != NULL)
            {
                struct msg_data_s* data = *msg;

                /*  只处理发送数据的消息  */
                if(data->type == send_msg_data)
                {
                    /*  先写入内置缓冲区    */
                    if(ox_buffer_write(send_buffer, data->data, data->len))
                    {
                        assert(data->msg_id == self->last_send_msg_id+1);
                        self->last_send_msg_id++;

                        ox_rwlist_pop(sendmsg_list, 0);
                        ox_rwlist_push(free_sendmsg_list, msg);
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    ox_rwlist_pop(sendmsg_list, 0);
                    ox_rwlist_push(free_sendmsg_list, msg);
                }
            }
        }

        send_len = ox_buffer_getreadvalidcount(send_buffer);
        if(send_len > 0)
        {
            /*  发送内置缓冲区 */
            int ret_len = send(self->fd, ox_buffer_getreadptr(send_buffer), send_len, 0);
            if(ret_len > 0)
            {
                ox_buffer_addreadpos(send_buffer, ret_len);

                if(send_len == ret_len)
                {
                    /*  如果发送全部成功,则继续处理发送消息队列中的消息    */
                    goto proc_send;
                }
            }
            else if(ret_len == SOCKET_ERROR)
            {
                if(S_EWOULDBLOCK == sErrno)
                {
                    self->writable = false;
                    ox_fdset_add(self->fdset, self->fd, WriteCheck);
                }
            }
        }
    }
}