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