Fix: Memory leak in relay_add_stream error path
[lttng-tools.git] / src / bin / lttng-relayd / stream.c
CommitLineData
2a174661
DG
1/*
2 * Copyright (C) 2013 - Julien Desfossez <jdesfossez@efficios.com>
3 * David Goulet <dgoulet@efficios.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License, version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51
16 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#define _GNU_SOURCE
20#include <common/common.h>
21
22#include "index.h"
23#include "stream.h"
24#include "viewer-stream.h"
25
2a174661
DG
26/*
27 * Get stream from stream id from the given hash table. Return stream if found
28 * else NULL.
29 *
30 * Need to be called with RCU read-side lock held.
31 */
32struct relay_stream *stream_find_by_id(struct lttng_ht *ht,
33 uint64_t stream_id)
34{
35 struct lttng_ht_node_u64 *node;
36 struct lttng_ht_iter iter;
37 struct relay_stream *stream = NULL;
38
39 assert(ht);
40
41 lttng_ht_lookup(ht, &stream_id, &iter);
42 node = lttng_ht_iter_get_node_u64(&iter);
43 if (node == NULL) {
44 DBG("Relay stream %" PRIu64 " not found", stream_id);
45 goto end;
46 }
47 stream = caa_container_of(node, struct relay_stream, node);
48
49end:
50 return stream;
51}
52
53/*
54 * Close a given stream. If an assosiated viewer stream exists it is updated.
55 *
56 * RCU read side lock MUST be acquired.
57 *
58 * Return 0 if close was successful or 1 if already closed.
59 */
60int stream_close(struct relay_session *session, struct relay_stream *stream)
61{
62 int delret, ret;
63 struct relay_viewer_stream *vstream;
64 struct ctf_trace *ctf_trace;
65
66 assert(stream);
67
68 pthread_mutex_lock(&stream->lock);
69
70 if (stream->terminated_flag) {
71 /* This stream is already closed. Ignore. */
72 ret = 1;
73 goto end_unlock;
74 }
75
76 DBG("Closing stream id %" PRIu64, stream->stream_handle);
77
78 if (stream->fd >= 0) {
79 delret = close(stream->fd);
80 if (delret < 0) {
81 PERROR("close stream");
82 }
83 }
84
85 if (stream->index_fd >= 0) {
86 delret = close(stream->index_fd);
87 if (delret < 0) {
88 PERROR("close stream index_fd");
89 }
90 }
91
92 vstream = viewer_stream_find_by_id(stream->stream_handle);
93 if (vstream) {
94 /*
95 * Set the last good value into the viewer stream. This is done
96 * right before the stream gets deleted from the hash table. The
97 * lookup failure on the live thread side of a stream indicates
98 * that the viewer stream index received value should be used.
99 */
100 pthread_mutex_lock(&stream->viewer_stream_rotation_lock);
101 vstream->total_index_received = stream->total_index_received;
102 vstream->tracefile_count_last = stream->tracefile_count_current;
103 vstream->close_write_flag = 1;
104 pthread_mutex_unlock(&stream->viewer_stream_rotation_lock);
105 }
106
107 /* Cleanup index of that stream. */
108 relay_index_destroy_by_stream_id(stream->stream_handle);
109
110 ctf_trace = ctf_trace_find_by_path(session->ctf_traces_ht,
111 stream->path_name);
112 assert(ctf_trace);
113 ctf_trace_put_ref(ctf_trace);
114
87a9eb5b 115 stream->close_flag = 1;
2a174661
DG
116 stream->terminated_flag = 1;
117 ret = 0;
118
119end_unlock:
120 pthread_mutex_unlock(&stream->lock);
121 return ret;
122}
123
124void stream_delete(struct lttng_ht *ht, struct relay_stream *stream)
125{
126 int ret;
127 struct lttng_ht_iter iter;
128
129 assert(ht);
130 assert(stream);
131
132 iter.iter.node = &stream->node.node;
133 ret = lttng_ht_del(ht, &iter);
134 assert(!ret);
135
136 cds_list_del(&stream->trace_list);
137}
138
139void stream_destroy(struct relay_stream *stream)
140{
141 assert(stream);
198d75ca
JG
142 free(stream->path_name);
143 free(stream->channel_name);
144 free(stream);
2a174661 145}
This page took 0.029191 seconds and 4 git commands to generate.