Ejemplo n.º 1
0
int Executor_current_timeout(Executor *executor, struct timeval *tv)
{
	struct timespec tm;
	clock_gettime(CLOCK_MONOTONIC, &tm);
	double cur_tm_ms = TIMESPEC_TO_MS(tm);
	DEBUG(("Executor cur_tm: %3.2f\n", cur_tm_ms));
	double left_ms = executor->end_tm_ms - cur_tm_ms;
	DEBUG(("Time left: %3.2f\n", left_ms));
	tv->tv_sec = (time_t)left_ms / 1000.0;
	tv->tv_usec = (left_ms - (tv->tv_sec * 1000.0)) * 1000.0;
	DEBUG(("Timeout: %d sec, %d usec\n", (int)tv->tv_sec, (int)tv->tv_usec));
	return 0;
}
Ejemplo n.º 2
0
int Executor_current_timeout(Executor *executor, int *timeout)
{
	struct timespec tm;
	clock_gettime(CLOCK_MONOTONIC, &tm);
	double cur_tm_ms = TIMESPEC_TO_MS(tm);
	DEBUG(("Executor cur_tm: %3.2f\n", cur_tm_ms));
	double left_ms = executor->end_tm_ms - cur_tm_ms;
	DEBUG(("Time left: %3.2f\n", left_ms));
	if (left_ms < 0.0) {
		return -1;
	}
	*timeout = (int)left_ms;
	DEBUG(("Timeout: %d msec\n", *timeout));
	return 0;
}
Ejemplo n.º 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, 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;
}
Ejemplo n.º 4
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;
}