Commit | Line | Data |
---|---|---|
a7333da7 | 1 | /* |
21cf9b6b | 2 | * Copyright (C) 2011 EfficiOS Inc. |
ab5be9fa MJ |
3 | * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
4 | * Copyright (C) 2013 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
a7333da7 | 5 | * |
ab5be9fa | 6 | * SPDX-License-Identifier: GPL-2.0-only |
a7333da7 | 7 | * |
a7333da7 JG |
8 | */ |
9 | ||
c9e313bc SM |
10 | #include "lttng-sessiond.hpp" |
11 | #include "utils.hpp" | |
12 | #include <common/utils.hpp> | |
99d688f2 JG |
13 | #include <pthread.h> |
14 | ||
a7333da7 | 15 | /* |
f90a04ed MJ |
16 | * Quit pipe for the main thread. This is used by signal handlers to start the |
17 | * shutdown sequence of the main thread which will tear down the other threads | |
18 | * in the appropriate order. | |
a7333da7 | 19 | */ |
f90a04ed | 20 | static int main_quit_pipe[2] = { -1, -1 }; |
a7333da7 JG |
21 | |
22 | /* | |
f90a04ed | 23 | * Init main quit pipe. |
a7333da7 JG |
24 | * |
25 | * Return -1 on error or 0 if all pipes are created. | |
26 | */ | |
f90a04ed | 27 | int sessiond_init_main_quit_pipe(void) |
a7333da7 JG |
28 | { |
29 | int ret, i; | |
30 | ||
f90a04ed | 31 | ret = pipe(main_quit_pipe); |
a7333da7 | 32 | if (ret < 0) { |
f90a04ed | 33 | PERROR("main quit pipe"); |
a7333da7 JG |
34 | goto error; |
35 | } | |
36 | ||
37 | for (i = 0; i < 2; i++) { | |
f90a04ed | 38 | ret = fcntl(main_quit_pipe[i], F_SETFD, FD_CLOEXEC); |
a7333da7 | 39 | if (ret < 0) { |
f90a04ed | 40 | PERROR("fcntl main_quit_pipe"); |
a7333da7 JG |
41 | goto error; |
42 | } | |
43 | } | |
44 | ||
45 | error: | |
46 | return ret; | |
47 | } | |
48 | ||
a7333da7 | 49 | /* |
f90a04ed | 50 | * Wait for a notification on the main quit pipe (with a timeout). |
a7333da7 | 51 | * |
99d688f2 JG |
52 | * A timeout value of -1U means no timeout. |
53 | * | |
a7333da7 JG |
54 | * Returns 1 if the caller should quit, 0 if the timeout was reached, and |
55 | * -1 if an error was encountered. | |
56 | */ | |
f90a04ed | 57 | int sessiond_wait_for_main_quit_pipe(int timeout_ms) |
a7333da7 JG |
58 | { |
59 | int ret; | |
2d54bfb6 | 60 | struct lttng_poll_event events; |
a7333da7 | 61 | |
2d54bfb6 MD |
62 | ret = lttng_poll_create(&events, 1, LTTNG_CLOEXEC); |
63 | if (ret < 0) { | |
64 | PERROR("Failed to initialize poll/epoll set"); | |
65 | ret = -1; | |
66 | goto end; | |
67 | } | |
1524f98c | 68 | ret = lttng_poll_add(&events, main_quit_pipe[0], LPOLLIN); |
2d54bfb6 MD |
69 | if (ret < 0) { |
70 | PERROR("Failed to add file descriptor to poll/epoll set"); | |
71 | ret = -1; | |
72 | goto end_clean_poll; | |
73 | } | |
74 | ret = lttng_poll_wait(&events, timeout_ms); | |
a7333da7 JG |
75 | if (ret > 0) { |
76 | /* Should quit. */ | |
77 | ret = 1; | |
78 | } else if (ret < 0 && errno != EINTR) { | |
79 | /* Unknown error. */ | |
f90a04ed | 80 | PERROR("Failed to epoll()/poll() main quit pipe"); |
a7333da7 JG |
81 | ret = -1; |
82 | } else { | |
83 | /* Timeout reached. */ | |
84 | ret = 0; | |
85 | } | |
2d54bfb6 MD |
86 | end_clean_poll: |
87 | lttng_poll_clean(&events); | |
88 | end: | |
a7333da7 JG |
89 | return ret; |
90 | } | |
91 | ||
f90a04ed | 92 | int sessiond_notify_main_quit_pipe(void) |
a7333da7 | 93 | { |
f90a04ed | 94 | return notify_thread_pipe(main_quit_pipe[1]); |
a7333da7 JG |
95 | } |
96 | ||
f90a04ed | 97 | void sessiond_close_main_quit_pipe(void) |
a7333da7 | 98 | { |
f90a04ed | 99 | utils_close_pipe(main_quit_pipe); |
a7333da7 JG |
100 | } |
101 | ||
f90a04ed MJ |
102 | /* |
103 | * Create a poll set with O_CLOEXEC and add the main quit pipe to the set. | |
104 | */ | |
105 | int sessiond_set_thread_pollset(struct lttng_poll_event *events, size_t size) | |
a7333da7 JG |
106 | { |
107 | int ret; | |
108 | ||
a0377dfe | 109 | LTTNG_ASSERT(events); |
a7333da7 JG |
110 | |
111 | ret = lttng_poll_create(events, size, LTTNG_CLOEXEC); | |
112 | if (ret < 0) { | |
113 | goto error; | |
114 | } | |
115 | ||
f90a04ed | 116 | /* Add main quit pipe */ |
1524f98c | 117 | ret = lttng_poll_add(events, main_quit_pipe[0], LPOLLIN); |
a7333da7 JG |
118 | if (ret < 0) { |
119 | goto error; | |
120 | } | |
121 | ||
122 | return 0; | |
123 | ||
124 | error: | |
125 | return ret; | |
126 | } |