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