include/babeltrace/graph: fix some include guards
[babeltrace.git] / lib / ctf-ir / stream.c
CommitLineData
273b65be
JG
1/*
2 * stream.c
3 *
d2dc44b6 4 * Babeltrace CTF IR - Stream
273b65be 5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
19abc2c6
PP
29#define BT_LOG_TAG "STREAM"
30#include <babeltrace/lib-logging-internal.h>
31
d975f66c 32#include <babeltrace/assert-pre-internal.h>
3dca2276
PP
33#include <babeltrace/ctf-ir/stream.h>
34#include <babeltrace/ctf-ir/stream-internal.h>
35#include <babeltrace/ctf-ir/stream-class.h>
36#include <babeltrace/ctf-ir/stream-class-internal.h>
37#include <babeltrace/ctf-ir/trace.h>
38#include <babeltrace/ctf-ir/trace-internal.h>
39#include <babeltrace/ref.h>
40#include <babeltrace/compiler-internal.h>
41#include <babeltrace/align-internal.h>
42#include <babeltrace/assert-internal.h>
43#include <inttypes.h>
44#include <unistd.h>
12c8a1a3 45
3dca2276
PP
46BT_HIDDEN
47void bt_stream_common_finalize(struct bt_stream_common *stream)
263a7df5 48{
3dca2276 49 int i;
263a7df5 50
3dca2276
PP
51 BT_LOGD("Finalizing common stream object: addr=%p, name=\"%s\"",
52 stream, bt_stream_common_get_name(stream));
263a7df5 53
3dca2276
PP
54 /* Call destroy listeners in reverse registration order */
55 for (i = stream->destroy_listeners->len - 1; i >= 0; i--) {
56 struct bt_stream_common_destroy_listener *listener =
57 &g_array_index(stream->destroy_listeners,
58 struct bt_stream_common_destroy_listener, i);
19abc2c6 59
3dca2276
PP
60 BT_LOGD("Calling destroy listener: func=%p, data=%p, index=%d",
61 listener->func, listener->data, i);
62 listener->func(stream, listener->data);
263a7df5
JG
63 }
64
3dca2276
PP
65 if (stream->name) {
66 g_string_free(stream->name, TRUE);
b3376dd9
PP
67 }
68
3dca2276
PP
69 if (stream->destroy_listeners) {
70 g_array_free(stream->destroy_listeners, TRUE);
263a7df5 71 }
263a7df5
JG
72}
73
c9af50d1 74static
3dca2276 75void bt_stream_destroy(struct bt_object *obj)
c9af50d1 76{
3dca2276 77 struct bt_stream *stream = (void *) obj;
c9af50d1 78
3dca2276
PP
79 BT_LOGD("Destroying stream object: addr=%p, name=\"%s\"",
80 stream, bt_stream_get_name(stream));
81 bt_stream_common_finalize((void *) obj);
82 g_free(stream);
c9af50d1
JG
83}
84
3dca2276
PP
85BT_HIDDEN
86int bt_stream_common_initialize(
87 struct bt_stream_common *stream,
88 struct bt_stream_class_common *stream_class, const char *name,
89 uint64_t id, bt_object_release_func release_func)
273b65be
JG
90{
91 int ret = 0;
3dca2276 92 struct bt_trace_common *trace = NULL;
98edd02c 93
3dca2276 94 bt_object_init(stream, release_func);
273b65be 95
3dca2276
PP
96 if (!stream_class) {
97 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
98 goto error;
b3376dd9 99 }
12c8a1a3 100
3dca2276
PP
101 BT_LOGD("Initializing common stream object: stream-class-addr=%p, "
102 "stream-class-name=\"%s\", stream-name=\"%s\", "
103 "stream-id=%" PRIu64,
104 stream_class, bt_stream_class_common_get_name(stream_class),
105 name, id);
106 trace = bt_stream_class_common_borrow_trace(stream_class);
107 if (!trace) {
108 BT_LOGW("Invalid parameter: cannot create stream from a stream class which is not part of trace: "
109 "stream-class-addr=%p, stream-class-name=\"%s\", "
110 "stream-name=\"%s\"",
111 stream_class,
112 bt_stream_class_common_get_name(stream_class), name);
113 goto error;
12c8a1a3
JG
114 }
115
3dca2276
PP
116 if (id != -1ULL) {
117 /*
118 * Validate that the given ID is unique amongst all the
119 * existing trace's streams created from the same stream
120 * class.
121 */
122 size_t i;
19abc2c6 123
3dca2276
PP
124 for (i = 0; i < trace->streams->len; i++) {
125 struct bt_stream_common *trace_stream =
126 g_ptr_array_index(trace->streams, i);
273b65be 127
3dca2276
PP
128 if (trace_stream->stream_class != (void *) stream_class) {
129 continue;
06b019a7 130 }
273b65be 131
3dca2276
PP
132 if (trace_stream->id == id) {
133 BT_LOGW_STR("Invalid parameter: another stream in the same trace already has this ID.");
134 goto error;
8bfa3f9c
JG
135 }
136 }
1c1d572f
JD
137 }
138
1c1d572f 139 /*
3dca2276
PP
140 * Acquire reference to parent since stream will become publicly
141 * reachable; it needs its parent to remain valid.
1c1d572f 142 */
3dca2276
PP
143 bt_object_set_parent(stream, trace);
144 stream->stream_class = stream_class;
145 stream->id = (int64_t) id;
146 stream->destroy_listeners = g_array_new(FALSE, TRUE,
147 sizeof(struct bt_stream_common_destroy_listener));
148 if (!stream->destroy_listeners) {
149 BT_LOGE_STR("Failed to allocate a GArray.");
150 goto error;
151 }
273b65be 152
3dca2276
PP
153 if (name) {
154 stream->name = g_string_new(name);
155 if (!stream->name) {
156 BT_LOGE_STR("Failed to allocate a GString.");
157 goto error;
98edd02c 158 }
273b65be
JG
159 }
160
3dca2276 161 BT_LOGD("Set common stream's trace parent: trace-addr=%p", trace);
1c1d572f 162
3dca2276
PP
163 /* Add this stream to the trace's streams */
164 BT_LOGD("Created common stream object: addr=%p", stream);
165 goto end;
cd7d8fb7 166
3dca2276
PP
167error:
168 ret = -1;
f0ea9318 169
3dca2276 170end:
273b65be
JG
171 return ret;
172}
173
273b65be 174static
3dca2276
PP
175struct bt_stream *bt_stream_create_with_id_no_check(
176 struct bt_stream_class *stream_class,
177 const char *name, uint64_t id)
273b65be 178{
3dca2276
PP
179 int ret;
180 struct bt_stream *stream = NULL;
181 struct bt_trace *trace = NULL;
3230ee6b 182
3dca2276
PP
183 BT_LOGD("Creating stream object: stream-class-addr=%p, "
184 "stream-class-name=\"%s\", stream-name=\"%s\", "
185 "stream-id=%" PRIu64,
186 stream_class, bt_stream_class_get_name(stream_class),
187 name, id);
3230ee6b 188
3dca2276
PP
189 trace = BT_FROM_COMMON(bt_stream_class_common_borrow_trace(
190 BT_TO_COMMON(stream_class)));
191 if (!trace) {
192 BT_LOGW("Invalid parameter: cannot create stream from a stream class which is not part of trace: "
193 "stream-class-addr=%p, stream-class-name=\"%s\", "
194 "stream-name=\"%s\"",
195 stream_class, bt_stream_class_get_name(stream_class),
196 name);
197 goto error;
3230ee6b
PP
198 }
199
3dca2276 200 if (bt_trace_is_static(trace)) {
0686ef94 201 /*
3dca2276
PP
202 * A static trace has the property that all its stream
203 * classes, clock classes, and streams are definitive:
204 * no more can be added, and each object is also frozen.
0686ef94 205 */
3dca2276
PP
206 BT_LOGW("Invalid parameter: cannot create stream from a stream class which is part of a static trace: "
207 "stream-class-addr=%p, stream-class-name=\"%s\", "
208 "stream-name=\"%s\", trace-addr=%p",
209 stream_class, bt_stream_class_get_name(stream_class),
210 name, trace);
211 goto error;
9f56e450 212 }
12c8a1a3 213
3dca2276
PP
214 stream = g_new0(struct bt_stream, 1);
215 if (!stream) {
216 BT_LOGE_STR("Failed to allocate one stream.");
217 goto error;
12c8a1a3 218 }
b71d7298 219
3dca2276
PP
220 ret = bt_stream_common_initialize(BT_TO_COMMON(stream),
221 BT_TO_COMMON(stream_class), name, id, bt_stream_destroy);
222 if (ret) {
223 /* bt_stream_common_initialize() logs errors */
224 goto error;
b71d7298 225 }
41ac640a 226
3dca2276
PP
227 g_ptr_array_add(trace->common.streams, stream);
228 BT_LOGD("Created stream object: addr=%p", stream);
229 goto end;
3230ee6b 230
3dca2276
PP
231error:
232 BT_PUT(stream);
233
234end:
235 return stream;
273b65be
JG
236}
237
3dca2276
PP
238struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class,
239 const char *name, uint64_t id_param)
273b65be 240{
3dca2276
PP
241 struct bt_stream *stream = NULL;
242 int64_t id = (int64_t) id_param;
273b65be 243
3dca2276
PP
244 if (!stream_class) {
245 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
12c8a1a3
JG
246 goto end;
247 }
248
3dca2276
PP
249 if (id < 0) {
250 BT_LOGW("Invalid parameter: invalid stream's ID: "
251 "name=\"%s\", id=%" PRIu64,
252 name, id_param);
12c8a1a3
JG
253 goto end;
254 }
255
3dca2276
PP
256 stream = bt_stream_create_with_id_no_check(stream_class,
257 name, id_param);
d7b1ea66 258
273b65be 259end:
3dca2276 260 return stream;
273b65be 261}
b71d7298 262
3dca2276 263struct bt_stream_class *bt_stream_get_class(struct bt_stream *stream)
af9296f3 264{
3dca2276 265 return BT_FROM_COMMON(bt_stream_common_get_class(BT_TO_COMMON(stream)));
af9296f3
JG
266}
267
50842bdc 268const char *bt_stream_get_name(struct bt_stream *stream)
b71d7298 269{
3dca2276 270 return bt_stream_common_get_name(BT_TO_COMMON(stream));
b71d7298 271}
98a4cbef 272
3dca2276 273int64_t bt_stream_get_id(struct bt_stream *stream)
98a4cbef 274{
3dca2276 275 return bt_stream_common_get_id(BT_TO_COMMON(stream));
98a4cbef 276}
3230ee6b 277
3230ee6b 278BT_HIDDEN
3dca2276
PP
279void bt_stream_common_add_destroy_listener(struct bt_stream_common *stream,
280 bt_stream_common_destroy_listener_func func, void *data)
3230ee6b 281{
3dca2276 282 struct bt_stream_common_destroy_listener listener;
3230ee6b 283
f6ccaed9
PP
284 BT_ASSERT(stream);
285 BT_ASSERT(func);
3230ee6b
PP
286 listener.func = func;
287 listener.data = data;
288 g_array_append_val(stream->destroy_listeners, listener);
19abc2c6
PP
289 BT_LOGV("Added stream destroy listener: stream-addr=%p, "
290 "stream-name=\"%s\", func=%p, data=%p",
3dca2276 291 stream, bt_stream_common_get_name(stream), func, data);
3230ee6b
PP
292}
293
294BT_HIDDEN
3dca2276
PP
295void bt_stream_common_remove_destroy_listener(struct bt_stream_common *stream,
296 bt_stream_common_destroy_listener_func func, void *data)
3230ee6b
PP
297{
298 size_t i;
299
f6ccaed9
PP
300 BT_ASSERT(stream);
301 BT_ASSERT(func);
3230ee6b
PP
302
303 for (i = 0; i < stream->destroy_listeners->len; i++) {
3dca2276 304 struct bt_stream_common_destroy_listener *listener =
3230ee6b 305 &g_array_index(stream->destroy_listeners,
3dca2276 306 struct bt_stream_common_destroy_listener, i);
3230ee6b
PP
307
308 if (listener->func == func && listener->data == data) {
309 g_array_remove_index(stream->destroy_listeners, i);
310 i--;
19abc2c6
PP
311 BT_LOGV("Removed stream destroy listener: stream-addr=%p, "
312 "stream-name=\"%s\", func=%p, data=%p",
3dca2276 313 stream, bt_stream_common_get_name(stream),
19abc2c6 314 func, data);
3230ee6b
PP
315 }
316 }
317}
This page took 0.070142 seconds and 4 git commands to generate.