+ /* Infinite blocking call, waiting for transmission */
+restart:
+ ret = lttng_poll_wait(&events, -1);
+ if (ret < 0) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart;
+ }
+ goto error;
+ }
+
+ nb_fd = ret;
+
+ for (i = 0; i < nb_fd; i++) {
+ /* Fetch once the poll data */
+ revents = LTTNG_POLL_GETEV(&events, i);
+ pollfd = LTTNG_POLL_GETFD(&events, i);
+
+ /* Event on the registration socket */
+ if (pollfd == sock) {
+ if (revents & LPOLLIN) {
+ continue;
+ } else if (revents & (LPOLLERR | LPOLLHUP | LPOLLRDHUP)) {
+ ERR("Health socket poll error");
+ goto error;
+ } else {
+ ERR("Unexpected poll events %u for sock %d", revents, pollfd);
+ goto error;
+ }
+ } else {
+ /* Event on the thread's quit pipe. */
+ err = 0;
+ goto exit;
+ }
+ }
+
+ new_sock = lttcomm_accept_unix_sock(sock);
+ if (new_sock < 0) {
+ goto error;
+ }
+
+ /*
+ * Set the CLOEXEC flag. Return code is useless because either way, the
+ * show must go on.
+ */
+ (void) utils_set_fd_cloexec(new_sock);
+
+ DBG("Receiving data from client for health...");
+ ret = lttcomm_recv_unix_sock(new_sock, (void *)&msg, sizeof(msg));
+ if (ret <= 0) {
+ DBG("Nothing recv() from client... continuing");
+ ret = close(new_sock);
+ if (ret) {
+ PERROR("close");
+ }
+ continue;
+ }
+
+ rcu_thread_online();
+
+ memset(&reply, 0, sizeof(reply));
+ for (i = 0; i < NR_HEALTH_SESSIOND_TYPES; i++) {
+ /*
+ * health_check_state returns 0 if health is
+ * bad.
+ */
+ if (!health_check_state(health_sessiond, i)) {
+ reply.ret_code |= 1ULL << i;
+ }
+ }
+
+ DBG2("Health check return value %" PRIx64, reply.ret_code);
+
+ ret = lttcomm_send_unix_sock(new_sock, (void *) &reply,
+ sizeof(reply));
+ if (ret < 0) {
+ ERR("Failed to send health data back to client");
+ }
+
+ /* End of transmission */
+ ret = close(new_sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+
+exit: