static
int run_command_wait(struct notification_thread_handle *handle,
		struct notification_thread_command *cmd)
{
	int ret;
	uint64_t notification_counter = 1;

	pthread_mutex_lock(&handle->cmd_queue.lock);
	/* Add to queue. */
	cds_list_add_tail(&cmd->cmd_list_node,
			&handle->cmd_queue.list);
	/* Wake-up thread. */
	ret = write(lttng_pipe_get_writefd(handle->cmd_queue.event_pipe),
			&notification_counter, sizeof(notification_counter));
	if (ret < 0) {
		PERROR("write to notification thread's queue event fd");
		/*
		 * Remove the command from the list so the notification
		 * thread does not process it.
		 */
		cds_list_del(&cmd->cmd_list_node);
		goto error_unlock_queue;
	}
	pthread_mutex_unlock(&handle->cmd_queue.lock);

	lttng_waiter_wait(&cmd->reply_waiter);
	return 0;
error_unlock_queue:
	pthread_mutex_unlock(&handle->cmd_queue.lock);
	return -1;
}
Beispiel #2
0
struct cds_list_head *deq_pop_r(struct deq *p)
{
	struct cds_list_head *e;

	if (cds_list_empty(&p->chain))
		e = NULL;
	else {
		e = p->chain.next;
		cds_list_del(e);
		CDS_INIT_LIST_HEAD(e);
	}
	return e;
}
Beispiel #3
0
struct cds_list_head *deq_pop_l(struct deq *p)
{
	struct cds_list_head *e;

	spin_lock(&p->lock);
	if (cds_list_empty(&p->chain))
		e = NULL;
	else {
		e = p->chain.prev;
		cds_list_del(e);
		CDS_INIT_LIST_HEAD(e);
	}
	spin_unlock(&p->lock);
	return e;
}
Beispiel #4
0
enum lttng_notification_channel_status
lttng_notification_channel_get_next_notification(
		struct lttng_notification_channel *channel,
		struct lttng_notification **_notification)
{
	int ret;
	struct lttng_notification *notification = NULL;
	enum lttng_notification_channel_status status =
			LTTNG_NOTIFICATION_CHANNEL_STATUS_OK;

	if (!channel || !_notification) {
		status = LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID;
		goto end;
	}

	if (channel->pending_notifications.count) {
		struct pending_notification *pending_notification;

		assert(!cds_list_empty(&channel->pending_notifications.list));

		/* Deliver one of the pending notifications. */
		pending_notification = cds_list_first_entry(
				&channel->pending_notifications.list,
				struct pending_notification,
				node);
		notification = pending_notification->notification;
		if (!notification) {
			status = LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED;
		}
		cds_list_del(&pending_notification->node);
		channel->pending_notifications.count--;
		free(pending_notification);
		goto end;
	}

	pthread_mutex_lock(&channel->lock);

	ret = receive_message(channel);
	if (ret) {
		status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR;
		goto end_unlock;
	}

	switch (get_current_message_type(channel)) {
	case LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_NOTIFICATION:
		notification = create_notification_from_current_message(
				channel);
		if (!notification) {
			status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR;
			goto end_unlock;
		}
		break;
	case LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_NOTIFICATION_DROPPED:
		/* No payload to consume. */
		status = LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED;
		break;
	default:
		/* Protocol error. */
		status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR;
		goto end_unlock;
	}

end_unlock:
	pthread_mutex_unlock(&channel->lock);
end:
	if (_notification) {
		*_notification = notification;
	}
	return status;
}