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