update stop for event list
[lttv.git] / ltt / branches / poly / lttv / modules / gui / lttvwindow / lttvwindow / lttvwindowtraces.c
CommitLineData
a1a2b649 1/* This file is part of the Linux Trace Toolkit Graphic User Interface
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
19/* This file is the API used to launch any background computation on a trace */
20
21/* Here is the implementation of the API */
22
4e4d11b3 23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
0fdb8bb0 27#include <sys/types.h>
28#include <sys/stat.h>
29#include <unistd.h>
2eef04b5 30#include <string.h>
0fdb8bb0 31
a1a2b649 32#include <ltt/time.h>
33#include <ltt/trace.h>
34#include <glib.h>
35#include <lttv/lttv.h>
36#include <lttv/traceset.h>
37#include <lttv/attribute.h>
38#include <lttv/tracecontext.h>
39#include <lttvwindow/lttvwindowtraces.h>
8bc02ec8 40#include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
b5e17af5 41#include <lttvwindow/mainwindow-private.h> /* for main window structure */
a1a2b649 42
b5e17af5 43extern GSList * g_main_window_list;
a1a2b649 44
45typedef struct _BackgroundRequest {
46 LttvAttributeName module_name; /* Hook path in global attributes,
47 where all standard hooks under computation/.
48 i.e. modulename */
49 LttvTrace *trace; /* trace concerned */
93ac601b 50 GtkWidget *dialog; /* Dialog linked with the request, may be NULL */
b5e17af5 51 GtkWidget *parent_window; /* Parent window the dialog must be transient for */
a1a2b649 52} BackgroundRequest;
53
54typedef struct _BackgroundNotify {
55 gpointer owner;
56 LttvTrace *trace; /* trace */
57 LttTime notify_time;
58 LttvTracesetContextPosition *notify_position;
59 LttvHooks *notify; /* Hook to call when the notify is
60 passed, or at the end of trace */
61} BackgroundNotify;
62
63
64
313bd6fc 65/* Prototypes */
66gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace);
67
a1a2b649 68/* Get a trace by its path name.
69 *
70 * @param path path of the trace on the virtual file system.
71 * @return Pointer to trace if found
72 * NULL is returned if the trace is not present
73 */
74
75LttvTrace *lttvwindowtraces_get_trace_by_name(gchar *path)
76{
a1a2b649 77 guint i;
78
79 for(i=0;i<lttvwindowtraces_get_number();i++) {
80 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
81 LttTrace *trace;
82 gchar *name;
a1a2b649 83 g_assert(trace_v != NULL);
84
85 trace = lttv_trace(trace_v);
86 g_assert(trace != NULL);
d27948a3 87 name = g_quark_to_string(ltt_trace_name(trace));
a1a2b649 88
89 if(strcmp(name, path) == 0) {
90 /* Found */
91 return trace_v;
92 }
93 }
94
95 return NULL;
96}
97
98/* Get a trace by its number identifier */
99
100LttvTrace *lttvwindowtraces_get_trace(guint num)
101{
102 LttvAttribute *g_attribute = lttv_global_attributes();
103 LttvAttribute *attribute;
104 LttvAttributeType type;
105 LttvAttributeName name;
106 LttvAttributeValue value;
c0cb4d12 107 gboolean is_named;
a1a2b649 108
109 g_assert(attribute =
110 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
111 LTTV_TRACES)));
112
c0cb4d12 113 type = lttv_iattribute_get(LTTV_IATTRIBUTE(attribute), num, &name, &value,
114 &is_named);
a1a2b649 115
116 if(type == LTTV_POINTER) {
117 return (LttvTrace *)*(value.v_pointer);
118 }
119
120 return NULL;
121}
122
123/* Total number of traces */
124
125guint lttvwindowtraces_get_number()
126{
127 LttvAttribute *g_attribute = lttv_global_attributes();
128 LttvAttribute *attribute;
129 LttvAttributeValue value;
130
131 g_assert(attribute =
132 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
133 LTTV_TRACES)));
134
135 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute)) );
136}
137
138/* Add a trace to the global attributes */
139
140void lttvwindowtraces_add_trace(LttvTrace *trace)
141{
142 LttvAttribute *g_attribute = lttv_global_attributes();
143 LttvAttribute *attribute;
144 LttvAttributeValue value;
145 guint num;
0fdb8bb0 146 struct stat buf;
147 gchar attribute_path[PATH_MAX];
a1a2b649 148
23bb9b6b 149 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace))), &buf)) {
0fdb8bb0 150 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
23bb9b6b 151 g_quark_to_string(ltt_trace_name(lttv_trace(trace))));
0fdb8bb0 152 return;
153 }
154 g_assert(
23bb9b6b 155 snprintf(attribute_path, PATH_MAX, "%llu:%llu", buf.st_dev, buf.st_ino) >= 0);
0fdb8bb0 156
a1a2b649 157 g_assert(attribute =
158 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
159 LTTV_TRACES)));
0fdb8bb0 160
a1a2b649 161 value = lttv_attribute_add(attribute,
0fdb8bb0 162 g_quark_from_string(attribute_path),
a1a2b649 163 LTTV_POINTER);
164
165 *(value.v_pointer) = (gpointer)trace;
8bc02ec8 166
167 /* create new traceset and tracesetcontext */
168 LttvTraceset *ts;
313bd6fc 169 LttvTracesetStats *tss;
088f6772 170 //LttvTracesetContextPosition *sync_position;
8bc02ec8 171
172 attribute = lttv_trace_attribute(trace);
173 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
174 LTTV_COMPUTATION_TRACESET,
175 LTTV_POINTER,
176 &value));
177 ts = lttv_traceset_new();
178 *(value.v_pointer) = ts;
179
180 lttv_traceset_add(ts,trace);
181
182 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
183 LTTV_COMPUTATION_TRACESET_CONTEXT,
184 LTTV_POINTER,
185 &value));
313bd6fc 186 tss = g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
187 *(value.v_pointer) = tss;
8bc02ec8 188
313bd6fc 189 lttv_context_init(LTTV_TRACESET_CONTEXT(tss), ts);
088f6772 190#if 0
79257ba5 191 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
192 LTTV_COMPUTATION_SYNC_POSITION,
193 LTTV_POINTER,
194 &value));
195
196 sync_position = lttv_traceset_context_position_new();
197 *(value.v_pointer) = sync_position;
088f6772 198#endif //0
8bc02ec8 199 value = lttv_attribute_add(attribute,
200 LTTV_REQUESTS_QUEUE,
201 LTTV_POINTER);
202
203 value = lttv_attribute_add(attribute,
204 LTTV_REQUESTS_CURRENT,
205 LTTV_POINTER);
206
207 value = lttv_attribute_add(attribute,
208 LTTV_NOTIFY_QUEUE,
209 LTTV_POINTER);
210
211 value = lttv_attribute_add(attribute,
212 LTTV_NOTIFY_CURRENT,
213 LTTV_POINTER);
214
a1a2b649 215}
216
217/* Remove a trace from the global attributes */
218
219void lttvwindowtraces_remove_trace(LttvTrace *trace)
220{
221 LttvAttribute *g_attribute = lttv_global_attributes();
222 LttvAttribute *attribute;
223 LttvAttributeValue value;
224 guint i;
225
226 g_assert(attribute =
227 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
228 LTTV_TRACES)));
229
230 for(i=0;i<lttvwindowtraces_get_number();i++) {
231 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
232
233 g_assert(trace_v != NULL);
234
b052368a 235 /* Remove and background computation that could be in progress */
236 g_idle_remove_by_data(trace_v);
237
a1a2b649 238 if(trace_v == trace) {
239 /* Found */
8bc02ec8 240 LttvAttribute *l_attribute;
241
23bb9b6b 242 /* destroy traceset and tracesetcontext */
8bc02ec8 243 LttvTraceset *ts;
313bd6fc 244 LttvTracesetStats *tss;
088f6772 245 //LttvTracesetContextPosition *sync_position;
8bc02ec8 246
247 l_attribute = lttv_trace_attribute(trace);
248
249
250 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
251 LTTV_REQUESTS_QUEUE);
252
253 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
254 LTTV_REQUESTS_CURRENT);
255
256 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
257 LTTV_NOTIFY_QUEUE);
258
259 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
260 LTTV_NOTIFY_CURRENT);
261
262 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
263 LTTV_COMPUTATION_TRACESET,
264 LTTV_POINTER,
265 &value));
266 ts = (LttvTraceset*)*(value.v_pointer);
088f6772 267#if 0
79257ba5 268 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
269 LTTV_COMPUTATION_SYNC_POSITION,
270 LTTV_POINTER,
271 &value));
272 sync_position = (LttvTracesetContextPosition*)*(value.v_pointer);
79257ba5 273 lttv_traceset_context_position_destroy(sync_position);
274
275 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
276 LTTV_COMPUTATION_SYNC_POSITION);
277
088f6772 278#endif //0
8bc02ec8 279 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
280 LTTV_COMPUTATION_TRACESET_CONTEXT,
281 LTTV_POINTER,
282 &value));
313bd6fc 283 tss = (LttvTracesetStats*)*(value.v_pointer);
8bc02ec8 284
313bd6fc 285 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss));
286 g_object_unref(tss);
8bc02ec8 287 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
288 LTTV_COMPUTATION_TRACESET_CONTEXT);
8bc02ec8 289 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
290 LTTV_COMPUTATION_TRACESET);
1ba187d3 291 /* Destroy the traceset and the trace also */
292 lttv_traceset_destroy(ts);
8bc02ec8 293
294 /* finally, remove the global attribute */
a1a2b649 295 lttv_attribute_remove(attribute, i);
8bc02ec8 296
a1a2b649 297 return;
298 }
299 }
300}
301
93ac601b 302static void destroy_dialog(BackgroundRequest *bg_req)
303{
304 gtk_widget_destroy(bg_req->dialog);
305 bg_req->dialog = NULL;
306}
307
a1a2b649 308
309/**
310 * Function to request data from a specific trace
311 *
312 * The memory allocated for the request will be managed by the API.
313 *
b5e17af5 314 * @param widget the current Window
a1a2b649 315 * @param trace the trace to compute
316 * @param module_name the name of the module which registered global computation
317 * hooks.
318 */
319
320void lttvwindowtraces_background_request_queue
b5e17af5 321 (GtkWidget *widget, LttvTrace *trace, gchar *module_name)
a1a2b649 322{
323 BackgroundRequest *bg_req;
324 LttvAttribute *attribute = lttv_trace_attribute(trace);
91fd6881 325 LttvAttribute *g_attribute = lttv_global_attributes();
326 LttvAttribute *module_attribute;
a1a2b649 327 LttvAttributeValue value;
91fd6881 328 LttvAttributeType type;
a1a2b649 329 GSList **slist;
330 guint num;
331
332 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
333 LTTV_REQUESTS_QUEUE,
334 LTTV_POINTER,
335 &value));
336 slist = (GSList**)(value.v_pointer);
91fd6881 337
338 /* Verify that the calculator is loaded */
339 g_assert(module_attribute =
340 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
341 LTTV_COMPUTATION)));
342
343
344 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
345 g_quark_from_string(module_name),
346 &value);
347 if(type == LTTV_NONE) {
348 g_critical("Missing background calculator %s", module_name);
349 return;
350 }
351
a1a2b649 352 bg_req = g_new(BackgroundRequest,1);
353 bg_req->module_name = g_quark_from_string(module_name);
354 bg_req->trace = trace;
355
356 *slist = g_slist_append(*slist, bg_req);
313bd6fc 357
358 /* Priority lower than live servicing */
359 g_idle_remove_by_data(trace);
360 g_idle_add_full((G_PRIORITY_HIGH_IDLE + 23),
361 (GSourceFunc)lttvwindowtraces_process_pending_requests,
362 trace,
363 NULL);
b052368a 364 /* FIXME : show message in status bar, need context and message id */
93ac601b 365 g_info("Background computation for %s started for trace %p", module_name,
366 trace);
367 GtkWidget *dialog =
b5e17af5 368 gtk_message_dialog_new(
369 GTK_WINDOW(widget),
370 GTK_DIALOG_DESTROY_WITH_PARENT,
371 GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
93ac601b 372 "Background computation for %s started for trace %s",
373 module_name,
374 g_quark_to_string(ltt_trace_name(lttv_trace(trace))));
b5e17af5 375 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(widget));
93ac601b 376 g_signal_connect_swapped (dialog, "response",
377 G_CALLBACK (destroy_dialog),
378 bg_req);
379 bg_req->dialog = dialog;
b5e17af5 380 /* the parent window might vanish : only use this pointer for a
381 * comparison with existing windows */
382 bg_req->parent_window = gtk_widget_get_toplevel(widget);
93ac601b 383 gtk_widget_show(dialog);
a1a2b649 384}
385
386/**
387 * Remove a background request from a trace.
388 *
389 * This should ONLY be used by the modules which registered the global hooks
390 * (module_name). If this is called by the viewers, it may lead to incomplete
391 * and incoherent background processing information.
392 *
393 * Even if the module which deals with the hooks removes the background
394 * requests, it may cause a problem if the module gets loaded again in the
395 * session : the data will be partially calculated. The calculation function
396 * must deal with this case correctly.
397 *
398 * @param trace the trace to compute
399 * @param module_name the name of the module which registered global computation
400 * hooks.
401 */
402
403void lttvwindowtraces_background_request_remove
404 (LttvTrace *trace, gchar *module_name)
405{
406 LttvAttribute *attribute = lttv_trace_attribute(trace);
407 LttvAttributeValue value;
408 GSList *iter = NULL;
409 GSList **slist;
410
411 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
412 LTTV_REQUESTS_QUEUE,
413 LTTV_POINTER,
414 &value));
415 slist = (GSList**)(value.v_pointer);
416
417 for(iter=*slist;iter!=NULL;) {
418 BackgroundRequest *bg_req =
419 (BackgroundRequest *)iter->data;
420
421 if(bg_req->module_name == g_quark_from_string(module_name)) {
422 GSList *rem_iter = iter;
423 iter=g_slist_next(iter);
424 g_free(bg_req);
425 *slist = g_slist_delete_link(*slist, rem_iter);
426 } else {
427 iter=g_slist_next(iter);
428 }
429 }
430}
431
93ac601b 432/**
433 * Find a background request in a trace
434 *
435 */
436
437gboolean lttvwindowtraces_background_request_find
438 (LttvTrace *trace, gchar *module_name)
439{
440 LttvAttribute *attribute = lttv_trace_attribute(trace);
441 LttvAttributeValue value;
442 GSList *iter = NULL;
443 GSList **slist;
444
445 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
446 LTTV_REQUESTS_QUEUE,
447 LTTV_POINTER,
448 &value));
449 slist = (GSList**)(value.v_pointer);
450
451 for(iter=*slist;iter!=NULL;) {
452 BackgroundRequest *bg_req =
453 (BackgroundRequest *)iter->data;
454
455 if(bg_req->module_name == g_quark_from_string(module_name)) {
456 return TRUE;
457 } else {
458 iter=g_slist_next(iter);
459 }
460 }
461 return FALSE;
462}
a1a2b649 463
464/**
465 * Register a callback to be called when requested data is passed in the next
466 * queued background processing.
467 *
468 * @param owner owner of the background notification
469 * @param trace the trace computed
470 * @param notify_time time when notification hooks must be called
471 * @param notify_position position when notification hooks must be called
472 * @param notify Hook to call when the notify position is passed
473 */
474
475void lttvwindowtraces_background_notify_queue
476 (gpointer owner,
477 LttvTrace *trace,
478 LttTime notify_time,
479 const LttvTracesetContextPosition *notify_position,
480 const LttvHooks *notify)
481{
482 BackgroundNotify *bg_notify;
483 LttvAttribute *attribute = lttv_trace_attribute(trace);
484 LttvAttributeValue value;
485 GSList **slist;
486
487 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
488 LTTV_NOTIFY_QUEUE,
489 LTTV_POINTER,
490 &value));
491 slist = (GSList**)(value.v_pointer);
492
8e680509 493 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
494 LTTV_COMPUTATION_TRACESET_CONTEXT,
495 LTTV_POINTER,
496 &value));
497 LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
a1a2b649 498
499 bg_notify = g_new(BackgroundNotify,1);
500
501 bg_notify->owner = owner;
502 bg_notify->trace = trace;
503 bg_notify->notify_time = notify_time;
313bd6fc 504 if(notify_position != NULL) {
8e680509 505 bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
313bd6fc 506 lttv_traceset_context_position_copy(bg_notify->notify_position,
507 notify_position);
508 } else {
509 bg_notify->notify_position = NULL;
510 }
511
a1a2b649 512 bg_notify->notify = lttv_hooks_new();
513 lttv_hooks_add_list(bg_notify->notify, notify);
514
515 *slist = g_slist_append(*slist, bg_notify);
516}
517
518/**
519 * Register a callback to be called when requested data is passed in the current
520 * background processing.
521 *
522 * @param owner owner of the background notification
523 * @param trace the trace computed
524 * @param notify_time time when notification hooks must be called
525 * @param notify_position position when notification hooks must be called
526 * @param notify Hook to call when the notify position is passed
527 */
528
529void lttvwindowtraces_background_notify_current
530 (gpointer owner,
531 LttvTrace *trace,
532 LttTime notify_time,
533 const LttvTracesetContextPosition *notify_position,
534 const LttvHooks *notify)
535{
536 BackgroundNotify *bg_notify;
537 LttvAttribute *attribute = lttv_trace_attribute(trace);
538 LttvAttributeValue value;
539 GSList **slist;
540
541 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
542 LTTV_NOTIFY_CURRENT,
543 LTTV_POINTER,
544 &value));
545 slist = (GSList**)(value.v_pointer);
546
8e680509 547 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
548 LTTV_COMPUTATION_TRACESET_CONTEXT,
549 LTTV_POINTER,
550 &value));
551 LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
552
553
a1a2b649 554 bg_notify = g_new(BackgroundNotify,1);
555
556 bg_notify->owner = owner;
557 bg_notify->trace = trace;
558 bg_notify->notify_time = notify_time;
313bd6fc 559 if(notify_position!= NULL) {
8e680509 560 bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
313bd6fc 561 lttv_traceset_context_position_copy(bg_notify->notify_position,
562 notify_position);
563 } else {
564 bg_notify->notify_position = NULL;
565 }
a1a2b649 566 bg_notify->notify = lttv_hooks_new();
567 lttv_hooks_add_list(bg_notify->notify, notify);
568
569 *slist = g_slist_append(*slist, bg_notify);
570}
571
b052368a 572
573static void notify_request_free(BackgroundNotify *notify_req)
574{
575 if(notify_req == NULL) return;
576
577 if(notify_req->notify_position != NULL)
578 lttv_traceset_context_position_destroy(notify_req->notify_position);
579 if(notify_req->notify != NULL)
580 lttv_hooks_destroy(notify_req->notify);
581 g_free(notify_req);
582}
583
a1a2b649 584/**
585 * Removes all the notifications requests from a specific viewer.
586 *
587 * @param owner owner of the background notification
588 */
589
590void lttvwindowtraces_background_notify_remove(gpointer owner)
591{
592 guint i;
593
594 for(i=0;i<lttvwindowtraces_get_number();i++) {
595 LttvAttribute *attribute;
596 LttvAttributeValue value;
597 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
598 GSList **slist;
599 GSList *iter = NULL;
600
601 g_assert(trace_v != NULL);
602
b052368a 603 attribute = lttv_trace_attribute(trace_v);
a1a2b649 604
605 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
606 LTTV_NOTIFY_QUEUE,
607 LTTV_POINTER,
608 &value));
609 slist = (GSList**)(value.v_pointer);
610
611 for(iter=*slist;iter!=NULL;) {
612
613 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
614
615 if(bg_notify->owner == owner) {
616 GSList *rem_iter = iter;
617 iter=g_slist_next(iter);
b052368a 618 notify_request_free(bg_notify);
619 *slist = g_slist_remove_link(*slist, rem_iter);
a1a2b649 620 } else {
621 iter=g_slist_next(iter);
622 }
623 }
624
625 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
626 LTTV_NOTIFY_CURRENT,
627 LTTV_POINTER,
628 &value));
629 slist = (GSList**)(value.v_pointer);
630
631 for(iter=*slist;iter!=NULL;) {
632
633 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
634
635 if(bg_notify->owner == owner) {
636 GSList *rem_iter = iter;
637 iter=g_slist_next(iter);
b052368a 638 notify_request_free(bg_notify);
639 *slist = g_slist_remove_link(*slist, rem_iter);
a1a2b649 640 } else {
641 iter=g_slist_next(iter);
642 }
643 }
644 }
645}
646
8bc02ec8 647
648/* Background processing helper functions */
649
650void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name,
1ce324c6 651 LttvTracesetContext *tsc,
652 LttvHooks *hook_adder)
8bc02ec8 653{
654 LttvAttribute *g_attribute = lttv_global_attributes();
655 LttvAttribute *module_attribute;
656 LttvAttributeType type;
657 LttvAttributeValue value;
088f6772 658
659
660 g_assert(module_attribute =
661 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
662 LTTV_COMPUTATION)));
663
664 g_assert(module_attribute =
665 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
666 LTTV_IATTRIBUTE(module_attribute),
667 module_name)));
668
669 /* Call the module's hook adder */
670 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
671 LTTV_HOOK_ADDER,
672 &value);
673 if(type == LTTV_POINTER) {
674 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
675 if(hook_adder != NULL)
676 lttv_hooks_add_list(hook_adder, (LttvHooks*)*(value.v_pointer));
677 }
678}
679
680void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name,
681 LttvTracesetContext *tsc,
682 LttvHooks *hook_remover)
683{
684 LttvAttribute *g_attribute = lttv_global_attributes();
685 LttvAttribute *module_attribute;
686 LttvAttributeType type;
687 LttvAttributeValue value;
688
689 g_assert(module_attribute =
690 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
691 LTTV_COMPUTATION)));
692
693 g_assert(module_attribute =
694 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
695 LTTV_IATTRIBUTE(module_attribute),
696 module_name)));
697
698 /* Call the module's hook remover */
699 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
700 LTTV_HOOK_REMOVER,
701 &value);
702 if(type == LTTV_POINTER) {
703 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
704 if(hook_remover != NULL)
705 lttv_hooks_add_list(hook_remover, (LttvHooks*)*(value.v_pointer));
706 }
707}
708
709void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name,
710 LttvTracesetContext *tsc)
711{
712 LttvAttribute *g_attribute = lttv_global_attributes();
713 LttvAttribute *module_attribute;
714 LttvAttributeType type;
715 LttvAttributeValue value;
8bc02ec8 716 LttvHooks *before_chunk_traceset=NULL;
717 LttvHooks *before_chunk_trace=NULL;
718 LttvHooks *before_chunk_tracefile=NULL;
719 LttvHooks *event_hook=NULL;
720 LttvHooksById *event_hook_by_id=NULL;
313bd6fc 721 LttvTracesetStats *tss = LTTV_TRACESET_STATS(tsc);
8bc02ec8 722
723
724 g_assert(module_attribute =
725 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
726 LTTV_COMPUTATION)));
727
728 g_assert(module_attribute =
729 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
730 LTTV_IATTRIBUTE(module_attribute),
731 module_name)));
732
733 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
734 LTTV_BEFORE_CHUNK_TRACESET,
735 &value);
736 if(type == LTTV_POINTER) {
737 before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
738 }
739
740 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
741 LTTV_BEFORE_CHUNK_TRACE,
742 &value);
743 if(type == LTTV_POINTER) {
744 before_chunk_trace = (LttvHooks*)*(value.v_pointer);
745 }
746
747 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
748 LTTV_BEFORE_CHUNK_TRACEFILE,
749 &value);
750 if(type == LTTV_POINTER) {
751 before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
752 }
753
754 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
755 LTTV_EVENT_HOOK,
756 &value);
757 if(type == LTTV_POINTER) {
758 event_hook = (LttvHooks*)*(value.v_pointer);
759 }
760
761 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
762 LTTV_EVENT_HOOK_BY_ID,
763 &value);
764 if(type == LTTV_POINTER) {
765 event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
766 }
767
8bc02ec8 768 lttv_process_traceset_begin(tsc,
769 before_chunk_traceset,
770 before_chunk_trace,
771 before_chunk_tracefile,
772 event_hook,
773 event_hook_by_id);
8bc02ec8 774}
088f6772 775
776
777
778void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name,
779 LttvTracesetContext *tsc)
8bc02ec8 780{
781 LttvAttribute *g_attribute = lttv_global_attributes();
782 LttvAttribute *module_attribute;
783 LttvAttributeType type;
784 LttvAttributeValue value;
785 LttvHooks *after_chunk_traceset=NULL;
786 LttvHooks *after_chunk_trace=NULL;
787 LttvHooks *after_chunk_tracefile=NULL;
788 LttvHooks *event_hook=NULL;
789 LttvHooksById *event_hook_by_id=NULL;
313bd6fc 790 LttvTracesetStats *tss = LTTV_TRACESET_STATS(tsc);
8bc02ec8 791
792 g_assert(module_attribute =
793 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
794 LTTV_COMPUTATION)));
795
796 g_assert(module_attribute =
797 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
798 LTTV_IATTRIBUTE(module_attribute),
799 module_name)));
800
801 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
802 LTTV_AFTER_CHUNK_TRACESET,
803 &value);
804 if(type == LTTV_POINTER) {
805 after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
806 }
807
808 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
809 LTTV_AFTER_CHUNK_TRACE,
810 &value);
811 if(type == LTTV_POINTER) {
812 after_chunk_trace = (LttvHooks*)*(value.v_pointer);
813 }
814
815 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
816 LTTV_AFTER_CHUNK_TRACEFILE,
817 &value);
818 if(type == LTTV_POINTER) {
819 after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
820 }
821
822 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
823 LTTV_EVENT_HOOK,
824 &value);
825 if(type == LTTV_POINTER) {
826 event_hook = (LttvHooks*)*(value.v_pointer);
827 }
828
829 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
830 LTTV_EVENT_HOOK_BY_ID,
831 &value);
832 if(type == LTTV_POINTER) {
833 event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
834 }
313bd6fc 835
8bc02ec8 836 lttv_process_traceset_end(tsc,
837 after_chunk_traceset,
838 after_chunk_trace,
839 after_chunk_tracefile,
840 event_hook,
841 event_hook_by_id);
313bd6fc 842
8bc02ec8 843}
844
845
846void lttvwindowtraces_set_in_progress(LttvAttributeName module_name,
847 LttvTrace *trace)
848{
849 LttvAttribute *attribute = lttv_trace_attribute(trace);
850 LttvAttributeValue value;
851
852 g_assert(attribute =
853 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
854 module_name)));
855
856 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
857 LTTV_IN_PROGRESS,
858 LTTV_INT);
859 /* the value is left unset. The only presence of the attribute is necessary.
860 */
861}
862
863void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name,
864 LttvTrace *trace)
865{
866 LttvAttribute *attribute = lttv_trace_attribute(trace);
867
868 g_assert(attribute =
869 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
870 module_name)));
871
313bd6fc 872 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
8bc02ec8 873 LTTV_IN_PROGRESS);
874}
875
876gboolean lttvwindowtraces_get_in_progress(LttvAttributeName module_name,
877 LttvTrace *trace)
878{
879 LttvAttribute *attribute = lttv_trace_attribute(trace);
880 LttvAttributeType type;
881 LttvAttributeValue value;
882
883 g_assert(attribute =
884 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
885 module_name)));
886
887 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
888 LTTV_IN_PROGRESS,
889 &value);
890 /* The only presence of the attribute is necessary. */
891 if(type == LTTV_NONE)
892 return FALSE;
893 else
894 return TRUE;
895}
896
897void lttvwindowtraces_set_ready(LttvAttributeName module_name,
898 LttvTrace *trace)
899{
900 LttvAttribute *attribute = lttv_trace_attribute(trace);
901 LttvAttributeValue value;
902
903 g_assert(attribute =
904 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
905 module_name)));
906
907 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
908 LTTV_READY,
909 LTTV_INT);
910 /* the value is left unset. The only presence of the attribute is necessary.
911 */
912}
913
914void lttvwindowtraces_unset_ready(LttvAttributeName module_name,
915 LttvTrace *trace)
916{
917 LttvAttribute *attribute = lttv_trace_attribute(trace);
918
919 g_assert(attribute =
920 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
921 module_name)));
922
313bd6fc 923 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
8bc02ec8 924 LTTV_READY);
925}
926
927gboolean lttvwindowtraces_get_ready(LttvAttributeName module_name,
928 LttvTrace *trace)
929{
930 LttvAttribute *attribute = lttv_trace_attribute(trace);
931 LttvAttributeType type;
932 LttvAttributeValue value;
933
934 g_assert(attribute =
935 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
936 module_name)));
937
938 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
939 LTTV_READY,
940 &value);
941 /* The only presence of the attribute is necessary. */
942 if(type == LTTV_NONE)
943 return FALSE;
944 else
945 return TRUE;
946}
947
b5e17af5 948static gint find_window_widget(MainWindow *a, GtkWidget *b)
949{
950 if(a->mwindow == b) return 0;
951 else return -1;
952}
953
8bc02ec8 954
8bc02ec8 955/* lttvwindowtraces_process_pending_requests
956 *
957 * This internal function gets called by g_idle, taking care of the pending
958 * requests.
959 *
960 */
961
962
963gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace)
964{
965 LttvTracesetContext *tsc;
313bd6fc 966 LttvTracesetStats *tss;
8bc02ec8 967 LttvTraceset *ts;
088f6772 968 //LttvTracesetContextPosition *sync_position;
8bc02ec8 969 LttvAttribute *attribute;
91fd6881 970 LttvAttribute *g_attribute = lttv_global_attributes();
313bd6fc 971 GSList **list_out, **list_in, **notify_in, **notify_out;
8bc02ec8 972 LttvAttributeValue value;
973 LttvAttributeType type;
b052368a 974 gboolean ret_val;
8bc02ec8 975
313bd6fc 976 if(trace == NULL)
8bc02ec8 977 return FALSE;
3c456a8a 978
979 if(lttvwindow_preempt_count > 0) return TRUE;
8bc02ec8 980
981 attribute = lttv_trace_attribute(trace);
982
983 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
984 LTTV_REQUESTS_QUEUE,
985 &value);
986 g_assert(type == LTTV_POINTER);
313bd6fc 987 list_out = (GSList**)(value.v_pointer);
8bc02ec8 988
989 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
990 LTTV_REQUESTS_CURRENT,
991 &value);
992 g_assert(type == LTTV_POINTER);
313bd6fc 993 list_in = (GSList**)(value.v_pointer);
8bc02ec8 994
995 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
996 LTTV_NOTIFY_QUEUE,
997 &value);
998 g_assert(type == LTTV_POINTER);
313bd6fc 999 notify_out = (GSList**)(value.v_pointer);
8bc02ec8 1000
1001 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1002 LTTV_NOTIFY_CURRENT,
1003 &value);
1004 g_assert(type == LTTV_POINTER);
313bd6fc 1005 notify_in = (GSList**)(value.v_pointer);
8bc02ec8 1006
1007 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1008 LTTV_COMPUTATION_TRACESET,
1009 &value);
1010 g_assert(type == LTTV_POINTER);
1011 ts = (LttvTraceset*)*(value.v_pointer);
1012
1013 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1014 LTTV_COMPUTATION_TRACESET_CONTEXT,
1015 &value);
1016 g_assert(type == LTTV_POINTER);
1017 tsc = (LttvTracesetContext*)*(value.v_pointer);
313bd6fc 1018 tss = (LttvTracesetStats*)*(value.v_pointer);
8bc02ec8 1019 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc));
313bd6fc 1020 g_assert(LTTV_IS_TRACESET_STATS(tss));
088f6772 1021#if 0
79257ba5 1022 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1023 LTTV_COMPUTATION_SYNC_POSITION,
1024 &value);
1025 g_assert(type == LTTV_POINTER);
1026 sync_position = (LttvTracesetContextPosition*)*(value.v_pointer);
088f6772 1027#endif //0
8bc02ec8 1028 /* There is no events requests pending : we should never have been called! */
313bd6fc 1029 g_assert(g_slist_length(*list_out) != 0 || g_slist_length(*list_in) != 0);
b052368a 1030 /* 0.1 Lock traces */
1031 {
1032 guint iter_trace=0;
1033
1034 for(iter_trace=0;
1035 iter_trace<lttv_traceset_number(tsc->ts);
1036 iter_trace++) {
1037 LttvTrace *trace_v = lttv_traceset_get(tsc->ts,iter_trace);
1038
1039 if(lttvwindowtraces_lock(trace_v) != 0)
1040 return TRUE; /* Cannot get trace lock, try later */
8bc02ec8 1041
b052368a 1042 }
1043 }
1044 /* 0.2 Sync tracefiles */
088f6772 1045 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1046 lttv_process_traceset_synchronize_tracefiles(tsc);
8bc02ec8 1047 /* 1. Before processing */
1048 {
1049 /* if list_in is empty */
313bd6fc 1050 if(g_slist_length(*list_in) == 0) {
8bc02ec8 1051
1052 {
1053 /* - Add all requests in list_out to list_in, empty list_out */
313bd6fc 1054 GSList *iter = *list_out;
8bc02ec8 1055
1056 while(iter != NULL) {
1057 gboolean remove = FALSE;
1058 gboolean free_data = FALSE;
1059
1060 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1061
1062 remove = TRUE;
1063 free_data = FALSE;
313bd6fc 1064 *list_in = g_slist_append(*list_in, bg_req);
8bc02ec8 1065
1066 /* Go to next */
1067 if(remove)
1068 {
1069 GSList *remove_iter = iter;
1070
1071 iter = g_slist_next(iter);
1072 if(free_data) g_free(remove_iter->data);
313bd6fc 1073 *list_out = g_slist_remove_link(*list_out, remove_iter);
8bc02ec8 1074 } else { // not remove
1075 iter = g_slist_next(iter);
1076 }
1077 }
1078 }
1079
1080 {
313bd6fc 1081 GSList *iter = *list_in;
8bc02ec8 1082 /* - for each request in list_in */
1083 while(iter != NULL) {
1084
1085 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
91fd6881 1086 /* - set hooks'in_progress flag to TRUE */
8bc02ec8 1087 lttvwindowtraces_set_in_progress(bg_req->module_name,
1088 bg_req->trace);
91fd6881 1089
1090 /* - call before request hook */
1091 /* Get before request hook */
1092 LttvAttribute *module_attribute;
1093
1094 g_assert(module_attribute =
1095 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1096 LTTV_IATTRIBUTE(g_attribute),
1097 LTTV_COMPUTATION)));
1098
1099 g_assert(module_attribute =
1100 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1101 LTTV_IATTRIBUTE(module_attribute),
1102 bg_req->module_name)));
1103
1104 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1105 LTTV_BEFORE_REQUEST,
1106 &value);
1107 g_assert(type == LTTV_POINTER);
1108 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
91fd6881 1109
1110 if(before_request != NULL) lttv_hooks_call(before_request, tsc);
8bc02ec8 1111
1112 iter = g_slist_next(iter);
1113 }
1114 }
1115
1116 /* - seek trace to start */
1117 {
1118 LttTime start = { 0, 0};
1119 lttv_process_traceset_seek_time(tsc, start);
1120 }
1121
1122 /* - Move all notifications from notify_out to notify_in. */
1123 {
313bd6fc 1124 GSList *iter = *notify_out;
1125 g_assert(g_slist_length(*notify_in) == 0);
8bc02ec8 1126
1127 while(iter != NULL) {
1128 gboolean remove = FALSE;
1129 gboolean free_data = FALSE;
1130
1131 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1132
1133 remove = TRUE;
1134 free_data = FALSE;
313bd6fc 1135 *notify_in = g_slist_append(*notify_in, notify_req);
8bc02ec8 1136
1137 /* Go to next */
1138 if(remove)
1139 {
1140 GSList *remove_iter = iter;
1141
1142 iter = g_slist_next(iter);
b052368a 1143 if(free_data)
1144 notify_request_free((BackgroundNotify*)remove_iter->data);
313bd6fc 1145 *notify_out = g_slist_remove_link(*notify_out, remove_iter);
8bc02ec8 1146 } else { // not remove
1147 iter = g_slist_next(iter);
1148 }
1149 }
1150 }
088f6772 1151 {
1152 GSList *iter = *list_in;
1153 LttvHooks *hook_adder = lttv_hooks_new();
1154 /* - for each request in list_in */
1155 while(iter != NULL) {
1156
1157 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1158 /*- add hooks to context*/
1159 lttvwindowtraces_add_computation_hooks(bg_req->module_name,
1160 tsc,
1161 hook_adder);
1162 iter = g_slist_next(iter);
1163 }
1164 lttv_hooks_call(hook_adder,tsc);
1165 lttv_hooks_destroy(hook_adder);
1166 }
1167
1168
8bc02ec8 1169 }
1170
1171 {
313bd6fc 1172 GSList *iter = *list_in;
8bc02ec8 1173 /* - for each request in list_in */
1174 while(iter != NULL) {
1175
1176 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1177 /*- Call before chunk hooks for list_in*/
088f6772 1178 lttvwindowtraces_call_before_chunk(bg_req->module_name,
1179 tsc);
8bc02ec8 1180 iter = g_slist_next(iter);
1181 }
1182 }
8bc02ec8 1183
088f6772 1184 }
8bc02ec8 1185 /* 2. call process traceset middle for a chunk */
1186 {
1187 /*(assert list_in is not empty! : should not even be called in that case)*/
0aa6c3a1 1188 LttTime end = ltt_time_infinite;
313bd6fc 1189 g_assert(g_slist_length(*list_in) != 0);
8bc02ec8 1190
1191 lttv_process_traceset_middle(tsc, end, CHUNK_NUM_EVENTS, NULL);
1192 }
1193
1194 /* 3. After the chunk */
1195 {
1196 /* 3.1 call after_chunk hooks for list_in */
1197 {
313bd6fc 1198 GSList *iter = *list_in;
8bc02ec8 1199 /* - for each request in list_in */
1200 while(iter != NULL) {
1201
1202 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1203 /* - Call after chunk hooks for list_in */
088f6772 1204 lttvwindowtraces_call_after_chunk(bg_req->module_name,
1205 tsc);
8bc02ec8 1206 iter = g_slist_next(iter);
1207 }
1208 }
1209
1210 /* 3.2 for each notify_in */
1211 {
313bd6fc 1212 GSList *iter = *notify_in;
8bc02ec8 1213 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1214
1215 while(iter != NULL) {
1216 gboolean remove = FALSE;
1217 gboolean free_data = FALSE;
1218
1219 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1220
1221 /* - if current time >= notify time, call notify and remove from
1222 * notify_in.
1223 * - if current position >= notify position, call notify and remove
1224 * from notify_in.
1225 */
1226 if( (tfc != NULL &&
313bd6fc 1227 ltt_time_compare(notify_req->notify_time, tfc->timestamp) <= 0)
8bc02ec8 1228 ||
313bd6fc 1229 (notify_req->notify_position != NULL &&
1230 lttv_traceset_context_ctx_pos_compare(tsc,
1231 notify_req->notify_position) >= 0)
8bc02ec8 1232 ) {
1233
1234 lttv_hooks_call(notify_req->notify, notify_req);
1235
1236 remove = TRUE;
1237 free_data = TRUE;
1238 }
1239
1240 /* Go to next */
1241 if(remove)
1242 {
1243 GSList *remove_iter = iter;
1244
1245 iter = g_slist_next(iter);
b052368a 1246 if(free_data)
1247 notify_request_free((BackgroundNotify*)remove_iter->data);
313bd6fc 1248 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
8bc02ec8 1249 } else { // not remove
1250 iter = g_slist_next(iter);
1251 }
1252 }
1253 }
1254
1255 {
1256 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1257 /* 3.3 if end of trace reached */
313bd6fc 1258 if(tfc != NULL)
1259 g_debug("Current time : %lu sec, %lu nsec",
1260 tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec);
8bc02ec8 1261 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
1262 tsc->time_span.end_time) > 0) {
088f6772 1263
1264 {
1265 GSList *iter = *list_in;
1266 LttvHooks *hook_remover = lttv_hooks_new();
1267 /* - for each request in list_in */
1268 while(iter != NULL) {
1269
1270 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1271 /* - remove hooks from context */
1272 lttvwindowtraces_remove_computation_hooks(bg_req->module_name,
1273 tsc,
1274 hook_remover);
1275 iter = g_slist_next(iter);
1276 }
1277 lttv_hooks_call(hook_remover,tsc);
1278 lttv_hooks_destroy(hook_remover);
1279 }
1280
8bc02ec8 1281 /* - for each request in list_in */
1282 {
313bd6fc 1283 GSList *iter = *list_in;
8bc02ec8 1284
1285 while(iter != NULL) {
1286 gboolean remove = FALSE;
1287 gboolean free_data = FALSE;
1288
1289 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1290
1291 /* - set hooks'in_progress flag to FALSE */
1292 lttvwindowtraces_unset_in_progress(bg_req->module_name,
1293 bg_req->trace);
1294 /* - set hooks'ready flag to TRUE */
1295 lttvwindowtraces_set_ready(bg_req->module_name,
1296 bg_req->trace);
91fd6881 1297 /* - call after request hook */
1298 /* Get after request hook */
1299 LttvAttribute *module_attribute;
1300
1301 g_assert(module_attribute =
1302 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1303 LTTV_IATTRIBUTE(g_attribute),
1304 LTTV_COMPUTATION)));
1305
1306 g_assert(module_attribute =
1307 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1308 LTTV_IATTRIBUTE(module_attribute),
1309 bg_req->module_name)));
1310
1311 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1312 LTTV_AFTER_REQUEST,
1313 &value);
1314 g_assert(type == LTTV_POINTER);
1315 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1316
1317 if(after_request != NULL) lttv_hooks_call(after_request, tsc);
93ac601b 1318
1319 if(bg_req->dialog != NULL)
1320 gtk_widget_destroy(bg_req->dialog);
b5e17af5 1321 GtkWidget *parent_window;
1322 if(g_slist_find_custom(g_main_window_list,
1323 bg_req->parent_window,
1324 (GCompareFunc)find_window_widget))
1325 parent_window = GTK_WIDGET(bg_req->parent_window);
1326 else
1327 parent_window = NULL;
1328
93ac601b 1329 GtkWidget *dialog =
b5e17af5 1330 gtk_message_dialog_new(GTK_WINDOW(parent_window),
1331 GTK_DIALOG_DESTROY_WITH_PARENT,
1332 GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
93ac601b 1333 "Background computation %s finished for trace %s",
1334 g_quark_to_string(bg_req->module_name),
1335 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req->trace))));
b5e17af5 1336 if(parent_window != NULL)
1337 gtk_window_set_transient_for(GTK_WINDOW(dialog),
1338 GTK_WINDOW(parent_window));
93ac601b 1339 g_signal_connect_swapped (dialog, "response",
1340 G_CALLBACK (gtk_widget_destroy),
1341 dialog);
1342 gtk_widget_show(dialog);
1343
8bc02ec8 1344 /* - remove request */
1345 remove = TRUE;
1346 free_data = TRUE;
1347
1348 /* Go to next */
1349 if(remove)
1350 {
1351 GSList *remove_iter = iter;
1352
1353 iter = g_slist_next(iter);
1354 if(free_data) g_free(remove_iter->data);
313bd6fc 1355 *list_in = g_slist_remove_link(*list_in, remove_iter);
8bc02ec8 1356 } else { // not remove
1357 iter = g_slist_next(iter);
1358 }
1359 }
1360 }
1361
1362 /* - for each notifications in notify_in */
1363 {
313bd6fc 1364 GSList *iter = *notify_in;
8bc02ec8 1365
1366 while(iter != NULL) {
1367 gboolean remove = FALSE;
1368 gboolean free_data = FALSE;
1369
1370 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1371
1372 /* - call notify and remove from notify_in */
1373 lttv_hooks_call(notify_req->notify, notify_req);
1374 remove = TRUE;
1375 free_data = TRUE;
1376
1377 /* Go to next */
1378 if(remove)
1379 {
1380 GSList *remove_iter = iter;
1381
1382 iter = g_slist_next(iter);
b052368a 1383 if(free_data)
1384 notify_request_free((BackgroundNotify*)remove_iter->data);
313bd6fc 1385 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
8bc02ec8 1386 } else { // not remove
1387 iter = g_slist_next(iter);
1388 }
1389 }
1390 }
1ce324c6 1391 {
1392 /* - reset the context */
1393 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->fini(tsc);
1394 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->init(tsc,ts);
1395 }
3710295e 1396 /* - if list_out is empty */
1397 if(g_slist_length(*list_out) == 0) {
1398 /* - return FALSE (scheduler stopped) */
1399 g_debug("Background computation scheduler stopped");
1400 g_info("Background computation finished for trace %p", trace);
1401 /* FIXME : remove status bar info, need context id and message id */
93ac601b 1402
3710295e 1403 ret_val = FALSE;
1404 } else {
1405 ret_val = TRUE;
1406 }
8bc02ec8 1407 } else {
1408 /* 3.4 else, end of trace not reached */
1409 /* - return TRUE (scheduler still registered) */
313bd6fc 1410 g_debug("Background computation left");
b052368a 1411 ret_val = TRUE;
8bc02ec8 1412 }
1413 }
1414 }
b052368a 1415 /* 4. Unlock traces */
1416 {
088f6772 1417 lttv_process_traceset_get_sync_data(tsc);
1418 //lttv_traceset_context_position_save(tsc, sync_position);
b052368a 1419 guint iter_trace;
1420
1421 for(iter_trace=0;
1422 iter_trace<lttv_traceset_number(tsc->ts);
1423 iter_trace++) {
1424 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1425
1426 lttvwindowtraces_unlock(trace_v);
1427 }
1428 }
1429 return ret_val;
8bc02ec8 1430}
e62a7964 1431
1432
1433
1434/**
1435 * Register the background computation hooks for a specific module. It adds the
313bd6fc 1436 * computation hooks to the global attrubutes, under "computation/module name".
e62a7964 1437 *
1438 * @param module_name A GQuark : the name of the module which computes the
1439 * information.
1440 */
1441void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name,
1442 LttvHooks *before_chunk_traceset,
1443 LttvHooks *before_chunk_trace,
1444 LttvHooks *before_chunk_tracefile,
1445 LttvHooks *after_chunk_traceset,
1446 LttvHooks *after_chunk_trace,
1447 LttvHooks *after_chunk_tracefile,
1448 LttvHooks *before_request,
1449 LttvHooks *after_request,
1450 LttvHooks *event_hook,
313bd6fc 1451 LttvHooksById *event_hook_by_id,
1452 LttvHooks *hook_adder,
1453 LttvHooks *hook_remover)
e62a7964 1454{
1455 LttvAttribute *g_attribute = lttv_global_attributes();
1456 LttvAttribute *attribute;
1457 LttvAttributeValue value;
1458
1459 g_assert(attribute =
1460 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1461 LTTV_COMPUTATION)));
1462
1463 g_assert(attribute =
1464 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1465 module_name)));
1466
1467 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1468 LTTV_BEFORE_CHUNK_TRACESET,
1469 LTTV_POINTER,
1470 &value));
1471 *(value.v_pointer) = before_chunk_traceset;
1472
1473 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1474 LTTV_BEFORE_CHUNK_TRACE,
1475 LTTV_POINTER,
1476 &value));
1477 *(value.v_pointer) = before_chunk_trace;
1478
1479 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1480 LTTV_BEFORE_CHUNK_TRACEFILE,
1481 LTTV_POINTER,
1482 &value));
1483 *(value.v_pointer) = before_chunk_tracefile;
1484
1485 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1486 LTTV_AFTER_CHUNK_TRACESET,
1487 LTTV_POINTER,
1488 &value));
1489 *(value.v_pointer) = after_chunk_traceset;
1490
1491 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1492 LTTV_AFTER_CHUNK_TRACE,
1493 LTTV_POINTER,
1494 &value));
1495 *(value.v_pointer) = after_chunk_trace;
1496
1497 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1498 LTTV_AFTER_CHUNK_TRACEFILE,
1499 LTTV_POINTER,
1500 &value));
1501 *(value.v_pointer) = after_chunk_tracefile;
1502
1503 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1504 LTTV_BEFORE_REQUEST,
1505 LTTV_POINTER,
1506 &value));
1507 *(value.v_pointer) = before_request;
1508
1509 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1510 LTTV_AFTER_REQUEST,
1511 LTTV_POINTER,
1512 &value));
1513 *(value.v_pointer) = after_request;
1514
1515 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1516 LTTV_EVENT_HOOK,
1517 LTTV_POINTER,
1518 &value));
1519 *(value.v_pointer) = event_hook;
1520
1521 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1522 LTTV_EVENT_HOOK_BY_ID,
1523 LTTV_POINTER,
1524 &value));
1525 *(value.v_pointer) = event_hook_by_id;
1526
313bd6fc 1527 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1528 LTTV_HOOK_ADDER,
1529 LTTV_POINTER,
1530 &value));
1531 *(value.v_pointer) = hook_adder;
1532
1533 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1534 LTTV_HOOK_REMOVER,
1535 LTTV_POINTER,
1536 &value));
1537 *(value.v_pointer) = hook_remover;
1538
e62a7964 1539}
1540
1541
1542/**
1543 * It removes all the requests than can be currently processed by the
1544 * background computation algorithm for all the traces (list_in and list_out).
1545 *
1546 * Leaves the flag to in_progress or none.. depending if current or queue
1547 *
1548 * @param module_name A GQuark : the name of the module which computes the
1549 * information.
1550 */
1551void lttvwindowtraces_unregister_requests(LttvAttributeName module_name)
1552{
1553 guint i;
1554
1555 for(i=0;i<lttvwindowtraces_get_number();i++) {
1556 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
1557 g_assert(trace_v != NULL);
1558 LttTrace *trace;
1559 LttvAttribute *attribute = lttv_trace_attribute(trace_v);
1560 LttvAttributeValue value;
313bd6fc 1561 GSList **queue, **current;
e62a7964 1562 GSList *iter;
1563
1564 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1565 LTTV_REQUESTS_QUEUE,
1566 LTTV_POINTER,
1567 &value));
313bd6fc 1568 queue = (GSList**)(value.v_pointer);
e62a7964 1569
313bd6fc 1570 iter = *queue;
e62a7964 1571 while(iter != NULL) {
1572 gboolean remove = FALSE;
1573 gboolean free_data = FALSE;
1574
1575 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1576
1577 if(bg_req->module_name == module_name) {
1578 remove = TRUE;
1579 free_data = TRUE;
1580 }
1581
1582 /* Go to next */
1583 if(remove)
1584 {
1585 GSList *remove_iter = iter;
1586
1587 iter = g_slist_next(iter);
1588 if(free_data) g_free(remove_iter->data);
313bd6fc 1589 *queue = g_slist_remove_link(*queue, remove_iter);
e62a7964 1590 } else { // not remove
1591 iter = g_slist_next(iter);
1592 }
1593 }
1594
1595
1596 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1597 LTTV_REQUESTS_CURRENT,
1598 LTTV_POINTER,
1599 &value));
313bd6fc 1600 current = (GSList**)(value.v_pointer);
e62a7964 1601
313bd6fc 1602 iter = *current;
e62a7964 1603 while(iter != NULL) {
1604 gboolean remove = FALSE;
1605 gboolean free_data = FALSE;
1606
1607 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1608
1609 if(bg_req->module_name == module_name) {
1610 remove = TRUE;
1611 free_data = TRUE;
1612 }
1613
1614 /* Go to next */
1615 if(remove)
1616 {
1617 GSList *remove_iter = iter;
1618
1619 iter = g_slist_next(iter);
1620 if(free_data) g_free(remove_iter->data);
313bd6fc 1621 *current = g_slist_remove_link(*current, remove_iter);
e62a7964 1622 } else { // not remove
1623 iter = g_slist_next(iter);
1624 }
1625 }
1626 }
1627}
1628
1629
1630/**
1631 * Unregister the background computation hooks for a specific module.
1632 *
1633 * It also removes all the requests than can be currently processed by the
1634 * background computation algorithm for all the traces (list_in and list_out).
1635 *
1636 * @param module_name A GQuark : the name of the module which computes the
1637 * information.
1638 */
1639
1640void lttvwindowtraces_unregister_computation_hooks
1641 (LttvAttributeName module_name)
1642{
1643 LttvAttribute *g_attribute = lttv_global_attributes();
1644 LttvAttribute *attribute;
91fd6881 1645 LttvAttributeValue value;
e62a7964 1646
1647 g_assert(attribute =
1648 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1649 LTTV_COMPUTATION)));
1650 g_assert(attribute =
1651 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1652 module_name)));
1653
1654
91fd6881 1655 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1656 LTTV_BEFORE_CHUNK_TRACESET,
1657 LTTV_POINTER,
1658 &value));
1659 LttvHooks *before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1660 if(before_chunk_traceset != NULL)
1661 lttv_hooks_destroy(before_chunk_traceset);
1662
1663 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1664 LTTV_BEFORE_CHUNK_TRACE,
1665 LTTV_POINTER,
1666 &value));
1667 LttvHooks *before_chunk_trace = (LttvHooks*)*(value.v_pointer);
1668 if(before_chunk_trace != NULL)
1669 lttv_hooks_destroy(before_chunk_trace);
1670
1671 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1672 LTTV_BEFORE_CHUNK_TRACEFILE,
1673 LTTV_POINTER,
1674 &value));
1675 LttvHooks *before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1676 if(before_chunk_tracefile != NULL)
1677 lttv_hooks_destroy(before_chunk_tracefile);
1678
1679 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1680 LTTV_AFTER_CHUNK_TRACESET,
1681 LTTV_POINTER,
1682 &value));
1683 LttvHooks *after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1684 if(after_chunk_traceset != NULL)
1685 lttv_hooks_destroy(after_chunk_traceset);
1686
1687 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1688 LTTV_AFTER_CHUNK_TRACE,
1689 LTTV_POINTER,
1690 &value));
1691 LttvHooks *after_chunk_trace = (LttvHooks*)*(value.v_pointer);
1692 if(after_chunk_trace != NULL)
1693 lttv_hooks_destroy(after_chunk_trace);
1694
1695 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1696 LTTV_AFTER_CHUNK_TRACEFILE,
1697 LTTV_POINTER,
1698 &value));
1699 LttvHooks *after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1700 if(after_chunk_tracefile != NULL)
1701 lttv_hooks_destroy(after_chunk_tracefile);
1702
1703 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1704 LTTV_BEFORE_REQUEST,
1705 LTTV_POINTER,
1706 &value));
1707 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1708 if(before_request != NULL)
1709 lttv_hooks_destroy(before_request);
1710
1711 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1712 LTTV_AFTER_REQUEST,
1713 LTTV_POINTER,
1714 &value));
1715 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1716 if(after_request != NULL)
1717 lttv_hooks_destroy(after_request);
1718
1719 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1720 LTTV_EVENT_HOOK,
1721 LTTV_POINTER,
1722 &value));
1723 LttvHooks *event_hook = (LttvHooks*)*(value.v_pointer);
1724 if(event_hook != NULL)
1725 lttv_hooks_destroy(event_hook);
1726
1727 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1728 LTTV_EVENT_HOOK_BY_ID,
1729 LTTV_POINTER,
1730 &value));
1731 LttvHooksById *event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
1732 if(event_hook_by_id != NULL)
1733 lttv_hooks_by_id_destroy(event_hook_by_id);
1734
1735 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1736 LTTV_HOOK_ADDER,
1737 LTTV_POINTER,
1738 &value));
1739 LttvHooks *hook_adder = (LttvHooks*)*(value.v_pointer);
1740 if(hook_adder != NULL)
1741 lttv_hooks_destroy(hook_adder);
1742
1743 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1744 LTTV_HOOK_REMOVER,
1745 LTTV_POINTER,
1746 &value));
1747 LttvHooks *hook_remover = (LttvHooks*)*(value.v_pointer);
1748 if(hook_remover != NULL)
1749 lttv_hooks_destroy(hook_remover);
1750
1751
e62a7964 1752 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1753 LTTV_EVENT_HOOK_BY_ID);
1754 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1755 LTTV_EVENT_HOOK);
1756
1757 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1758 LTTV_AFTER_REQUEST);
1759 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1760 LTTV_BEFORE_REQUEST);
1761
1762 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1763 LTTV_AFTER_CHUNK_TRACEFILE);
1764 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1765 LTTV_AFTER_CHUNK_TRACE);
1766 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1767 LTTV_AFTER_CHUNK_TRACESET);
1768
1769 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1770 LTTV_BEFORE_CHUNK_TRACEFILE);
1771 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1772 LTTV_BEFORE_CHUNK_TRACE);
1773 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1774 LTTV_BEFORE_CHUNK_TRACESET);
313bd6fc 1775 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1776 LTTV_HOOK_ADDER);
1777 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1778 LTTV_HOOK_REMOVER);
1779
e62a7964 1780 /* finally, remove module name */
1781 g_assert(attribute =
1782 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1783 LTTV_COMPUTATION)));
1784 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1785 module_name);
1786
1787}
1788
b052368a 1789/**
1790 * Lock a trace so no other instance can use it.
1791 *
1792 * @param trace The trace to lock.
1793 * @return 0 on success, -1 if cannot get lock.
1794 */
1795gint lttvwindowtraces_lock(LttvTrace *trace)
1796{
1797 LttvAttribute *attribute = lttv_trace_attribute(trace);
1798 LttvAttributeValue value;
1799 LttvAttributeType type;
1800
1801 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1802 LTTV_LOCK,
1803 &value);
1804 /* Verify the absence of the lock. */
1805 if(type != LTTV_NONE) {
1806 g_critical("Cannot take trace lock");
1807 return -1;
1808 }
1809
1810 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
1811 LTTV_LOCK,
1812 LTTV_INT);
1813 /* the value is left unset. The only presence of the attribute is necessary.
1814 */
1815
1816 return 0;
1817}
1818
1819/**
1820 * Unlock a trace.
1821 *
1822 * @param trace The trace to unlock.
1823 * @return 0 on success, -1 if cannot unlock (not locked ?).
1824 */
1825gint lttvwindowtraces_unlock(LttvTrace *trace)
1826{
1827 LttvAttribute *attribute = lttv_trace_attribute(trace);
1828 LttvAttributeType type;
1829 LttvAttributeValue value;
1830
1831 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1832 LTTV_LOCK,
1833 &value);
1834 /* Verify the presence of the lock. */
1835 if(type == LTTV_NONE) {
1836 g_critical("Cannot release trace lock");
1837 return -1;
1838 }
1839
1840 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1841 LTTV_LOCK);
1842
1843 return 0;
1844}
1845
1846/**
1847 * Verify if a trace is locked.
1848 *
1849 * @param trace The trace to verify.
1850 * @return TRUE if locked, FALSE is unlocked.
1851 */
1852gint lttvwindowtraces_get_lock_state(LttvTrace *trace)
1853{
1854 LttvAttribute *attribute = lttv_trace_attribute(trace);
1855 LttvAttributeType type;
1856 LttvAttributeValue value;
1857
1858 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1859 LTTV_LOCK,
1860 &value);
1861 /* The only presence of the attribute is necessary. */
1862 if(type == LTTV_NONE)
1863 return FALSE;
1864 else
1865 return TRUE;
1866}
e62a7964 1867
This page took 0.126465 seconds and 4 git commands to generate.