Typo fix: uninitializez ->uninitialized
[lttng-tools.git] / src / common / pipe.c
1 /*
2 * Copyright (C) 2013 - David Goulet <dgoulet@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License, version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
15 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18 #define _LGPL_SOURCE
19 #include <assert.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22
23 #include <common/common.h>
24
25 #include "pipe.h"
26
27 /*
28 * Lock read side of a pipe.
29 */
30 static void lock_read_side(struct lttng_pipe *pipe)
31 {
32 pthread_mutex_lock(&pipe->read_mutex);
33 }
34
35 /*
36 * Unlock read side of a pipe.
37 */
38 static void unlock_read_side(struct lttng_pipe *pipe)
39 {
40 pthread_mutex_unlock(&pipe->read_mutex);
41 }
42
43 /*
44 * Lock write side of a pipe.
45 */
46 static void lock_write_side(struct lttng_pipe *pipe)
47 {
48 pthread_mutex_lock(&pipe->write_mutex);
49 }
50
51 /*
52 * Unlock write side of a pipe.
53 */
54 static void unlock_write_side(struct lttng_pipe *pipe)
55 {
56 pthread_mutex_unlock(&pipe->write_mutex);
57 }
58
59 /*
60 * Internal function. Close read side of pipe WITHOUT locking the mutex.
61 *
62 * Return 0 on success else a negative errno from close(2).
63 */
64 static int _pipe_read_close(struct lttng_pipe *pipe)
65 {
66 int ret, ret_val = 0;
67
68 assert(pipe);
69
70 if (!lttng_pipe_is_read_open(pipe)) {
71 goto end;
72 }
73
74 do {
75 ret = close(pipe->fd[0]);
76 } while (ret < 0 && errno == EINTR);
77 if (ret < 0) {
78 PERROR("close lttng read pipe");
79 ret_val = -errno;
80 }
81 pipe->r_state = LTTNG_PIPE_STATE_CLOSED;
82
83 end:
84 return ret_val;
85 }
86
87 /*
88 * Internal function. Close write side of pipe WITHOUT locking the mutex.
89 *
90 * Return 0 on success else a negative errno from close(2).
91 */
92 static int _pipe_write_close(struct lttng_pipe *pipe)
93 {
94 int ret, ret_val = 0;
95
96 assert(pipe);
97
98 if (!lttng_pipe_is_write_open(pipe)) {
99 goto end;
100 }
101
102 do {
103 ret = close(pipe->fd[1]);
104 } while (ret < 0 && errno == EINTR);
105 if (ret < 0) {
106 PERROR("close lttng write pipe");
107 ret_val = -errno;
108 }
109 pipe->w_state = LTTNG_PIPE_STATE_CLOSED;
110
111 end:
112 return ret_val;
113 }
114
115
116 /*
117 * Open a new lttng pipe and set flags using fcntl().
118 *
119 * Return a newly allocated lttng pipe on success or else NULL.
120 */
121 LTTNG_HIDDEN
122 struct lttng_pipe *lttng_pipe_open(int flags)
123 {
124 int ret;
125 struct lttng_pipe *p;
126
127 p = zmalloc(sizeof(*p));
128 if (!p) {
129 PERROR("zmalloc pipe open");
130 goto error;
131 }
132
133 ret = pipe(p->fd);
134 if (ret < 0) {
135 PERROR("lttng pipe");
136 goto error;
137 }
138
139 if (flags) {
140 int i;
141
142 for (i = 0; i < 2; i++) {
143 ret = fcntl(p->fd[i], F_SETFD, flags);
144 if (ret < 0) {
145 PERROR("fcntl lttng pipe %d", flags);
146 goto error;
147 }
148 }
149 }
150
151 pthread_mutex_init(&p->read_mutex, NULL);
152 pthread_mutex_init(&p->write_mutex, NULL);
153 p->r_state = LTTNG_PIPE_STATE_OPENED;
154 p->w_state = LTTNG_PIPE_STATE_OPENED;
155 p->flags = flags;
156
157 return p;
158
159 error:
160 lttng_pipe_destroy(p);
161 return NULL;
162 }
163
164 /*
165 * Close read side of a lttng pipe.
166 *
167 * Return 0 on success else a negative value.
168 */
169 LTTNG_HIDDEN
170 int lttng_pipe_read_close(struct lttng_pipe *pipe)
171 {
172 int ret;
173
174 assert(pipe);
175
176 /* Handle read side first. */
177 lock_read_side(pipe);
178 ret = _pipe_read_close(pipe);
179 unlock_read_side(pipe);
180
181 return ret;
182 }
183
184 /*
185 * Close write side of a lttng pipe.
186 *
187 * Return 0 on success else a negative value.
188 */
189 LTTNG_HIDDEN
190 int lttng_pipe_write_close(struct lttng_pipe *pipe)
191 {
192 int ret;
193
194 assert(pipe);
195
196 lock_write_side(pipe);
197 ret = _pipe_write_close(pipe);
198 unlock_write_side(pipe);
199
200 return ret;
201 }
202
203 /*
204 * Close both read and write side of a lttng pipe.
205 *
206 * Return 0 on success else a negative value.
207 */
208 LTTNG_HIDDEN
209 int lttng_pipe_close(struct lttng_pipe *pipe)
210 {
211 int ret, ret_val = 0;
212
213 assert(pipe);
214
215 ret = lttng_pipe_read_close(pipe);
216 if (ret < 0) {
217 ret_val = ret;
218 }
219
220 ret = lttng_pipe_write_close(pipe);
221 if (ret < 0) {
222 ret_val = ret;
223 }
224
225 return ret_val;
226 }
227
228 /*
229 * Close and destroy a lttng pipe object. Finally, pipe is freed.
230 */
231 LTTNG_HIDDEN
232 void lttng_pipe_destroy(struct lttng_pipe *pipe)
233 {
234 int ret;
235
236 if (!pipe) {
237 return;
238 }
239
240 /*
241 * Destroy should *never* be called with a locked mutex. These must always
242 * succeed so we unlock them after the close pipe below.
243 */
244 ret = pthread_mutex_trylock(&pipe->read_mutex);
245 assert(!ret);
246 ret = pthread_mutex_trylock(&pipe->write_mutex);
247 assert(!ret);
248
249 /* Close pipes WITHOUT trying to lock the pipes. */
250 (void) _pipe_read_close(pipe);
251 (void) _pipe_write_close(pipe);
252
253 unlock_read_side(pipe);
254 unlock_write_side(pipe);
255
256 (void) pthread_mutex_destroy(&pipe->read_mutex);
257 (void) pthread_mutex_destroy(&pipe->write_mutex);
258
259 free(pipe);
260 }
261
262 /*
263 * Read on a lttng pipe and put the data in buf of at least size count.
264 *
265 * Return "count" on success. Return < count on error. errno can be used
266 * to check the actual error.
267 */
268 LTTNG_HIDDEN
269 ssize_t lttng_pipe_read(struct lttng_pipe *pipe, void *buf, size_t count)
270 {
271 ssize_t ret;
272
273 assert(pipe);
274 assert(buf);
275
276 lock_read_side(pipe);
277 if (!lttng_pipe_is_read_open(pipe)) {
278 ret = -1;
279 errno = EBADF;
280 goto error;
281 }
282 ret = lttng_read(pipe->fd[0], buf, count);
283 error:
284 unlock_read_side(pipe);
285 return ret;
286 }
287
288 /*
289 * Write on a lttng pipe using the data in buf and size of count.
290 *
291 * Return "count" on success. Return < count on error. errno can be used
292 * to check the actual error.
293 */
294 LTTNG_HIDDEN
295 ssize_t lttng_pipe_write(struct lttng_pipe *pipe, const void *buf,
296 size_t count)
297 {
298 ssize_t ret;
299
300 assert(pipe);
301 assert(buf);
302
303 lock_write_side(pipe);
304 if (!lttng_pipe_is_write_open(pipe)) {
305 ret = -1;
306 errno = EBADF;
307 goto error;
308 }
309 ret = lttng_write(pipe->fd[1], buf, count);
310 error:
311 unlock_write_side(pipe);
312 return ret;
313 }
This page took 0.037291 seconds and 5 git commands to generate.