1 /* This file is part of the Linux Trace Toolkit Graphic User Interface
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
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;
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.
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,
19 /* This file is the API used to launch any background computation on a trace */
21 /* Here is the implementation of the API */
27 #include <sys/types.h>
33 #include <ltt/trace.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>
40 #include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
43 typedef struct _BackgroundRequest
{
44 LttvAttributeName module_name
; /* Hook path in global attributes,
45 where all standard hooks under computation/.
47 LttvTrace
*trace
; /* trace concerned */
50 typedef struct _BackgroundNotify
{
52 LttvTrace
*trace
; /* trace */
54 LttvTracesetContextPosition
*notify_position
;
55 LttvHooks
*notify
; /* Hook to call when the notify is
56 passed, or at the end of trace */
62 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
);
64 /* Get a trace by its path name.
66 * @param path path of the trace on the virtual file system.
67 * @return Pointer to trace if found
68 * NULL is returned if the trace is not present
71 LttvTrace
*lttvwindowtraces_get_trace_by_name(gchar
*path
)
75 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
76 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
79 g_assert(trace_v
!= NULL
);
81 trace
= lttv_trace(trace_v
);
82 g_assert(trace
!= NULL
);
83 name
= g_quark_to_string(ltt_trace_name(trace
));
85 if(strcmp(name
, path
) == 0) {
94 /* Get a trace by its number identifier */
96 LttvTrace
*lttvwindowtraces_get_trace(guint num
)
98 LttvAttribute
*g_attribute
= lttv_global_attributes();
99 LttvAttribute
*attribute
;
100 LttvAttributeType type
;
101 LttvAttributeName name
;
102 LttvAttributeValue value
;
105 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
108 type
= lttv_iattribute_get(LTTV_IATTRIBUTE(attribute
), num
, &name
, &value
);
110 if(type
== LTTV_POINTER
) {
111 return (LttvTrace
*)*(value
.v_pointer
);
117 /* Total number of traces */
119 guint
lttvwindowtraces_get_number()
121 LttvAttribute
*g_attribute
= lttv_global_attributes();
122 LttvAttribute
*attribute
;
123 LttvAttributeValue value
;
126 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
129 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute
)) );
132 /* Add a trace to the global attributes */
134 void lttvwindowtraces_add_trace(LttvTrace
*trace
)
136 LttvAttribute
*g_attribute
= lttv_global_attributes();
137 LttvAttribute
*attribute
;
138 LttvAttributeValue value
;
141 gchar attribute_path
[PATH_MAX
];
143 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace
))), &buf
)) {
144 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
145 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
149 snprintf(attribute_path
, PATH_MAX
, "%llu:%llu", buf
.st_dev
, buf
.st_ino
) >= 0);
152 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
155 value
= lttv_attribute_add(attribute
,
156 g_quark_from_string(attribute_path
),
159 *(value
.v_pointer
) = (gpointer
)trace
;
161 /* create new traceset and tracesetcontext */
163 LttvTracesetStats
*tss
;
164 LttvTracesetContextPosition
*sync_position
;
166 attribute
= lttv_trace_attribute(trace
);
167 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
168 LTTV_COMPUTATION_TRACESET
,
171 ts
= lttv_traceset_new();
172 *(value
.v_pointer
) = ts
;
174 lttv_traceset_add(ts
,trace
);
176 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
177 LTTV_COMPUTATION_TRACESET_CONTEXT
,
180 tss
= g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
181 *(value
.v_pointer
) = tss
;
183 lttv_context_init(LTTV_TRACESET_CONTEXT(tss
), ts
);
185 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
186 LTTV_COMPUTATION_SYNC_POSITION
,
190 sync_position
= lttv_traceset_context_position_new();
191 *(value
.v_pointer
) = sync_position
;
193 value
= lttv_attribute_add(attribute
,
197 value
= lttv_attribute_add(attribute
,
198 LTTV_REQUESTS_CURRENT
,
201 value
= lttv_attribute_add(attribute
,
205 value
= lttv_attribute_add(attribute
,
211 /* Remove a trace from the global attributes */
213 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
215 LttvAttribute
*g_attribute
= lttv_global_attributes();
216 LttvAttribute
*attribute
;
217 LttvAttributeValue value
;
221 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
224 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
225 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
227 g_assert(trace_v
!= NULL
);
229 /* Remove and background computation that could be in progress */
230 g_idle_remove_by_data(trace_v
);
232 if(trace_v
== trace
) {
234 LttvAttribute
*l_attribute
;
236 /* destroy traceset and tracesetcontext */
238 LttvTracesetStats
*tss
;
239 LttvTracesetContextPosition
*sync_position
;
241 l_attribute
= lttv_trace_attribute(trace
);
244 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
245 LTTV_REQUESTS_QUEUE
);
247 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
248 LTTV_REQUESTS_CURRENT
);
250 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
253 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
254 LTTV_NOTIFY_CURRENT
);
256 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
257 LTTV_COMPUTATION_TRACESET
,
260 ts
= (LttvTraceset
*)*(value
.v_pointer
);
262 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
263 LTTV_COMPUTATION_SYNC_POSITION
,
266 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
268 lttv_traceset_context_position_destroy(sync_position
);
270 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
271 LTTV_COMPUTATION_SYNC_POSITION
);
273 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
274 LTTV_COMPUTATION_TRACESET_CONTEXT
,
277 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
279 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss
));
281 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
282 LTTV_COMPUTATION_TRACESET_CONTEXT
);
283 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
284 LTTV_COMPUTATION_TRACESET
);
285 /* Destroy the traceset and the trace also */
286 lttv_traceset_destroy(ts
);
288 /* finally, remove the global attribute */
289 lttv_attribute_remove(attribute
, i
);
298 * Function to request data from a specific trace
300 * The memory allocated for the request will be managed by the API.
302 * @param trace the trace to compute
303 * @param module_name the name of the module which registered global computation
307 void lttvwindowtraces_background_request_queue
308 (LttvTrace
*trace
, gchar
*module_name
)
310 BackgroundRequest
*bg_req
;
311 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
312 LttvAttribute
*g_attribute
= lttv_global_attributes();
313 LttvAttribute
*module_attribute
;
314 LttvAttributeValue value
;
315 LttvAttributeType type
;
319 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
323 slist
= (GSList
**)(value
.v_pointer
);
325 /* Verify that the calculator is loaded */
326 g_assert(module_attribute
=
327 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
331 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
332 g_quark_from_string(module_name
),
334 if(type
== LTTV_NONE
) {
335 g_critical("Missing background calculator %s", module_name
);
339 bg_req
= g_new(BackgroundRequest
,1);
340 bg_req
->module_name
= g_quark_from_string(module_name
);
341 bg_req
->trace
= trace
;
343 *slist
= g_slist_append(*slist
, bg_req
);
345 /* Priority lower than live servicing */
346 g_idle_remove_by_data(trace
);
347 g_idle_add_full((G_PRIORITY_HIGH_IDLE
+ 23),
348 (GSourceFunc
)lttvwindowtraces_process_pending_requests
,
351 /* FIXME : show message in status bar, need context and message id */
352 g_info("Background computation started for trace %p", trace
);
356 * Remove a background request from a trace.
358 * This should ONLY be used by the modules which registered the global hooks
359 * (module_name). If this is called by the viewers, it may lead to incomplete
360 * and incoherent background processing information.
362 * Even if the module which deals with the hooks removes the background
363 * requests, it may cause a problem if the module gets loaded again in the
364 * session : the data will be partially calculated. The calculation function
365 * must deal with this case correctly.
367 * @param trace the trace to compute
368 * @param module_name the name of the module which registered global computation
372 void lttvwindowtraces_background_request_remove
373 (LttvTrace
*trace
, gchar
*module_name
)
375 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
376 LttvAttributeValue value
;
380 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
384 slist
= (GSList
**)(value
.v_pointer
);
386 for(iter
=*slist
;iter
!=NULL
;) {
387 BackgroundRequest
*bg_req
=
388 (BackgroundRequest
*)iter
->data
;
390 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
391 GSList
*rem_iter
= iter
;
392 iter
=g_slist_next(iter
);
394 *slist
= g_slist_delete_link(*slist
, rem_iter
);
396 iter
=g_slist_next(iter
);
403 * Register a callback to be called when requested data is passed in the next
404 * queued background processing.
406 * @param owner owner of the background notification
407 * @param trace the trace computed
408 * @param notify_time time when notification hooks must be called
409 * @param notify_position position when notification hooks must be called
410 * @param notify Hook to call when the notify position is passed
413 void lttvwindowtraces_background_notify_queue
417 const LttvTracesetContextPosition
*notify_position
,
418 const LttvHooks
*notify
)
420 BackgroundNotify
*bg_notify
;
421 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
422 LttvAttributeValue value
;
425 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
429 slist
= (GSList
**)(value
.v_pointer
);
432 bg_notify
= g_new(BackgroundNotify
,1);
434 bg_notify
->owner
= owner
;
435 bg_notify
->trace
= trace
;
436 bg_notify
->notify_time
= notify_time
;
437 if(notify_position
!= NULL
) {
438 bg_notify
->notify_position
= lttv_traceset_context_position_new();
439 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
442 bg_notify
->notify_position
= NULL
;
445 bg_notify
->notify
= lttv_hooks_new();
446 lttv_hooks_add_list(bg_notify
->notify
, notify
);
448 *slist
= g_slist_append(*slist
, bg_notify
);
452 * Register a callback to be called when requested data is passed in the current
453 * background processing.
455 * @param owner owner of the background notification
456 * @param trace the trace computed
457 * @param notify_time time when notification hooks must be called
458 * @param notify_position position when notification hooks must be called
459 * @param notify Hook to call when the notify position is passed
462 void lttvwindowtraces_background_notify_current
466 const LttvTracesetContextPosition
*notify_position
,
467 const LttvHooks
*notify
)
469 BackgroundNotify
*bg_notify
;
470 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
471 LttvAttributeValue value
;
474 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
478 slist
= (GSList
**)(value
.v_pointer
);
480 bg_notify
= g_new(BackgroundNotify
,1);
482 bg_notify
->owner
= owner
;
483 bg_notify
->trace
= trace
;
484 bg_notify
->notify_time
= notify_time
;
485 if(notify_position
!= NULL
) {
486 bg_notify
->notify_position
= lttv_traceset_context_position_new();
487 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
490 bg_notify
->notify_position
= NULL
;
492 bg_notify
->notify
= lttv_hooks_new();
493 lttv_hooks_add_list(bg_notify
->notify
, notify
);
495 *slist
= g_slist_append(*slist
, bg_notify
);
499 static void notify_request_free(BackgroundNotify
*notify_req
)
501 if(notify_req
== NULL
) return;
503 if(notify_req
->notify_position
!= NULL
)
504 lttv_traceset_context_position_destroy(notify_req
->notify_position
);
505 if(notify_req
->notify
!= NULL
)
506 lttv_hooks_destroy(notify_req
->notify
);
511 * Removes all the notifications requests from a specific viewer.
513 * @param owner owner of the background notification
516 void lttvwindowtraces_background_notify_remove(gpointer owner
)
520 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
521 LttvAttribute
*attribute
;
522 LttvAttributeValue value
;
523 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
527 g_assert(trace_v
!= NULL
);
529 attribute
= lttv_trace_attribute(trace_v
);
531 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
535 slist
= (GSList
**)(value
.v_pointer
);
537 for(iter
=*slist
;iter
!=NULL
;) {
539 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
541 if(bg_notify
->owner
== owner
) {
542 GSList
*rem_iter
= iter
;
543 iter
=g_slist_next(iter
);
544 notify_request_free(bg_notify
);
545 *slist
= g_slist_remove_link(*slist
, rem_iter
);
547 iter
=g_slist_next(iter
);
551 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
555 slist
= (GSList
**)(value
.v_pointer
);
557 for(iter
=*slist
;iter
!=NULL
;) {
559 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
561 if(bg_notify
->owner
== owner
) {
562 GSList
*rem_iter
= iter
;
563 iter
=g_slist_next(iter
);
564 notify_request_free(bg_notify
);
565 *slist
= g_slist_remove_link(*slist
, rem_iter
);
567 iter
=g_slist_next(iter
);
574 /* Background processing helper functions */
576 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
577 LttvTracesetContext
*tsc
,
578 LttvHooks
*hook_adder
)
580 LttvAttribute
*g_attribute
= lttv_global_attributes();
581 LttvAttribute
*module_attribute
;
582 LttvAttributeType type
;
583 LttvAttributeValue value
;
584 LttvHooks
*before_chunk_traceset
=NULL
;
585 LttvHooks
*before_chunk_trace
=NULL
;
586 LttvHooks
*before_chunk_tracefile
=NULL
;
587 LttvHooks
*event_hook
=NULL
;
588 LttvHooksById
*event_hook_by_id
=NULL
;
589 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
592 g_assert(module_attribute
=
593 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
596 g_assert(module_attribute
=
597 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
598 LTTV_IATTRIBUTE(module_attribute
),
601 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
602 LTTV_BEFORE_CHUNK_TRACESET
,
604 if(type
== LTTV_POINTER
) {
605 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
608 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
609 LTTV_BEFORE_CHUNK_TRACE
,
611 if(type
== LTTV_POINTER
) {
612 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
615 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
616 LTTV_BEFORE_CHUNK_TRACEFILE
,
618 if(type
== LTTV_POINTER
) {
619 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
622 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
625 if(type
== LTTV_POINTER
) {
626 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
629 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
630 LTTV_EVENT_HOOK_BY_ID
,
632 if(type
== LTTV_POINTER
) {
633 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
636 /* Call the module's hook adder */
637 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
640 if(type
== LTTV_POINTER
) {
641 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
642 if(hook_adder
!= NULL
)
643 lttv_hooks_add_list(hook_adder
, (LttvHooks
*)*(value
.v_pointer
));
648 lttv_process_traceset_begin(tsc
,
649 before_chunk_traceset
,
651 before_chunk_tracefile
,
657 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
658 LttvTracesetContext
*tsc
,
659 LttvHooks
*hook_remover
)
661 LttvAttribute
*g_attribute
= lttv_global_attributes();
662 LttvAttribute
*module_attribute
;
663 LttvAttributeType type
;
664 LttvAttributeValue value
;
665 LttvHooks
*after_chunk_traceset
=NULL
;
666 LttvHooks
*after_chunk_trace
=NULL
;
667 LttvHooks
*after_chunk_tracefile
=NULL
;
668 LttvHooks
*event_hook
=NULL
;
669 LttvHooksById
*event_hook_by_id
=NULL
;
670 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
672 g_assert(module_attribute
=
673 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
676 g_assert(module_attribute
=
677 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
678 LTTV_IATTRIBUTE(module_attribute
),
681 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
682 LTTV_AFTER_CHUNK_TRACESET
,
684 if(type
== LTTV_POINTER
) {
685 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
688 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
689 LTTV_AFTER_CHUNK_TRACE
,
691 if(type
== LTTV_POINTER
) {
692 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
695 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
696 LTTV_AFTER_CHUNK_TRACEFILE
,
698 if(type
== LTTV_POINTER
) {
699 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
702 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
705 if(type
== LTTV_POINTER
) {
706 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
709 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
710 LTTV_EVENT_HOOK_BY_ID
,
712 if(type
== LTTV_POINTER
) {
713 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
716 lttv_process_traceset_end(tsc
,
717 after_chunk_traceset
,
719 after_chunk_tracefile
,
723 /* Call the module's hook remover */
724 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
727 if(type
== LTTV_POINTER
) {
728 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
729 if(hook_remover
!= NULL
)
730 lttv_hooks_add_list(hook_remover
, (LttvHooks
*)*(value
.v_pointer
));
735 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
738 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
739 LttvAttributeValue value
;
742 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
745 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
748 /* the value is left unset. The only presence of the attribute is necessary.
752 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
755 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
758 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
761 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
765 gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
768 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
769 LttvAttributeType type
;
770 LttvAttributeValue value
;
773 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
776 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
779 /* The only presence of the attribute is necessary. */
780 if(type
== LTTV_NONE
)
786 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
789 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
790 LttvAttributeValue value
;
793 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
796 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
799 /* the value is left unset. The only presence of the attribute is necessary.
803 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
806 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
809 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
812 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
816 gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
819 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
820 LttvAttributeType type
;
821 LttvAttributeValue value
;
824 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
827 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
830 /* The only presence of the attribute is necessary. */
831 if(type
== LTTV_NONE
)
838 /* lttvwindowtraces_process_pending_requests
840 * This internal function gets called by g_idle, taking care of the pending
846 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
848 LttvTracesetContext
*tsc
;
849 LttvTracesetStats
*tss
;
851 LttvTracesetContextPosition
*sync_position
;
852 LttvAttribute
*attribute
;
853 LttvAttribute
*g_attribute
= lttv_global_attributes();
854 GSList
**list_out
, **list_in
, **notify_in
, **notify_out
;
855 LttvAttributeValue value
;
856 LttvAttributeType type
;
862 attribute
= lttv_trace_attribute(trace
);
864 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
867 g_assert(type
== LTTV_POINTER
);
868 list_out
= (GSList
**)(value
.v_pointer
);
870 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
871 LTTV_REQUESTS_CURRENT
,
873 g_assert(type
== LTTV_POINTER
);
874 list_in
= (GSList
**)(value
.v_pointer
);
876 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
879 g_assert(type
== LTTV_POINTER
);
880 notify_out
= (GSList
**)(value
.v_pointer
);
882 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
885 g_assert(type
== LTTV_POINTER
);
886 notify_in
= (GSList
**)(value
.v_pointer
);
888 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
889 LTTV_COMPUTATION_TRACESET
,
891 g_assert(type
== LTTV_POINTER
);
892 ts
= (LttvTraceset
*)*(value
.v_pointer
);
894 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
895 LTTV_COMPUTATION_TRACESET_CONTEXT
,
897 g_assert(type
== LTTV_POINTER
);
898 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
899 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
900 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc
));
901 g_assert(LTTV_IS_TRACESET_STATS(tss
));
903 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
904 LTTV_COMPUTATION_SYNC_POSITION
,
906 g_assert(type
== LTTV_POINTER
);
907 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
909 /* There is no events requests pending : we should never have been called! */
910 g_assert(g_slist_length(*list_out
) != 0 || g_slist_length(*list_in
) != 0);
911 /* 0.1 Lock traces */
916 iter_trace
<lttv_traceset_number(tsc
->ts
);
918 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
,iter_trace
);
920 if(lttvwindowtraces_lock(trace_v
) != 0)
921 return TRUE
; /* Cannot get trace lock, try later */
925 /* 0.2 Sync tracefiles */
926 g_assert(lttv_process_traceset_seek_position(tsc
, sync_position
) == 0);
927 // lttv_process_traceset_synchronize_tracefiles(tsc);
928 /* 1. Before processing */
930 /* if list_in is empty */
931 if(g_slist_length(*list_in
) == 0) {
934 /* - Add all requests in list_out to list_in, empty list_out */
935 GSList
*iter
= *list_out
;
937 while(iter
!= NULL
) {
938 gboolean remove
= FALSE
;
939 gboolean free_data
= FALSE
;
941 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
945 *list_in
= g_slist_append(*list_in
, bg_req
);
950 GSList
*remove_iter
= iter
;
952 iter
= g_slist_next(iter
);
953 if(free_data
) g_free(remove_iter
->data
);
954 *list_out
= g_slist_remove_link(*list_out
, remove_iter
);
955 } else { // not remove
956 iter
= g_slist_next(iter
);
962 GSList
*iter
= *list_in
;
963 /* - for each request in list_in */
964 while(iter
!= NULL
) {
966 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
967 /* - set hooks'in_progress flag to TRUE */
968 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
971 /* - call before request hook */
972 /* Get before request hook */
973 LttvAttribute
*module_attribute
;
975 g_assert(module_attribute
=
976 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
977 LTTV_IATTRIBUTE(g_attribute
),
980 g_assert(module_attribute
=
981 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
982 LTTV_IATTRIBUTE(module_attribute
),
983 bg_req
->module_name
)));
985 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
988 g_assert(type
== LTTV_POINTER
);
989 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
991 if(before_request
!= NULL
) lttv_hooks_call(before_request
, tsc
);
993 iter
= g_slist_next(iter
);
997 /* - seek trace to start */
999 LttTime start
= { 0, 0};
1000 lttv_process_traceset_seek_time(tsc
, start
);
1003 /* - Move all notifications from notify_out to notify_in. */
1005 GSList
*iter
= *notify_out
;
1006 g_assert(g_slist_length(*notify_in
) == 0);
1008 while(iter
!= NULL
) {
1009 gboolean remove
= FALSE
;
1010 gboolean free_data
= FALSE
;
1012 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1016 *notify_in
= g_slist_append(*notify_in
, notify_req
);
1021 GSList
*remove_iter
= iter
;
1023 iter
= g_slist_next(iter
);
1025 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1026 *notify_out
= g_slist_remove_link(*notify_out
, remove_iter
);
1027 } else { // not remove
1028 iter
= g_slist_next(iter
);
1035 GSList
*iter
= *list_in
;
1036 LttvHooks
*hook_adder
= lttv_hooks_new();
1037 /* - for each request in list_in */
1038 while(iter
!= NULL
) {
1040 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1041 /*- Call before chunk hooks for list_in*/
1042 /*- add hooks to context*/
1043 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
1046 iter
= g_slist_next(iter
);
1048 lttv_hooks_call(hook_adder
,tsc
);
1049 lttv_hooks_destroy(hook_adder
);
1053 /* 2. call process traceset middle for a chunk */
1055 /*(assert list_in is not empty! : should not even be called in that case)*/
1056 LttTime end
= ltt_time_infinite
;
1057 g_assert(g_slist_length(*list_in
) != 0);
1059 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
1062 /* 3. After the chunk */
1064 /* 3.1 call after_chunk hooks for list_in */
1066 GSList
*iter
= *list_in
;
1067 LttvHooks
*hook_remover
= lttv_hooks_new();
1068 /* - for each request in list_in */
1069 while(iter
!= NULL
) {
1071 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1072 /* - Call after chunk hooks for list_in */
1073 /* - remove hooks from context */
1074 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
1077 iter
= g_slist_next(iter
);
1079 lttv_hooks_call(hook_remover
,tsc
);
1080 lttv_hooks_destroy(hook_remover
);
1083 /* 3.2 for each notify_in */
1085 GSList
*iter
= *notify_in
;
1086 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1088 while(iter
!= NULL
) {
1089 gboolean remove
= FALSE
;
1090 gboolean free_data
= FALSE
;
1092 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1094 /* - if current time >= notify time, call notify and remove from
1096 * - if current position >= notify position, call notify and remove
1100 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) <= 0)
1102 (notify_req
->notify_position
!= NULL
&&
1103 lttv_traceset_context_ctx_pos_compare(tsc
,
1104 notify_req
->notify_position
) >= 0)
1107 lttv_hooks_call(notify_req
->notify
, notify_req
);
1116 GSList
*remove_iter
= iter
;
1118 iter
= g_slist_next(iter
);
1120 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1121 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1122 } else { // not remove
1123 iter
= g_slist_next(iter
);
1129 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1130 /* 3.3 if end of trace reached */
1132 g_debug("Current time : %lu sec, %lu nsec",
1133 tfc
->timestamp
.tv_sec
, tfc
->timestamp
.tv_nsec
);
1134 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1135 tsc
->time_span
.end_time
) > 0) {
1137 /* - for each request in list_in */
1139 GSList
*iter
= *list_in
;
1141 while(iter
!= NULL
) {
1142 gboolean remove
= FALSE
;
1143 gboolean free_data
= FALSE
;
1145 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1147 /* - set hooks'in_progress flag to FALSE */
1148 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
1150 /* - set hooks'ready flag to TRUE */
1151 lttvwindowtraces_set_ready(bg_req
->module_name
,
1153 /* - call after request hook */
1154 /* Get after request hook */
1155 LttvAttribute
*module_attribute
;
1157 g_assert(module_attribute
=
1158 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1159 LTTV_IATTRIBUTE(g_attribute
),
1160 LTTV_COMPUTATION
)));
1162 g_assert(module_attribute
=
1163 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1164 LTTV_IATTRIBUTE(module_attribute
),
1165 bg_req
->module_name
)));
1167 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1170 g_assert(type
== LTTV_POINTER
);
1171 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1173 if(after_request
!= NULL
) lttv_hooks_call(after_request
, tsc
);
1174 /* - remove request */
1181 GSList
*remove_iter
= iter
;
1183 iter
= g_slist_next(iter
);
1184 if(free_data
) g_free(remove_iter
->data
);
1185 *list_in
= g_slist_remove_link(*list_in
, remove_iter
);
1186 } else { // not remove
1187 iter
= g_slist_next(iter
);
1192 /* - for each notifications in notify_in */
1194 GSList
*iter
= *notify_in
;
1196 while(iter
!= NULL
) {
1197 gboolean remove
= FALSE
;
1198 gboolean free_data
= FALSE
;
1200 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1202 /* - call notify and remove from notify_in */
1203 lttv_hooks_call(notify_req
->notify
, notify_req
);
1210 GSList
*remove_iter
= iter
;
1212 iter
= g_slist_next(iter
);
1214 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1215 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1216 } else { // not remove
1217 iter
= g_slist_next(iter
);
1222 /* - reset the context */
1223 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->fini(tsc
);
1224 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->init(tsc
,ts
);
1226 /* - if list_out is empty */
1227 if(g_slist_length(*list_out
) == 0) {
1228 /* - return FALSE (scheduler stopped) */
1229 g_debug("Background computation scheduler stopped");
1230 g_info("Background computation finished for trace %p", trace
);
1231 /* FIXME : remove status bar info, need context id and message id */
1237 /* 3.4 else, end of trace not reached */
1238 /* - return TRUE (scheduler still registered) */
1239 g_debug("Background computation left");
1244 /* 4. Unlock traces */
1246 // lttv_process_traceset_get_sync_data(tsc);
1247 lttv_traceset_context_position_save(tsc
, sync_position
);
1251 iter_trace
<lttv_traceset_number(tsc
->ts
);
1253 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1255 lttvwindowtraces_unlock(trace_v
);
1264 * Register the background computation hooks for a specific module. It adds the
1265 * computation hooks to the global attrubutes, under "computation/module name".
1267 * @param module_name A GQuark : the name of the module which computes the
1270 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1271 LttvHooks
*before_chunk_traceset
,
1272 LttvHooks
*before_chunk_trace
,
1273 LttvHooks
*before_chunk_tracefile
,
1274 LttvHooks
*after_chunk_traceset
,
1275 LttvHooks
*after_chunk_trace
,
1276 LttvHooks
*after_chunk_tracefile
,
1277 LttvHooks
*before_request
,
1278 LttvHooks
*after_request
,
1279 LttvHooks
*event_hook
,
1280 LttvHooksById
*event_hook_by_id
,
1281 LttvHooks
*hook_adder
,
1282 LttvHooks
*hook_remover
)
1284 LttvAttribute
*g_attribute
= lttv_global_attributes();
1285 LttvAttribute
*attribute
;
1286 LttvAttributeValue value
;
1288 g_assert(attribute
=
1289 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1290 LTTV_COMPUTATION
)));
1292 g_assert(attribute
=
1293 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1296 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1297 LTTV_BEFORE_CHUNK_TRACESET
,
1300 *(value
.v_pointer
) = before_chunk_traceset
;
1302 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1303 LTTV_BEFORE_CHUNK_TRACE
,
1306 *(value
.v_pointer
) = before_chunk_trace
;
1308 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1309 LTTV_BEFORE_CHUNK_TRACEFILE
,
1312 *(value
.v_pointer
) = before_chunk_tracefile
;
1314 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1315 LTTV_AFTER_CHUNK_TRACESET
,
1318 *(value
.v_pointer
) = after_chunk_traceset
;
1320 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1321 LTTV_AFTER_CHUNK_TRACE
,
1324 *(value
.v_pointer
) = after_chunk_trace
;
1326 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1327 LTTV_AFTER_CHUNK_TRACEFILE
,
1330 *(value
.v_pointer
) = after_chunk_tracefile
;
1332 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1333 LTTV_BEFORE_REQUEST
,
1336 *(value
.v_pointer
) = before_request
;
1338 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1342 *(value
.v_pointer
) = after_request
;
1344 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1348 *(value
.v_pointer
) = event_hook
;
1350 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1351 LTTV_EVENT_HOOK_BY_ID
,
1354 *(value
.v_pointer
) = event_hook_by_id
;
1356 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1360 *(value
.v_pointer
) = hook_adder
;
1362 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1366 *(value
.v_pointer
) = hook_remover
;
1372 * It removes all the requests than can be currently processed by the
1373 * background computation algorithm for all the traces (list_in and list_out).
1375 * Leaves the flag to in_progress or none.. depending if current or queue
1377 * @param module_name A GQuark : the name of the module which computes the
1380 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1384 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1385 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1386 g_assert(trace_v
!= NULL
);
1388 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1389 LttvAttributeValue value
;
1390 GSList
**queue
, **current
;
1393 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1394 LTTV_REQUESTS_QUEUE
,
1397 queue
= (GSList
**)(value
.v_pointer
);
1400 while(iter
!= NULL
) {
1401 gboolean remove
= FALSE
;
1402 gboolean free_data
= FALSE
;
1404 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1406 if(bg_req
->module_name
== module_name
) {
1414 GSList
*remove_iter
= iter
;
1416 iter
= g_slist_next(iter
);
1417 if(free_data
) g_free(remove_iter
->data
);
1418 *queue
= g_slist_remove_link(*queue
, remove_iter
);
1419 } else { // not remove
1420 iter
= g_slist_next(iter
);
1425 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1426 LTTV_REQUESTS_CURRENT
,
1429 current
= (GSList
**)(value
.v_pointer
);
1432 while(iter
!= NULL
) {
1433 gboolean remove
= FALSE
;
1434 gboolean free_data
= FALSE
;
1436 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1438 if(bg_req
->module_name
== module_name
) {
1446 GSList
*remove_iter
= iter
;
1448 iter
= g_slist_next(iter
);
1449 if(free_data
) g_free(remove_iter
->data
);
1450 *current
= g_slist_remove_link(*current
, remove_iter
);
1451 } else { // not remove
1452 iter
= g_slist_next(iter
);
1460 * Unregister the background computation hooks for a specific module.
1462 * It also removes all the requests than can be currently processed by the
1463 * background computation algorithm for all the traces (list_in and list_out).
1465 * @param module_name A GQuark : the name of the module which computes the
1469 void lttvwindowtraces_unregister_computation_hooks
1470 (LttvAttributeName module_name
)
1472 LttvAttribute
*g_attribute
= lttv_global_attributes();
1473 LttvAttribute
*attribute
;
1474 LttvAttributeValue value
;
1476 g_assert(attribute
=
1477 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1478 LTTV_COMPUTATION
)));
1479 g_assert(attribute
=
1480 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1484 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1485 LTTV_BEFORE_CHUNK_TRACESET
,
1488 LttvHooks
*before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1489 if(before_chunk_traceset
!= NULL
)
1490 lttv_hooks_destroy(before_chunk_traceset
);
1492 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1493 LTTV_BEFORE_CHUNK_TRACE
,
1496 LttvHooks
*before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1497 if(before_chunk_trace
!= NULL
)
1498 lttv_hooks_destroy(before_chunk_trace
);
1500 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1501 LTTV_BEFORE_CHUNK_TRACEFILE
,
1504 LttvHooks
*before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1505 if(before_chunk_tracefile
!= NULL
)
1506 lttv_hooks_destroy(before_chunk_tracefile
);
1508 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1509 LTTV_AFTER_CHUNK_TRACESET
,
1512 LttvHooks
*after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1513 if(after_chunk_traceset
!= NULL
)
1514 lttv_hooks_destroy(after_chunk_traceset
);
1516 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1517 LTTV_AFTER_CHUNK_TRACE
,
1520 LttvHooks
*after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1521 if(after_chunk_trace
!= NULL
)
1522 lttv_hooks_destroy(after_chunk_trace
);
1524 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1525 LTTV_AFTER_CHUNK_TRACEFILE
,
1528 LttvHooks
*after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1529 if(after_chunk_tracefile
!= NULL
)
1530 lttv_hooks_destroy(after_chunk_tracefile
);
1532 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1533 LTTV_BEFORE_REQUEST
,
1536 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1537 if(before_request
!= NULL
)
1538 lttv_hooks_destroy(before_request
);
1540 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1544 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1545 if(after_request
!= NULL
)
1546 lttv_hooks_destroy(after_request
);
1548 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1552 LttvHooks
*event_hook
= (LttvHooks
*)*(value
.v_pointer
);
1553 if(event_hook
!= NULL
)
1554 lttv_hooks_destroy(event_hook
);
1556 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1557 LTTV_EVENT_HOOK_BY_ID
,
1560 LttvHooksById
*event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
1561 if(event_hook_by_id
!= NULL
)
1562 lttv_hooks_by_id_destroy(event_hook_by_id
);
1564 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1568 LttvHooks
*hook_adder
= (LttvHooks
*)*(value
.v_pointer
);
1569 if(hook_adder
!= NULL
)
1570 lttv_hooks_destroy(hook_adder
);
1572 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1576 LttvHooks
*hook_remover
= (LttvHooks
*)*(value
.v_pointer
);
1577 if(hook_remover
!= NULL
)
1578 lttv_hooks_destroy(hook_remover
);
1581 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1582 LTTV_EVENT_HOOK_BY_ID
);
1583 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1586 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1587 LTTV_AFTER_REQUEST
);
1588 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1589 LTTV_BEFORE_REQUEST
);
1591 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1592 LTTV_AFTER_CHUNK_TRACEFILE
);
1593 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1594 LTTV_AFTER_CHUNK_TRACE
);
1595 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1596 LTTV_AFTER_CHUNK_TRACESET
);
1598 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1599 LTTV_BEFORE_CHUNK_TRACEFILE
);
1600 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1601 LTTV_BEFORE_CHUNK_TRACE
);
1602 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1603 LTTV_BEFORE_CHUNK_TRACESET
);
1604 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1606 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1609 /* finally, remove module name */
1610 g_assert(attribute
=
1611 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1612 LTTV_COMPUTATION
)));
1613 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1619 * Lock a trace so no other instance can use it.
1621 * @param trace The trace to lock.
1622 * @return 0 on success, -1 if cannot get lock.
1624 gint
lttvwindowtraces_lock(LttvTrace
*trace
)
1626 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1627 LttvAttributeValue value
;
1628 LttvAttributeType type
;
1630 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1633 /* Verify the absence of the lock. */
1634 if(type
!= LTTV_NONE
) {
1635 g_critical("Cannot take trace lock");
1639 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
1642 /* the value is left unset. The only presence of the attribute is necessary.
1651 * @param trace The trace to unlock.
1652 * @return 0 on success, -1 if cannot unlock (not locked ?).
1654 gint
lttvwindowtraces_unlock(LttvTrace
*trace
)
1656 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1657 LttvAttributeType type
;
1658 LttvAttributeValue value
;
1660 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1663 /* Verify the presence of the lock. */
1664 if(type
== LTTV_NONE
) {
1665 g_critical("Cannot release trace lock");
1669 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1676 * Verify if a trace is locked.
1678 * @param trace The trace to verify.
1679 * @return TRUE if locked, FALSE is unlocked.
1681 gint
lttvwindowtraces_get_lock_state(LttvTrace
*trace
)
1683 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1684 LttvAttributeType type
;
1685 LttvAttributeValue value
;
1687 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1690 /* The only presence of the attribute is necessary. */
1691 if(type
== LTTV_NONE
)