Пример #1
0
void Connection_read_data(Connection *connection, int ordinal)
{
    if(CS_ABORTED == connection->state) {
        return;
    }

    DEBUG(("connection read data fd: %d\n", connection->sockfd));
    assert(connection->current_batch != NULL);
    assert(connection->current_executor != NULL);
    assert(CS_CONNECTED == connection->state);

    Buffer *buffer = Batch_read_buffer(connection->current_batch);
    assert(buffer != NULL);

    while(Batch_has_command(connection->current_batch)) {
        DEBUG(("exec rp\n"));
        Reply *reply = NULL;
        ReplyParserResult rp_res = ReplyParser_execute(connection->parser, Buffer_data(buffer), Buffer_position(buffer), &reply);
        switch(rp_res) {
        case RPR_ERROR: {
            Connection_abort(connection, "result parse error");
            return;
        }
        case RPR_MORE: {
            DEBUG(("read data RPR_MORE buf recv\n"));
            size_t res = Buffer_recv(buffer, connection->sockfd);
            DEBUG(("read data RPR_MORE res: %d\n", res));
#ifndef NDEBUG
        Buffer_dump(buffer, 128);
#endif
            if(res == -1) {
                if(errno == EAGAIN) {
                     DEBUG(("read data expecting more data in future, adding event\n"));
                    Executor_notify_event(connection->current_executor, connection, EVENT_READ, ordinal);
                    return;
                }
                else {
                    Connection_abort(connection, "read error, errno: [%d] %s", errno, strerror(errno));
                    return;
                }
            }
            else if(res == 0) {
                Connection_abort(connection, "read eof");
                return;
            }
            break;
        }
        case RPR_REPLY: {
            DEBUG(("read data RPR_REPLY batch add reply\n"));
            Batch_add_reply(connection->current_batch, reply);
            break;
        }
        default:
            Connection_abort(connection, "unexpected result parser result, rpres: %d", rp_res);
            return;
        }
    }
}
Пример #2
0
int Executor_execute(Executor *executor, int timeout_ms)
{
	DEBUG(("Executor execute start\n"));

	//determine max endtime based on timeout
	struct timespec tm;
	clock_gettime(CLOCK_MONOTONIC, &tm);
	DEBUG(("Executor start_tm_ms: %3.2f\n", TIMESPEC_TO_MS(tm)));
	executor->end_tm_ms = TIMESPEC_TO_MS(tm) + ((float)timeout_ms);
	DEBUG(("Executor end_tm_ms: %3.2f\n", executor->end_tm_ms));

	executor->numevents = 0;
	for(int i = 0; i < executor->numpairs; i++) {
		struct _Pair *pair = &executor->pairs[i];
		Connection_execute_start(pair->connection, executor, pair->batch, i);
	}

	int poll_result = 1;
	//for as long there are outstanding events and no error or timeout occurred:
	while(executor->numevents > 0 && poll_result > 0) {
		//figure out how many ms left for this execution
		int timeout;
		if (Executor_current_timeout(executor, &timeout) == -1) {
			//if no time is left, force a timeout
			poll_result = 0;
		} else {
			//do the poll
			DEBUG(("Executor start poll num_events: %d\n", executor->numevents));
			poll_result = poll(executor->fds, executor->numpairs, timeout);

			DEBUG(("Executor select res %d\n", poll_result));
		}

		for(int i = 0; i < executor->numpairs; i++) {

			struct _Pair *pair = &executor->pairs[i];
			Connection *connection = pair->connection;
			Batch *batch = pair->batch;
			struct pollfd *fd = &executor->fds[i];

			EventType event = 0;
			if(fd->revents & POLLIN) {
				event |= EVENT_READ;
				fd->events &= ~POLLIN;
				fd->revents &= ~POLLIN;
				executor->numevents -= 1;
			}
			if(fd->revents & POLLOUT) {
				event |= EVENT_WRITE;
				fd->events &= ~POLLOUT;
				fd->revents &= ~POLLOUT;
				executor->numevents -= 1;
			}

			if(poll_result == 0) {
				event = EVENT_TIMEOUT;
			}
			else if(poll_result < 0) {
				event = EVENT_ERROR;
			}

			if(event > 0 && Batch_has_command(batch)) {
				//there is an event, and batch is not finished
				Connection_handle_event(connection, event, i);
			}
		}
	}

	if(poll_result > 1) {
		poll_result = 1;
	}
	if(poll_result < 0) {
		Module_set_error(GET_MODULE(), "Execute select error, errno: [%d] %s", errno, strerror(errno));
	}
	else if(poll_result == 0) {
		Module_set_error(GET_MODULE(), "Execute timeout");
	}
	DEBUG(("Executor execute done\n"));
	return poll_result;
}
Пример #3
0
int Executor_execute(Executor *executor, int timeout_ms)
{
	DEBUG(("Executor execute start\n"));

	//determine max endtime based on timeout
	struct timespec tm;
	clock_gettime(CLOCK_MONOTONIC, &tm);
	DEBUG(("Executor start_tm_ms: %3.2f\n", TIMESPEC_TO_MS(tm)));
	executor->end_tm_ms = TIMESPEC_TO_MS(tm) + ((float)timeout_ms);
	DEBUG(("Executor end_tm_ms: %3.2f\n", executor->end_tm_ms));

	executor->numevents = 0;
	for(int i = 0; i < executor->numpairs; i++) {
		struct _Pair *pair = &executor->pairs[i];
		Connection_execute_start(pair->connection, executor, pair->batch);
	}

	int select_result = 1;
	//for as long there are outstanding events and no error or timeout occurred:
	while(executor->numevents > 0 && select_result > 0) {

		//figure out how many ms left for this execution
		struct timeval tv;
		Executor_current_timeout(executor, &tv);

		//copy filedes. sets, because select is going to modify them
		fd_set readfds;
		fd_set writefds;
		readfds = executor->readfds;
		writefds = executor->writefds;

		//do the select
		DEBUG(("Executor start select max_fd %d, num_events: %d\n", executor->max_fd, executor->numevents));
		select_result = select(executor->max_fd + 1, &readfds, &writefds, NULL, &tv);

		DEBUG(("Executor select res %d\n", select_result));

		for(int i = 0; i < executor->numpairs; i++) {

			struct _Pair *pair = &executor->pairs[i];
			Connection *connection = pair->connection;
			Batch *batch = pair->batch;

			EventType event = 0;
			if(FD_ISSET(connection->sockfd, &readfds)) {
				event |= EVENT_READ;
				FD_CLR(connection->sockfd, &executor->readfds);
				executor->numevents -= 1;
			}
			if(FD_ISSET(connection->sockfd, &writefds)) {
				event |= EVENT_WRITE;
				FD_CLR(connection->sockfd, &executor->writefds);
				executor->numevents -= 1;
			}

			if(select_result == 0) {
				event = EVENT_TIMEOUT;
			}
			else if(select_result < 0) {
				event = EVENT_ERROR;
			}

			if(event > 0 && Batch_has_command(batch)) {
				//there is an event, and batch is not finished
				Connection_handle_event(connection, event);
			}
		}
	}

	if(select_result > 1) {
		select_result = 1;
	}
	if(select_result < 0) {
		Module_set_error(GET_MODULE(), "Execute select error, errno: [%d] %s", errno, strerror(errno));
	}
	else if(select_result == 0) {
		Module_set_error(GET_MODULE(), "Execute timeout");
	}
	DEBUG(("Executor execute done\n"));
	return select_result;
}