Exemplo n.º 1
0
que_thr_t*
que_fork_start_command(
/*===================*/
				/* out: a query thread of the graph moved to
				QUE_THR_RUNNING state, or NULL; the query
				thread should be executed by que_run_threads
				by the caller */
	que_fork_t* 	fork)	/* in: a query fork */
{
	que_thr_t*	thr;

	fork->state = QUE_FORK_ACTIVE;
	
	fork->last_sel_node = NULL;

	/* Choose the query thread to run: usually there is just one thread,
	but in a parallelized select, which necessarily is non-scrollable,
	there may be several to choose from */

	/*---------------------------------------------------------------
	First we try to find a query thread in the QUE_THR_COMMAND_WAIT state */
	
	thr = UT_LIST_GET_FIRST(fork->thrs);

	while (thr != NULL) {
		if (thr->state == QUE_THR_COMMAND_WAIT) {

			/* We have to send the initial message to query thread
			to start it */

			que_thr_init_command(thr);

			return(thr);
		}

		ut_ad(thr->state != QUE_THR_LOCK_WAIT);
		
		thr = UT_LIST_GET_NEXT(thrs, thr);
	}

	/*----------------------------------------------------------------
	Then we try to find a query thread in the QUE_THR_SUSPENDED state */

	thr = UT_LIST_GET_FIRST(fork->thrs);

	while (thr != NULL) {
		if (thr->state == QUE_THR_SUSPENDED) {
			/* In this case the execution of the thread was
			suspended: no initial message is needed because
			execution can continue from where it was left */

			que_thr_move_to_run_state(thr);

			return(thr);
		}

		thr = UT_LIST_GET_NEXT(thrs, thr);
	}

	/*-----------------------------------------------------------------
	Then we try to find a query thread in the QUE_THR_COMPLETED state */
	
	thr = UT_LIST_GET_FIRST(fork->thrs);

	while (thr != NULL) {
		if (thr->state == QUE_THR_COMPLETED) {
			que_thr_init_command(thr);

			return(thr);
		}

		thr = UT_LIST_GET_NEXT(thrs, thr);
	}

	/* Else we return NULL */
	return(NULL);
}
Exemplo n.º 2
0
/**********************************************************************//**
Starts execution of a command in a query fork. Picks a query thread which
is not in the QUE_THR_RUNNING state and moves it to that state. If none
can be chosen, a situation which may arise in parallelized fetches, NULL
is returned.
@return a query thread of the graph moved to QUE_THR_RUNNING state, or
NULL; the query thread should be executed by que_run_threads by the
caller */
UNIV_INTERN
que_thr_t*
que_fork_start_command(
/*===================*/
	que_fork_t*	fork)	/*!< in: a query fork */
{
	que_thr_t*	thr;
	que_thr_t*	suspended_thr = NULL;
	que_thr_t*	completed_thr = NULL;

	fork->state = QUE_FORK_ACTIVE;

	fork->last_sel_node = NULL;

	suspended_thr = NULL;
	completed_thr = NULL;

	/* Choose the query thread to run: usually there is just one thread,
	but in a parallelized select, which necessarily is non-scrollable,
	there may be several to choose from */

	/* First we try to find a query thread in the QUE_THR_COMMAND_WAIT
	state. Then we try to find a query thread in the QUE_THR_SUSPENDED
	state, finally we try to find a query thread in the QUE_THR_COMPLETED
	state */

	thr = UT_LIST_GET_FIRST(fork->thrs);

	/* We make a single pass over the thr list within which we note which
	threads are ready to run. */
	while (thr) {
		switch (thr->state) {
		case QUE_THR_COMMAND_WAIT:

			/* We have to send the initial message to query thread
			to start it */

			que_thr_init_command(thr);

			return(thr);

		case QUE_THR_SUSPENDED:
			/* In this case the execution of the thread was
			suspended: no initial message is needed because
			execution can continue from where it was left */
			if (!suspended_thr) {
				suspended_thr = thr;
			}

			break;

		case QUE_THR_COMPLETED:
			if (!completed_thr) {
				completed_thr = thr;
			}

			break;

		case QUE_THR_LOCK_WAIT:
			ut_error;

		}

		thr = UT_LIST_GET_NEXT(thrs, thr);
	}

	if (suspended_thr) {

		thr = suspended_thr;
		que_thr_move_to_run_state(thr);

	} else if (completed_thr) {

		thr = completed_thr;
		que_thr_init_command(thr);
	}

	return(thr);
}