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), ¬ification_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; }
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; }
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; }
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; }