X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-relayd%2Fthread-utils.cpp;fp=src%2Fbin%2Flttng-relayd%2Fthread-utils.cpp;h=d469f90e55f67b28730c64955aacfb4757716682;hp=0000000000000000000000000000000000000000;hb=8a00688e1d58cc5a2e77eba206ff23bd6105130c;hpb=6b979fc6dd8c03ed8332bdef2915b9d6d3ecfd6a diff --git a/src/bin/lttng-relayd/thread-utils.cpp b/src/bin/lttng-relayd/thread-utils.cpp new file mode 100644 index 000000000..d469f90e5 --- /dev/null +++ b/src/bin/lttng-relayd/thread-utils.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2022 EfficiOS Inc. + * + * SPDX-License-Identifier: GPL-2.0-only + * + */ + +#include "lttng-relayd.hpp" + +#include +#include +#include +#include +#include + +/* + * Quit pipe for all threads. This permits a single cancellation point + * for all threads when receiving an event on the pipe. + */ +static int thread_quit_pipe[2] = { -1, -1 }; + +/* + * Write to writable pipe used to notify a thread. + */ +static int notify_thread_pipe(int wpipe) +{ + const auto ret = lttng_write(wpipe, "!", 1); + + if (ret < 1) { + PERROR("Failed to write to thread pipe"); + return -1; + } + + return 0; +} + +/* + * Initialize the thread quit pipe. + * + * Return -1 on error or 0 if all pipes are created. + */ +int relayd_init_thread_quit_pipe(void) +{ + return fd_tracker_util_pipe_open_cloexec( + the_fd_tracker, "Thread quit pipe", thread_quit_pipe); +} + +/* + * Notify the threads to initiate shutdown. + * + * Return 0 on success or -1 on error. + */ +int relayd_notify_thread_quit_pipe(void) +{ + return notify_thread_pipe(thread_quit_pipe[1]); +} + +/* + * Close the thread quit pipe. + */ +void relayd_close_thread_quit_pipe(void) +{ + if (thread_quit_pipe[0] != -1) { + (void) fd_tracker_util_pipe_close( + the_fd_tracker, thread_quit_pipe); + } +} + +/* + * Return 1 if 'fd' is the thread quit pipe read fd. + */ +bool relayd_is_thread_quit_pipe(const int fd) +{ + return (fd == thread_quit_pipe[0]); +} + +/* + * Create a poll set with O_CLOEXEC and add the thread quit pipe to the set. + */ +int create_named_thread_poll_set(struct lttng_poll_event *events, + int size, const char *name) +{ + if (events == NULL || size == 0) { + return -1; + } + + const auto create_ret = fd_tracker_util_poll_create(the_fd_tracker, + name, events, 1, LTTNG_CLOEXEC); + if (create_ret) { + PERROR("Failed to create \"%s\" poll file descriptor", name); + return -1; + } + + /* Add thread quit pipe to monitored events. */ + const auto poll_add_ret = lttng_poll_add(events, thread_quit_pipe[0], LPOLLIN | LPOLLERR); + if (poll_add_ret < 0) { + return -1; + } + + return 0; +}