+static
+int drain_event_notifier_notification_pipe(
+ struct notification_thread_state *state,
+ int pipe, enum lttng_domain_type domain)
+{
+ struct lttng_poll_event events = {0};
+ int ret;
+
+ ret = lttng_poll_create(&events, 1, LTTNG_CLOEXEC);
+ if (ret < 0) {
+ ERR("[notification-thread] Error creating lttng_poll_event");
+ goto end;
+ }
+
+ ret = lttng_poll_add(&events, pipe, LPOLLIN);
+ if (ret < 0) {
+ ERR("[notification-thread] Error adding fd event notifier notification pipe to lttng_poll_event: fd = %d",
+ pipe);
+ goto end;
+ }
+
+ while (true) {
+ /*
+ * Continue to consume notifications as long as there are new
+ * ones coming in. The tracer has been asked to stop producing
+ * them.
+ *
+ * LPOLLIN is explicitly checked since LPOLLHUP is implicitly
+ * monitored (on Linux, at least) and will be returned when
+ * the pipe is closed but empty.
+ */
+ ret = lttng_poll_wait_interruptible(&events, 0);
+ if (ret == 0 || (LTTNG_POLL_GETEV(&events, 0) & LPOLLIN) == 0) {
+ /* No more notification to be read on this pipe. */
+ ret = 0;
+ goto end;
+ } else if (ret < 0) {
+ PERROR("Failed on lttng_poll_wait_interruptible() call");
+ ret = -1;
+ goto end;
+ }
+
+ ret = handle_one_event_notifier_notification(state, pipe, domain);
+ if (ret) {
+ ERR("[notification-thread] Error consuming an event notifier notification from pipe: fd = %d",
+ pipe);
+ }
+ }
+end:
+ lttng_poll_clean(&events);
+ return ret;
+}
+