Add the concept of a static trace
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 26 Apr 2017 17:18:26 +0000 (13:18 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 28 May 2017 16:57:41 +0000 (12:57 -0400)
A static trace is a frozen trace with the additional property that you
cannot call:

* bt_ctf_trace_add_stream_class()
* bt_ctf_trace_add_clock_class()
* bt_ctf_stream_create() with any stream that belongs to the trace

You can make a trace static with bt_ctf_trace_set_is_static(). This is
not a reversible operation. You can check if a trace is static with
bt_ctf_trace_is_static().

This static property can help a sink/filter component determine when the
trace is "finished", in that a static trace guarantees that its streams
are complete and there won't be more. It is up to the filter or sink
component to know when each stream is considered to be ended. The end of
a stream is provided by a notification. For example, a given filter
could receive two streams of a given trace on two different ports. In
this case, when the component gets both "stream end" notifications, and
when their trace is static, it can discard any resource associated with
this trace.

This feature is essential for a CTF writer sink component to put CTF
writer objects which are no longer needed. This is especially true when
working with a ctf.lttng-live source which "never ends": the sink
resources need to be released when it is known that there won't be more
streams for a given trace, otherwise this would be considered a leak.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
include/babeltrace/ctf-ir/trace-internal.h
include/babeltrace/ctf-ir/trace.h
lib/ctf-ir/stream-class.c
lib/ctf-ir/stream.c
lib/ctf-ir/trace.c

index eb3e0e27f26f139f4f4c96ac15a24f824b80c190..8b6c1f5a45ec6e99850b3c0de3a9478bb91a56e5 100644 (file)
@@ -67,6 +67,7 @@ struct bt_ctf_trace {
         */
        int valid;
        GPtrArray *listeners; /* Array of struct listener_wrapper */
+       bool is_static;
 };
 
 struct metadata_context {
index 858d9681624c6311671f4a1cac9068f26b8b5ae4..a9e4fa89e1bc6cd76e7eab6e5aee87c78c704878 100644 (file)
@@ -769,6 +769,48 @@ extern struct bt_ctf_stream *bt_ctf_trace_get_stream(
 @{
 */
 
+/**
+@brief Returns whether or not the CTF IR trace class \p trace_class
+       is static.
+
+It is guaranteed that a static trace class will never contain new
+streams, stream classes, or clock classes. A static class is always
+frozen.
+
+This function returns \c true if bt_ctf_trace_set_is_static() was
+previously called on it.
+
+@param[in] trace_class Trace class to check.
+@returns               \c true if \p trace_class is static,
+
+@sa bt_ctf_trace_set_is_static(): Makes a trace class static.
+*/
+extern bool bt_ctf_trace_is_static(struct bt_ctf_trace *trace_class);
+
+/**
+@brief Makes the CTF IR trace class \p trace_class static.
+
+A static trace class is frozen and you cannot call any modifying
+function on it:
+
+- bt_ctf_trace_add_stream_class()
+- bt_ctf_trace_add_clock_class()
+
+You cannot create a stream with bt_ctf_stream_create() with any of the
+stream classes of a static trace class.
+
+@param[in] trace_class Trace class to make static.
+@returns               0 on success, or a negative value on error.
+
+@prenotnull{trace_class}
+@postrefcountsame{trace_class}
+@postsuccessfrozen{trace_class}
+
+@sa bt_ctf_trace_is_static(): Checks whether or not a given trace class
+       is static.
+*/
+extern int bt_ctf_trace_set_is_static(struct bt_ctf_trace *trace_class);
+
 /**
 @brief Accepts the visitor \p visitor to visit the hierarchy of the
        CTF IR trace class \p trace_class.
index 4fac746800a0646508cc3d14af2044d2c71be3a4..0463a119e591f620f0fae02be0b9c7bde294f6c8 100644 (file)
@@ -336,6 +336,12 @@ int bt_ctf_stream_class_add_event_class(
                goto end;
        }
 
+       trace = bt_ctf_stream_class_get_trace(stream_class);
+       if (trace && trace->is_static) {
+               ret = -1;
+               goto end;
+       }
+
        event_id = g_new(int64_t, 1);
        if (!event_id) {
                ret = -1;
@@ -358,7 +364,6 @@ int bt_ctf_stream_class_add_event_class(
                goto end;
        }
 
-       trace = bt_ctf_stream_class_get_trace(stream_class);
        if (trace) {
                /*
                 * If the stream class is associated with a trace, then
index 949b11e9512f66889a90fe02d609017e8cfdd07d..7ab3544a8f41c061780b884248242e9c990ccaaf 100644 (file)
@@ -36,6 +36,7 @@
 #include <babeltrace/ctf-ir/stream.h>
 #include <babeltrace/ctf-ir/stream-internal.h>
 #include <babeltrace/ctf-ir/stream-class-internal.h>
+#include <babeltrace/ctf-ir/trace.h>
 #include <babeltrace/ctf-ir/trace-internal.h>
 #include <babeltrace/ctf-writer/writer-internal.h>
 #include <babeltrace/graph/component-internal.h>
@@ -367,6 +368,15 @@ struct bt_ctf_stream *bt_ctf_stream_create(
                goto error;
        }
 
+       if (bt_ctf_trace_is_static(trace)) {
+               /*
+                * A static trace has the property that all its stream
+                * classes, clock classes, and streams are definitive:
+                * no more can be added, and each object is also frozen.
+                */
+               goto error;
+       }
+
        stream = g_new0(struct bt_ctf_stream, 1);
        if (!stream) {
                goto error;
index b850b4ffe6e35495fcc07bad3eea2c2105a41a75..067e7db903d0937d494f6aecaa909270313bf06d 100644 (file)
@@ -389,7 +389,8 @@ int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace,
 {
        int ret = 0;
 
-       if (!trace || !bt_ctf_clock_class_is_valid(clock_class)) {
+       if (!trace || trace->is_static ||
+                       !bt_ctf_clock_class_is_valid(clock_class)) {
                ret = -1;
                goto end;
        }
@@ -457,7 +458,7 @@ int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace,
        int event_class_count;
        struct bt_ctf_trace *current_parent_trace = NULL;
 
-       if (!trace || !stream_class) {
+       if (!trace || !stream_class || trace->is_static) {
                ret = -1;
                goto end;
        }
@@ -1300,3 +1301,33 @@ end:
        bt_put(trace_packet_header_type);
        return ret;
 }
+
+bool bt_ctf_trace_is_static(struct bt_ctf_trace *trace)
+{
+       bool is_static = false;
+
+       if (!trace) {
+               goto end;
+       }
+
+       is_static = trace->is_static;
+
+end:
+       return is_static;
+}
+
+int bt_ctf_trace_set_is_static(struct bt_ctf_trace *trace)
+{
+       int ret = 0;
+
+       if (!trace) {
+               ret = -1;
+               goto end;
+       }
+
+       trace->is_static = true;
+       bt_ctf_trace_freeze(trace);
+
+end:
+       return ret;
+}
This page took 0.031396 seconds and 4 git commands to generate.