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