Protect the abort_flag on reset and always close on rotate
[lttng-tools.git] / src / bin / lttng-relayd / ctf-trace.c
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 <assert.h>
21
22 #include <common/common.h>
23 #include <common/utils.h>
24
25 #include "ctf-trace.h"
26
27 static uint64_t last_relay_ctf_trace_id;
28
29 /*
30 * Try to destroy a ctf_trace object meaning that the refcount is decremented
31 * and checked if down to 0 which will free it.
32 */
33 void ctf_trace_try_destroy(struct ctf_trace *obj)
34 {
35 unsigned long ret_ref;
36
37 if (!obj) {
38 return;
39 }
40
41 ret_ref = uatomic_add_return(&obj->refcount, -1);
42 assert(ret_ref >= 0);
43 if (ret_ref == 0) {
44 DBG("Freeing ctf_trace %" PRIu64, obj->id);
45 free(obj);
46 }
47 }
48
49 /*
50 * Create and return an allocated ctf_trace object. NULL on error.
51 */
52 struct ctf_trace *ctf_trace_create(void)
53 {
54 struct ctf_trace *obj;
55
56 obj = zmalloc(sizeof(*obj));
57 if (!obj) {
58 PERROR("ctf_trace alloc");
59 goto error;
60 }
61
62 obj->id = ++last_relay_ctf_trace_id;
63 DBG("Created ctf_trace %" PRIu64, obj->id);
64
65 error:
66 return obj;
67 }
68
69 /*
70 * Check if we can assign the ctf_trace id and metadata stream to one or all
71 * the streams with the same path_name (our unique ID for ctf traces).
72 *
73 * The given stream MUST be new and NOT visible (in any hash table).
74 */
75 void ctf_trace_assign(struct lttng_ht *ht, struct relay_stream *stream)
76 {
77 struct lttng_ht_iter iter;
78 struct relay_stream *tmp_stream;
79
80 assert(ht);
81 assert(stream);
82
83 rcu_read_lock();
84 cds_lfht_for_each_entry_duplicate(ht->ht,
85 ht->hash_fct((void *) stream->path_name, lttng_ht_seed),
86 ht->match_fct, (void *) stream->path_name,
87 &iter.iter, tmp_stream, ctf_trace_node.node) {
88 if (stream->metadata_flag) {
89 /*
90 * The new stream is the metadata stream for this trace,
91 * assign the ctf_trace pointer to all the streams in
92 * this bucket.
93 */
94 pthread_mutex_lock(&tmp_stream->lock);
95 tmp_stream->ctf_trace = stream->ctf_trace;
96 uatomic_inc(&tmp_stream->ctf_trace->refcount);
97 pthread_mutex_unlock(&tmp_stream->lock);
98 DBG("Assigned ctf_trace %" PRIu64 " to stream %" PRIu64,
99 tmp_stream->ctf_trace->id, tmp_stream->stream_handle);
100 } else if (tmp_stream->ctf_trace) {
101 /*
102 * The ctf_trace already exists for this bucket,
103 * just assign the pointer to the new stream and exit.
104 */
105 stream->ctf_trace = tmp_stream->ctf_trace;
106 uatomic_inc(&stream->ctf_trace->refcount);
107 DBG("Assigned ctf_trace %" PRIu64 " to stream %" PRIu64,
108 tmp_stream->ctf_trace->id, tmp_stream->stream_handle);
109 goto end;
110 } else {
111 /*
112 * We don't know yet the ctf_trace ID (no metadata has been added),
113 * so leave it there until the metadata stream arrives.
114 */
115 goto end;
116 }
117 }
118
119 end:
120 rcu_read_unlock();
121 return;
122 }
123
This page took 0.033686 seconds and 4 git commands to generate.