Cleanup: fix cppcheck warning
[babeltrace.git] / formats / ctf / callbacks.c
CommitLineData
6f3077a2
JD
1/*
2 * callbacks.c
3 *
4 * Babeltrace Library
5 *
6 * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
7 *
8 * Author: Mathieu Desnoyers <mathieu.desnoyers@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
21#include <babeltrace/babeltrace.h>
22#include <babeltrace/babeltrace-internal.h>
95d36295 23#include <babeltrace/context.h>
08c22d05 24#include <babeltrace/context-internal.h>
6f3077a2
JD
25#include <babeltrace/ctf-ir/metadata.h>
26#include <babeltrace/iterator-internal.h>
aacd0c69 27#include <babeltrace/ctf/events.h>
634d474b
MD
28#include <babeltrace/ctf/events-internal.h>
29#include <babeltrace/ctf/callbacks-internal.h>
6f3077a2
JD
30#include <inttypes.h>
31
32static
33struct bt_dependencies *_babeltrace_dependencies_create(const char *first,
34 va_list ap)
35{
36 const char *iter;
37 struct bt_dependencies *dep;
38
39 dep = g_new0(struct bt_dependencies, 1);
40 dep->refcount = 1;
41 dep->deps = g_array_new(FALSE, TRUE, sizeof(GQuark));
42 iter = first;
43 while (iter) {
44 GQuark q = g_quark_from_string(iter);
45 g_array_append_val(dep->deps, q);
46 iter = va_arg(ap, const char *);
47 }
48 return dep;
49}
50
51struct bt_dependencies *babeltrace_dependencies_create(const char *first, ...)
52{
53 va_list ap;
54 struct bt_dependencies *deps;
55
56 va_start(ap, first);
57 deps = _babeltrace_dependencies_create(first, ap);
58 va_end(ap);
59 return deps;
60}
61
62/*
634d474b 63 * bt_ctf_iter_add_callback: Add a callback to CTF iterator.
6f3077a2 64 */
634d474b 65int bt_ctf_iter_add_callback(struct bt_ctf_iter *iter,
34861b9d 66 bt_intern_str event, void *private_data, int flags,
c50d2a7a 67 enum bt_cb_ret (*callback)(struct bt_ctf_event *ctf_data,
6f3077a2
JD
68 void *private_data),
69 struct bt_dependencies *depends,
70 struct bt_dependencies *weak_depends,
71 struct bt_dependencies *provides)
72{
73 int i, stream_id;
74 gpointer *event_id_ptr;
75 unsigned long event_id;
7f89ddce 76 struct trace_collection *tc;
6f3077a2 77
7f89ddce
MD
78 if (!iter || !callback)
79 return -EINVAL;
80
81 tc = iter->parent.ctx->tc;
6f3077a2
JD
82 for (i = 0; i < tc->array->len; i++) {
83 struct ctf_trace *tin;
84 struct trace_descriptor *td_read;
85
86 td_read = g_ptr_array_index(tc->array, i);
87 tin = container_of(td_read, struct ctf_trace, parent);
88
89 for (stream_id = 0; stream_id < tin->streams->len; stream_id++) {
f380e105 90 struct ctf_stream_declaration *stream;
6f3077a2
JD
91 struct bt_stream_callbacks *bt_stream_cb = NULL;
92 struct bt_callback_chain *bt_chain = NULL;
93 struct bt_callback new_callback;
94
95 stream = g_ptr_array_index(tin->streams, stream_id);
96
97 if (stream_id >= iter->callbacks->len) {
98 g_array_set_size(iter->callbacks, stream->stream_id + 1);
99 }
100 bt_stream_cb = &g_array_index(iter->callbacks,
101 struct bt_stream_callbacks, stream->stream_id);
102 if (!bt_stream_cb->per_id_callbacks) {
103 bt_stream_cb->per_id_callbacks = g_array_new(FALSE, TRUE,
104 sizeof(struct bt_callback_chain));
105 }
106
107 if (event) {
108 /* find the event id */
109 event_id_ptr = g_hash_table_lookup(stream->event_quark_to_id,
110 (gconstpointer) (unsigned long) event);
111 /* event not found in this stream class */
112 if (!event_id_ptr) {
00607d51 113 fprintf(stderr, "[error] Event ID not found in stream class\n");
6f3077a2
JD
114 continue;
115 }
116 event_id = (uint64_t)(unsigned long) *event_id_ptr;
117
118 /* find or create the bt_callback_chain for this event */
119 if (event_id >= bt_stream_cb->per_id_callbacks->len) {
120 g_array_set_size(bt_stream_cb->per_id_callbacks, event_id + 1);
121 }
122 bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks,
123 struct bt_callback_chain, event_id);
124 if (!bt_chain->callback) {
125 bt_chain->callback = g_array_new(FALSE, TRUE,
126 sizeof(struct bt_callback));
127 }
128 } else {
129 /* callback for all events */
130 if (!iter->main_callbacks.callback) {
131 iter->main_callbacks.callback = g_array_new(FALSE, TRUE,
132 sizeof(struct bt_callback));
133 }
134 bt_chain = &iter->main_callbacks;
135 }
136
137 new_callback.private_data = private_data;
138 new_callback.flags = flags;
139 new_callback.callback = callback;
140 new_callback.depends = depends;
141 new_callback.weak_depends = weak_depends;
142 new_callback.provides = provides;
143
144 /* TODO : take care of priority, for now just FIFO */
145 g_array_append_val(bt_chain->callback, new_callback);
146 }
147 }
148
149 return 0;
150}
151
152static
c50d2a7a
JD
153int extract_ctf_stream_event(struct ctf_stream_definition *stream,
154 struct bt_ctf_event *event)
6f3077a2 155{
f380e105 156 struct ctf_stream_declaration *stream_class = stream->stream_class;
4716614a 157 struct ctf_event_declaration *event_class;
6f3077a2
JD
158 uint64_t id = stream->event_id;
159
160 if (id >= stream_class->events_by_id->len) {
3394d22e 161 fprintf(stderr, "[error] Event id %" PRIu64 " is outside range.\n", id);
c50d2a7a 162 return -1;
6f3077a2 163 }
c50d2a7a
JD
164 event->parent = g_ptr_array_index(stream->events_by_id, id);
165 if (!event->parent) {
3394d22e 166 fprintf(stderr, "[error] Event id %" PRIu64 " is unknown.\n", id);
c50d2a7a 167 return -1;
6f3077a2
JD
168 }
169 event_class = g_ptr_array_index(stream_class->events_by_id, id);
170 if (!event_class) {
3394d22e 171 fprintf(stderr, "[error] Event id %" PRIu64 " is unknown.\n", id);
c50d2a7a 172 return -1;
6f3077a2
JD
173 }
174
c50d2a7a 175 return 0;
6f3077a2
JD
176}
177
634d474b 178void process_callbacks(struct bt_ctf_iter *iter,
9e88d150 179 struct ctf_stream_definition *stream)
6f3077a2
JD
180{
181 struct bt_stream_callbacks *bt_stream_cb;
182 struct bt_callback_chain *bt_chain;
183 struct bt_callback *cb;
184 int i;
185 enum bt_cb_ret ret;
c50d2a7a 186 struct bt_ctf_event ctf_data;
6f3077a2 187
7f89ddce
MD
188 assert(iter && stream);
189
c50d2a7a 190 ret = extract_ctf_stream_event(stream, &ctf_data);
6f3077a2
JD
191
192 /* process all events callback first */
193 if (iter->main_callbacks.callback) {
194 for (i = 0; i < iter->main_callbacks.callback->len; i++) {
195 cb = &g_array_index(iter->main_callbacks.callback, struct bt_callback, i);
196 if (!cb)
197 goto end;
c50d2a7a 198 ret = cb->callback(&ctf_data, cb->private_data);
6f3077a2
JD
199 switch (ret) {
200 case BT_CB_OK_STOP:
201 case BT_CB_ERROR_STOP:
202 goto end;
203 default:
204 break;
205 }
206 }
207 }
208
209 /* process per event callbacks */
210 bt_stream_cb = &g_array_index(iter->callbacks,
211 struct bt_stream_callbacks, stream->stream_id);
212 if (!bt_stream_cb || !bt_stream_cb->per_id_callbacks)
213 goto end;
214
a91196c6 215 if (stream->event_id >= bt_stream_cb->per_id_callbacks->len)
6f3077a2
JD
216 goto end;
217 bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks,
218 struct bt_callback_chain, stream->event_id);
219 if (!bt_chain || !bt_chain->callback)
220 goto end;
221
222 for (i = 0; i < bt_chain->callback->len; i++) {
223 cb = &g_array_index(bt_chain->callback, struct bt_callback, i);
224 if (!cb)
225 goto end;
c50d2a7a 226 ret = cb->callback(&ctf_data, cb->private_data);
6f3077a2
JD
227 switch (ret) {
228 case BT_CB_OK_STOP:
229 case BT_CB_ERROR_STOP:
230 goto end;
231 default:
232 break;
233 }
234 }
235
236end:
237 return;
238}
This page took 0.033744 seconds and 4 git commands to generate.