Пример #1
0
void stop_state_manager(void)
{
	struct list_element* current;
	struct client_state* state;

	current = list_head(expiring_states);
	while (current) {
		state = container_of(current, struct client_state, expire);

		bst_remove_node(&states_tree, &state->node);
		release_state(state, 1);

		current = list_next(&state->expire);

		free(state);
	}

	current = list_head(renewed_states);
	while (current) {
		state = container_of(current, struct client_state, expire);

		bst_remove_node(&states_tree, &state->node);
		release_state(state, 1);

		current = list_next(&state->expire);

		free(state);
	}

	free(renewed_states);
	free(expiring_states);
}
Пример #2
0
rcl_status quit_state(state_t state_id, uint32_t sequence)
{
	struct bst_node* node;
	struct client_state* state;
	rcl_status error = RCL_OK;

	log_print(log_notice, "Quitting state: %#" PRIx64 " %" PRIu32, state_id,
		sequence);

	pthread_mutex_lock(&states_lock);
	node = bst_get_node(&states_tree, state_id);
	if (!node) {
		log_print(log_error, "State %#" PRIx64 " not found", state_id);
		error = RCL_BAD_STATE;
		goto out_tree_lock;
	}

	state = container_of(node, struct client_state, node);

	pthread_mutex_lock(&state->lock);
	switch (check_sequence(state, sequence)) {
		case sequence_retry:
			log_print(log_warning, "State %#" PRIx64 " still exists during"	\
				" QUIT retry", state_id);
		case sequence_invalid:
			error = RCL_BAD_SEQUENCE;
			pthread_mutex_unlock(&state->lock);
			goto out_tree_lock;
		default:
			break;
	}

	if (current_epoch == state->expire_epoch)
		list_remove(renewed_states, &state->expire);
	else
		list_remove(expiring_states, &state->expire);

	pthread_mutex_unlock(&state->lock);

	bst_remove_node(&states_tree, node);

out_tree_lock:
	pthread_mutex_unlock(&states_lock);
	if (error)
		return error;

	release_state(state, 0);
	free(state);
	return error;
}
Пример #3
0
static void* state_releaser(void* ptr)
{
	struct list_element* current;
	struct client_state* state;

	struct list* expired_states;

	(void)ptr;

	log_print(log_notice, "Expire epoch %d -> %d", current_epoch,
		!current_epoch);

	pthread_mutex_lock(&states_lock);
	expired_states = expiring_states;
	expiring_states = renewed_states;

	renewed_states = malloc(sizeof(struct list));
	if (renewed_states)
		list_init(renewed_states);
	current_epoch = !current_epoch;

	current = list_head(expired_states);
	while (current) {
		state = container_of(current, struct client_state, expire);

		bst_remove_node(&states_tree, &state->node);
		release_state(state, 1);

		current = list_next(&state->expire);

		free(state);
	}
	
	pthread_mutex_unlock(&states_lock);

	free(expired_states);
	enqueue_delayed_task(state_releaser, NULL, time(NULL) + STATE_EXPIRE);
	return NULL;
}
Пример #4
0
bst_node_t *bst_remove(bst_t *bst, int key) {
	bst_node_t *node = bst_search(bst, key);
	if (NULL_NODE == node) return node;

	return bst_remove_node(bst, node);
}