lib: add internal object pool API and use it; adapt plugins/tests
[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>
312c056a 39#include <babeltrace/ctf-ir/packet-internal.h>
3dca2276
PP
40#include <babeltrace/ref.h>
41#include <babeltrace/compiler-internal.h>
42#include <babeltrace/align-internal.h>
43#include <babeltrace/assert-internal.h>
44#include <inttypes.h>
45#include <unistd.h>
12c8a1a3 46
3dca2276
PP
47BT_HIDDEN
48void bt_stream_common_finalize(struct bt_stream_common *stream)
263a7df5 49{
3dca2276 50 int i;
263a7df5 51
3dca2276
PP
52 BT_LOGD("Finalizing common stream object: addr=%p, name=\"%s\"",
53 stream, bt_stream_common_get_name(stream));
263a7df5 54
3dca2276 55 /* Call destroy listeners in reverse registration order */
8328cc28
PP
56 if (stream->destroy_listeners) {
57 for (i = stream->destroy_listeners->len - 1; i >= 0; i--) {
58 struct bt_stream_common_destroy_listener *listener =
59 &g_array_index(stream->destroy_listeners,
60 struct bt_stream_common_destroy_listener, i);
19abc2c6 61
8328cc28
PP
62 BT_LOGD("Calling destroy listener: func=%p, data=%p, index=%d",
63 listener->func, listener->data, i);
64 listener->func(stream, listener->data);
65 }
263a7df5
JG
66 }
67
3dca2276
PP
68 if (stream->name) {
69 g_string_free(stream->name, TRUE);
b3376dd9
PP
70 }
71
3dca2276
PP
72 if (stream->destroy_listeners) {
73 g_array_free(stream->destroy_listeners, TRUE);
263a7df5 74 }
263a7df5
JG
75}
76
c9af50d1 77static
3dca2276 78void bt_stream_destroy(struct bt_object *obj)
c9af50d1 79{
3dca2276 80 struct bt_stream *stream = (void *) obj;
c9af50d1 81
3dca2276
PP
82 BT_LOGD("Destroying stream object: addr=%p, name=\"%s\"",
83 stream, bt_stream_get_name(stream));
312c056a 84 bt_object_pool_finalize(&stream->packet_pool);
3dca2276
PP
85 bt_stream_common_finalize((void *) obj);
86 g_free(stream);
c9af50d1
JG
87}
88
3dca2276
PP
89BT_HIDDEN
90int bt_stream_common_initialize(
91 struct bt_stream_common *stream,
92 struct bt_stream_class_common *stream_class, const char *name,
93 uint64_t id, bt_object_release_func release_func)
273b65be
JG
94{
95 int ret = 0;
3dca2276 96 struct bt_trace_common *trace = NULL;
98edd02c 97
3dca2276 98 bt_object_init(stream, release_func);
273b65be 99
3dca2276
PP
100 if (!stream_class) {
101 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
102 goto error;
b3376dd9 103 }
12c8a1a3 104
3dca2276
PP
105 BT_LOGD("Initializing common stream object: stream-class-addr=%p, "
106 "stream-class-name=\"%s\", stream-name=\"%s\", "
107 "stream-id=%" PRIu64,
108 stream_class, bt_stream_class_common_get_name(stream_class),
109 name, id);
110 trace = bt_stream_class_common_borrow_trace(stream_class);
111 if (!trace) {
112 BT_LOGW("Invalid parameter: cannot create stream from a stream class which is not part of trace: "
113 "stream-class-addr=%p, stream-class-name=\"%s\", "
114 "stream-name=\"%s\"",
115 stream_class,
116 bt_stream_class_common_get_name(stream_class), name);
117 goto error;
12c8a1a3
JG
118 }
119
3dca2276
PP
120 if (id != -1ULL) {
121 /*
122 * Validate that the given ID is unique amongst all the
123 * existing trace's streams created from the same stream
124 * class.
125 */
126 size_t i;
19abc2c6 127
3dca2276
PP
128 for (i = 0; i < trace->streams->len; i++) {
129 struct bt_stream_common *trace_stream =
130 g_ptr_array_index(trace->streams, i);
273b65be 131
3dca2276
PP
132 if (trace_stream->stream_class != (void *) stream_class) {
133 continue;
06b019a7 134 }
273b65be 135
3dca2276
PP
136 if (trace_stream->id == id) {
137 BT_LOGW_STR("Invalid parameter: another stream in the same trace already has this ID.");
138 goto error;
8bfa3f9c
JG
139 }
140 }
1c1d572f
JD
141 }
142
1c1d572f 143 /*
3dca2276
PP
144 * Acquire reference to parent since stream will become publicly
145 * reachable; it needs its parent to remain valid.
1c1d572f 146 */
3dca2276
PP
147 bt_object_set_parent(stream, trace);
148 stream->stream_class = stream_class;
149 stream->id = (int64_t) id;
150 stream->destroy_listeners = g_array_new(FALSE, TRUE,
151 sizeof(struct bt_stream_common_destroy_listener));
152 if (!stream->destroy_listeners) {
153 BT_LOGE_STR("Failed to allocate a GArray.");
154 goto error;
155 }
273b65be 156
3dca2276
PP
157 if (name) {
158 stream->name = g_string_new(name);
159 if (!stream->name) {
160 BT_LOGE_STR("Failed to allocate a GString.");
161 goto error;
98edd02c 162 }
273b65be
JG
163 }
164
3dca2276 165 BT_LOGD("Set common stream's trace parent: trace-addr=%p", trace);
1c1d572f 166
3dca2276
PP
167 /* Add this stream to the trace's streams */
168 BT_LOGD("Created common stream object: addr=%p", stream);
169 goto end;
cd7d8fb7 170
3dca2276
PP
171error:
172 ret = -1;
f0ea9318 173
3dca2276 174end:
273b65be
JG
175 return ret;
176}
177
312c056a
PP
178static
179void bt_stream_free_packet(struct bt_packet *packet, struct bt_stream *stream)
180{
181 bt_packet_destroy(packet);
182}
183
273b65be 184static
3dca2276
PP
185struct bt_stream *bt_stream_create_with_id_no_check(
186 struct bt_stream_class *stream_class,
187 const char *name, uint64_t id)
273b65be 188{
3dca2276
PP
189 int ret;
190 struct bt_stream *stream = NULL;
191 struct bt_trace *trace = NULL;
3230ee6b 192
3dca2276
PP
193 BT_LOGD("Creating stream object: stream-class-addr=%p, "
194 "stream-class-name=\"%s\", stream-name=\"%s\", "
195 "stream-id=%" PRIu64,
196 stream_class, bt_stream_class_get_name(stream_class),
197 name, id);
3230ee6b 198
3dca2276
PP
199 trace = BT_FROM_COMMON(bt_stream_class_common_borrow_trace(
200 BT_TO_COMMON(stream_class)));
201 if (!trace) {
202 BT_LOGW("Invalid parameter: cannot create stream from a stream class which is not part of trace: "
203 "stream-class-addr=%p, stream-class-name=\"%s\", "
204 "stream-name=\"%s\"",
205 stream_class, bt_stream_class_get_name(stream_class),
206 name);
207 goto error;
3230ee6b
PP
208 }
209
3dca2276 210 if (bt_trace_is_static(trace)) {
0686ef94 211 /*
3dca2276
PP
212 * A static trace has the property that all its stream
213 * classes, clock classes, and streams are definitive:
214 * no more can be added, and each object is also frozen.
0686ef94 215 */
3dca2276
PP
216 BT_LOGW("Invalid parameter: cannot create stream from a stream class which is part of a static trace: "
217 "stream-class-addr=%p, stream-class-name=\"%s\", "
218 "stream-name=\"%s\", trace-addr=%p",
219 stream_class, bt_stream_class_get_name(stream_class),
220 name, trace);
221 goto error;
9f56e450 222 }
12c8a1a3 223
3dca2276
PP
224 stream = g_new0(struct bt_stream, 1);
225 if (!stream) {
226 BT_LOGE_STR("Failed to allocate one stream.");
227 goto error;
12c8a1a3 228 }
b71d7298 229
3dca2276
PP
230 ret = bt_stream_common_initialize(BT_TO_COMMON(stream),
231 BT_TO_COMMON(stream_class), name, id, bt_stream_destroy);
232 if (ret) {
233 /* bt_stream_common_initialize() logs errors */
234 goto error;
b71d7298 235 }
41ac640a 236
312c056a
PP
237 ret = bt_object_pool_initialize(&stream->packet_pool,
238 (bt_object_pool_new_object_func) bt_packet_new,
239 (bt_object_pool_destroy_object_func) bt_stream_free_packet,
240 stream);
241 if (ret) {
242 BT_LOGE("Failed to initialize packet pool: ret=%d", ret);
243 goto error;
244 }
245
3dca2276
PP
246 g_ptr_array_add(trace->common.streams, stream);
247 BT_LOGD("Created stream object: addr=%p", stream);
248 goto end;
3230ee6b 249
3dca2276
PP
250error:
251 BT_PUT(stream);
252
253end:
254 return stream;
273b65be
JG
255}
256
3dca2276
PP
257struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class,
258 const char *name, uint64_t id_param)
273b65be 259{
3dca2276
PP
260 struct bt_stream *stream = NULL;
261 int64_t id = (int64_t) id_param;
273b65be 262
3dca2276
PP
263 if (!stream_class) {
264 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
12c8a1a3
JG
265 goto end;
266 }
267
3dca2276
PP
268 if (id < 0) {
269 BT_LOGW("Invalid parameter: invalid stream's ID: "
270 "name=\"%s\", id=%" PRIu64,
271 name, id_param);
12c8a1a3
JG
272 goto end;
273 }
274
3dca2276
PP
275 stream = bt_stream_create_with_id_no_check(stream_class,
276 name, id_param);
d7b1ea66 277
273b65be 278end:
3dca2276 279 return stream;
273b65be 280}
b71d7298 281
094ff7c0 282struct bt_stream_class *bt_stream_borrow_class(struct bt_stream *stream)
af9296f3 283{
094ff7c0 284 return BT_FROM_COMMON(bt_stream_common_borrow_class(BT_TO_COMMON(stream)));
af9296f3
JG
285}
286
50842bdc 287const char *bt_stream_get_name(struct bt_stream *stream)
b71d7298 288{
3dca2276 289 return bt_stream_common_get_name(BT_TO_COMMON(stream));
b71d7298 290}
98a4cbef 291
3dca2276 292int64_t bt_stream_get_id(struct bt_stream *stream)
98a4cbef 293{
3dca2276 294 return bt_stream_common_get_id(BT_TO_COMMON(stream));
98a4cbef 295}
3230ee6b 296
3230ee6b 297BT_HIDDEN
3dca2276
PP
298void bt_stream_common_add_destroy_listener(struct bt_stream_common *stream,
299 bt_stream_common_destroy_listener_func func, void *data)
3230ee6b 300{
3dca2276 301 struct bt_stream_common_destroy_listener listener;
3230ee6b 302
f6ccaed9
PP
303 BT_ASSERT(stream);
304 BT_ASSERT(func);
3230ee6b
PP
305 listener.func = func;
306 listener.data = data;
307 g_array_append_val(stream->destroy_listeners, listener);
19abc2c6
PP
308 BT_LOGV("Added stream destroy listener: stream-addr=%p, "
309 "stream-name=\"%s\", func=%p, data=%p",
3dca2276 310 stream, bt_stream_common_get_name(stream), func, data);
3230ee6b
PP
311}
312
313BT_HIDDEN
3dca2276
PP
314void bt_stream_common_remove_destroy_listener(struct bt_stream_common *stream,
315 bt_stream_common_destroy_listener_func func, void *data)
3230ee6b
PP
316{
317 size_t i;
318
f6ccaed9
PP
319 BT_ASSERT(stream);
320 BT_ASSERT(func);
3230ee6b
PP
321
322 for (i = 0; i < stream->destroy_listeners->len; i++) {
3dca2276 323 struct bt_stream_common_destroy_listener *listener =
3230ee6b 324 &g_array_index(stream->destroy_listeners,
3dca2276 325 struct bt_stream_common_destroy_listener, i);
3230ee6b
PP
326
327 if (listener->func == func && listener->data == data) {
328 g_array_remove_index(stream->destroy_listeners, i);
329 i--;
19abc2c6
PP
330 BT_LOGV("Removed stream destroy listener: stream-addr=%p, "
331 "stream-name=\"%s\", func=%p, data=%p",
3dca2276 332 stream, bt_stream_common_get_name(stream),
19abc2c6 333 func, data);
3230ee6b
PP
334 }
335 }
336}
This page took 0.07085 seconds and 4 git commands to generate.