示例#1
0
int get_chunk_body_buffer(struct worker_context *ctx, struct connection *conn, char **p_start, int *p_len)
{
	int flag = 0;
	struct body_buffer *buffer;
	if ( DLIST_EMPTY(&conn->_client._body) )
	{
		flag = 1;
	}
	else
	{
		__dlist_t *cur = DLIST_PRE(&conn->_client._body);
		buffer = GET_OWNER(cur, struct body_buffer, _list);
		if ( buffer->_data_len - buffer->_curpos == 0 )
		{
			flag = 1;
		}
	}
	if ( flag )
	{
		buffer = (struct body_buffer *)mp_alloc(ctx->_body_pool);
		if ( NULL == buffer )
		{
			WARNING("failed to alloc mem for body buffer.");
			return -1;
		}
		DLIST_INIT(&buffer->_list);
		buffer->_curpos = 0;
		buffer->_data_len = ctx->_data_len;
		DLIST_INSERT_B(&buffer->_list, &conn->_client._body);
	}
	*p_start = buffer->_data + buffer->_curpos;
	*p_len = buffer->_data_len - buffer->_curpos;
	return 0;
}
示例#2
0
void Worker::run()
{
    int ret;
    __dlist_t head;
    __dlist_t *next;
    Connection *conn;
    NOTICE("worker is running now.");
    while (!_stopped)
    {
        DLIST_INIT(&head);
        pthread_mutex_lock(&_mutex);
        while (DLIST_EMPTY(&_queue))
            pthread_cond_wait(&_cond, &_mutex);
        next = DLIST_NEXT(&_queue);
        DLIST_REMOVE(&_queue);
        pthread_mutex_unlock(&_mutex);
        DLIST_INSERT_B(&head, next);
        while (!DLIST_EMPTY(&head))
        {
            next = DLIST_NEXT(&head);
            DLIST_REMOVE(next);
            conn = GET_OWNER(next, Connection, _list);
            TRACE("start to process conn, sock[%d].", conn->_sock_fd);
            try
            {
                ret = conn->on_process();
                if (ret == 0)
                {
                    conn->_status = Connection::ST_PROCESSING_REQUEST_OK;
                    TRACE("process conn ok, sock[%d].", conn->_sock_fd);
                }
                else
                {
                    conn->_status = Connection::ST_PROCESSING_REQUEST_FAIL;
                    WARNING("failed to process conn, sock[%d], ret=%d.", conn->_sock_fd, ret);
                }
            }
            catch (...)
            {
                WARNING("failed to process conn, sock[%d], exception catched.", conn->_sock_fd);
            }
            _server_manager->done(conn);
        }
    }
    NOTICE("worker is stopped by user, exiting now.");
}
示例#3
0
inline static void* __d_fp_malloc_from_list(struct fixed_dmem_pool* pool)
{
    if(!DLIST_EMPTY(&pool->head)){
        struct dlist_node* node = pool->head.next;
        dlist_del(node);
        return container_of(node, struct dmem_node, node);
    }
    return NULL;
}
示例#4
0
void Worker::post(Connection *conn)
{
    if (!conn) return ;
    DLIST_REMOVE(&conn->_list);
    int empty = 0;
    pthread_mutex_lock(&_mutex);
    if (DLIST_EMPTY(&_queue)) empty = 1;
    DLIST_INSERT_B(&conn->_list, &_queue);
    if (empty) pthread_cond_signal(&_cond);
    pthread_mutex_unlock(&_mutex);
}
示例#5
0
void NetProxy::detach(NetStub *st)
{
    if (st->_cancel)
        return ;
    st->_cancel = 1;
    {
        AutoLock __lock(_mutex);
        if (!DLIST_EMPTY(&st->_att_list))
        {
            DLIST_REMOVE(&st->_att_list);/* still in _attach_list */
        }
        else return ;
    }
    this->done(st);
}
示例#6
0
void NetProxy::run()
{
#define SET_ERROR(errno)                                   \
    do                                                     \
    {                                                      \
        st->_errno = errno;                                \
        epex_detach(_epex, st->_talk->_sock, NULL);        \
    } while(0)

    ssize_t ret;
    netresult_t results[20];
    __dlist_t attach_ok_list;
    __dlist_t attach_fail_list;
    __dlist_t *ptr;
    NetStub *st;
    int sock;
    int tm_left;
    int elasp_tm;
    struct timeval now;

    _stop = false;
    while (!_stop)
    {
        DLIST_INIT(&attach_ok_list);
        DLIST_INIT(&attach_fail_list);
        {
            AutoLock __lock(_mutex);
            while (!DLIST_EMPTY(&_attach_list))
            {
                ptr = DLIST_NEXT(&_attach_list);
                st = GET_OWNER(ptr, NetStub, _att_list);
                DLIST_REMOVE(ptr);
                if (epex_attach(_epex, st->_talk->_sock, st, -1))
                    DLIST_INSERT_B(&st->_tmp_list, &attach_ok_list);
                else
                    DLIST_INSERT_B(&st->_tmp_list, &attach_fail_list);
            }
        }
        gettimeofday(&now, NULL);
        while (!DLIST_EMPTY(&attach_fail_list))
        {
            ptr = DLIST_NEXT(&attach_fail_list);
            st = GET_OWNER(ptr, NetStub, _tmp_list);
            DLIST_REMOVE(ptr);
            st->_errno = NET_ERR_ATTACH_FAIL;
            this->done(st, &now);
        }
        while (!DLIST_EMPTY(&attach_ok_list))
        {
            ptr = DLIST_NEXT(&attach_ok_list);
            st = GET_OWNER(ptr, NetStub, _tmp_list);
            DLIST_REMOVE(ptr);
            st->_talk->_req_head._magic_num = MAGIC_NUM;
            st->_talk->_req_head._body_len = st->_talk->_req_len;
            st->_status = NET_ST_SEND_HEAD;
            if (epex_write(_epex, st->_talk->_sock, &st->_talk->_req_head,
                        sizeof(st->_talk->_req_head), NULL, st->_timeout))
            {
                TRACE("try to send head to sock[%d]", st->_talk->_sock);
            }
            else
            {
                SET_ERROR(NET_ERR_WRITE);
            }
        }
        ret = epex_poll(_epex, results, sizeof(results)/sizeof(results[0]));
        gettimeofday(&now, NULL);
        for (long i = 0; i < ret; ++i)
        {
            const netresult_t &res = results[i];
            st = (NetStub *)res._user_ptr2;
            if (NET_OP_NOTIFY == res._op_type)
            {
                this->done(st, &now);
                continue;
            }
            switch (res._status)
            {
                case NET_DONE:
                    break;
                case NET_ECLOSED:
                    SET_ERROR(NET_ERR_CLOSED);
                    continue;
                case NET_ETIMEOUT:
                    SET_ERROR(NET_ERR_TIMEOUT);
                    continue;
                case NET_ERROR:
                    st->_errno = res._errno;
                    /* fall through */
                case NET_EDETACHED:
                    continue;
                default:
                    WARNING("should not be here, res._status=%hd", res._status);
                    continue;
            }
            sock = st->_talk->_sock;
            if (st->_cancel) /* canceled by user */
            {
                TRACE("sock[%d] is canceled by user", sock);
                epex_detach(_epex, sock, NULL);
                continue;
            }
            elasp_tm = (now.tv_sec - st->_start_tm.tv_sec) * 1000
                + (now.tv_usec - st->_start_tm.tv_usec) / 1000;
            if (st->_timeout < 0)
                tm_left = -1;
            else if (st->_timeout > elasp_tm)
                tm_left = st->_timeout - elasp_tm;
            else
                tm_left = 0;
            switch (st->_status)
            {
                case NET_ST_SEND_HEAD:
                    TRACE("send head to sock[%d] ok", sock);
                    st->_tm._send_head = elasp_tm;
                    st->_status = NET_ST_SEND_BODY;
                    if (tm_left == 0)
                    {
                        SET_ERROR(NET_ERR_TIMEOUT);
                        continue;
                    }
                    if (!epex_write(_epex, sock, st->_talk->_req_buf, st->_talk->_req_len,
                                NULL, tm_left))
                    {
                        SET_ERROR(NET_ERR_WRITE);
                        continue;
                    }
                    TRACE("try to send body[%u] to sock[%d]", st->_talk->_req_len, sock);
                    break;
                case NET_ST_SEND_BODY:
                    TRACE("send body[%u] to sock[%d] ok", st->_talk->_req_len, sock);
                    st->_tm._send_body = elasp_tm - st->_tm._send_head;
                    st->_status = NET_ST_RECV_HEAD;
                    if (tm_left == 0)
                    {
                        SET_ERROR(NET_ERR_TIMEOUT);
                        continue;
                    }
                    if (!epex_read(_epex, sock, &st->_talk->_res_head, sizeof(st->_talk->_res_head),
                                NULL, tm_left))
                    {
                        SET_ERROR(NET_ERR_READ);
                        continue;
                    }
                    TRACE("try to recv head from sock[%d]", sock);
                    break;
                case NET_ST_RECV_HEAD:
                    TRACE("recv head from sock[%d] ok", sock);
                    st->_tm._recv_head = elasp_tm - st->_tm._send_body - st->_tm._send_head;
                    if (st->_talk->_res_head._magic_num != MAGIC_NUM)
                    {
                        SET_ERROR(NET_ERR_MAGIC_NUM);
                        continue;
                    }
                    if (st->_talk->_res_head._body_len > st->_talk->_res_len)
                    {
                        SET_ERROR(NET_ERR_BIG_RESP);
                        continue;
                    }
                    st->_status = NET_ST_RECV_BODY;
                    if (tm_left == 0)
                    {
                        SET_ERROR(NET_ERR_TIMEOUT);
                        continue;
                    }
                    if (!epex_read(_epex, sock, st->_talk->_res_buf, st->_talk->_res_head._body_len,
                                NULL, tm_left))
                    {
                        SET_ERROR(NET_ERR_READ);
                        continue;
                    }
                    TRACE("try to recv body[%u] from sock[%d]", st->_talk->_res_head._body_len, sock);
                    break;
                case NET_ST_RECV_BODY:
                    TRACE("recv body[%u] from sock[%d] ok", st->_talk->_res_head._body_len, sock);
                    st->_tm._recv_body = elasp_tm - st->_tm._recv_head
                        - st->_tm._send_body - st->_tm._send_head;
                    st->_status = NET_ST_DONE;
                    epex_detach(_epex, sock, NULL);
                    TRACE("talk with sock[%d] ok", sock);
                    break;
                default:
                    WARNING("should not be here");
                    break;
            }
        }
    }
    NOTICE("NetPoller is stoped now");
#undef SET_ERROR
}