ir: make bt_ctf_stream_create() public
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 17 Feb 2016 21:52:05 +0000 (16:52 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 22 Feb 2016 17:49:16 +0000 (12:49 -0500)
This patch also removes bt_ctf_trace_create_stream(), so that the
only way to create a stream in non-writer mode is using
bt_ctf_stream_create(). Only the stream class is needed, and since
it needs to be part of a trace before calling the function, the
created stream gets associated to this trace on creation.

The function also knows if the stream class's trace was created by
a CTF writer thanks to a new flag. With this, it's able to create
a stream file and set the stream's FD if it's a writer stream.
Otherwise the FD is set to -1 and this stream cannot be passed to
stream writer functions like bt_ctf_stream_append_event() and
bt_ctf_stream_append_discarded_events(), for example.

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

index 4339010e1846f1b8a7fbbcbbac9a01b8e24e0a79..b3081de487749d101906d92e33438720b305f14e 100644 (file)
@@ -35,6 +35,8 @@
 #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-internal.h>
+#include <babeltrace/ctf-writer/writer-internal.h>
 #include <babeltrace/ref.h>
 #include <babeltrace/ctf-writer/functor-internal.h>
 #include <babeltrace/compiler.h>
@@ -252,15 +254,64 @@ void release_event(struct bt_ctf_event *event)
        }
 }
 
-BT_HIDDEN
+static
+int create_stream_file(struct bt_ctf_writer *writer,
+               struct bt_ctf_stream *stream)
+{
+       int fd;
+       GString *filename = g_string_new(stream->stream_class->name->str);
+
+       if (stream->stream_class->name->len == 0) {
+               int64_t ret;
+
+               ret = bt_ctf_stream_class_get_id(stream->stream_class);
+               if (ret < 0) {
+                       fd = -1;
+                       goto error;
+               }
+
+               g_string_printf(filename, "stream_%" PRId64, ret);
+       }
+
+       g_string_append_printf(filename, "_%" PRIu32, stream->id);
+       fd = openat(writer->trace_dir_fd, filename->str,
+               O_RDWR | O_CREAT | O_TRUNC,
+               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+error:
+       g_string_free(filename, TRUE);
+       return fd;
+}
+
+static
+int set_stream_fd(struct bt_ctf_stream *stream, int fd)
+{
+       int ret = 0;
+
+       if (stream->pos.fd != -1) {
+               ret = -1;
+               goto end;
+       }
+
+       ctf_init_pos(&stream->pos, NULL, fd, O_RDWR);
+       stream->pos.fd = fd;
+end:
+       return ret;
+}
+
 struct bt_ctf_stream *bt_ctf_stream_create(
-       struct bt_ctf_stream_class *stream_class,
-       struct bt_ctf_trace *trace)
+               struct bt_ctf_stream_class *stream_class)
 {
        int ret;
        struct bt_ctf_stream *stream = NULL;
+       struct bt_ctf_trace *trace = NULL;
+       struct bt_ctf_writer *writer = NULL;
 
-       if (!stream_class || !trace) {
+       if (!stream_class) {
+               goto end;
+       }
+
+       trace = bt_ctf_stream_class_get_trace(stream_class);
+       if (!trace) {
                goto end;
        }
 
@@ -275,70 +326,91 @@ struct bt_ctf_stream *bt_ctf_stream_create(
         * reachable; it needs its parent to remain valid.
         */
        bt_object_set_parent(stream, trace);
-       stream->packet_context = bt_ctf_field_create(
-               stream_class->packet_context_type);
-       if (!stream->packet_context) {
-               goto error;
-       }
-
-       /* Initialize events_discarded */
-       ret = set_structure_field_integer(stream->packet_context,
-               "events_discarded", 0);
-       if (ret) {
-               goto error;
-       }
-
-       stream->pos.fd = -1;
        stream->id = stream_class->next_stream_id++;
        stream->stream_class = stream_class;
-       stream->events = g_ptr_array_new_with_free_func(
-               (GDestroyNotify) release_event);
-       if (!stream->events) {
-               goto error;
-       }
+       stream->pos.fd = -1;
 
-       /* A trace is not allowed to have a NULL packet header */
-       assert(trace->packet_header_type);
-       stream->packet_header = bt_ctf_field_create(trace->packet_header_type);
-       if (!stream->packet_header) {
-               goto error;
-       }
-       /*
-        * Attempt to populate the default trace packet header fields
-        * (magic, uuid and stream_id). This will _not_ fail shall the
-        * fields not be found or be of an incompatible type; they will
-        * simply not be populated automatically. The user will have to
-        * make sure to set the trace packet header fields himself before
-        * flushing.
-        */
-       ret = set_packet_header(stream);
-       if (ret) {
-               goto error;
+       if (trace->is_created_by_writer) {
+               int fd;
+               writer = (struct bt_ctf_writer *)
+                       bt_object_get_parent(trace);
+
+               assert(writer);
+               stream->packet_context = bt_ctf_field_create(
+                       stream_class->packet_context_type);
+               if (!stream->packet_context) {
+                       goto error;
+               }
+
+               /* Initialize events_discarded */
+               ret = set_structure_field_integer(stream->packet_context,
+                       "events_discarded", 0);
+               if (ret) {
+                       goto error;
+               }
+
+               stream->events = g_ptr_array_new_with_free_func(
+                       (GDestroyNotify) release_event);
+               if (!stream->events) {
+                       goto error;
+               }
+
+               /* A trace is not allowed to have a NULL packet header */
+               assert(trace->packet_header_type);
+               stream->packet_header =
+                       bt_ctf_field_create(trace->packet_header_type);
+               if (!stream->packet_header) {
+                       goto error;
+               }
+
+               /*
+                * Attempt to populate the default trace packet header fields
+                * (magic, uuid and stream_id). This will _not_ fail shall the
+                * fields not be found or be of an incompatible type; they will
+                * simply not be populated automatically. The user will have to
+                * make sure to set the trace packet header fields himself
+                * before flushing.
+                */
+               ret = set_packet_header(stream);
+               if (ret) {
+                       goto error;
+               }
+
+               /* Create file associated with this stream */
+               fd = create_stream_file(writer, stream);
+               if (fd < 0) {
+                       goto error;
+               }
+
+               ret = set_stream_fd(stream, fd);
+               if (ret) {
+                       goto error;
+               }
+
+               /* Freeze the writer */
+               bt_ctf_writer_freeze(writer);
+       } else {
+               /* Non-writer stream indicated by a negative FD */
+               ret = set_stream_fd(stream, -1);
+               if (ret) {
+                       goto error;
+               }
        }
+
+       /* Add this stream to the trace's streams */
+       g_ptr_array_add(trace->streams, stream);
+
 end:
+       BT_PUT(trace);
+       BT_PUT(writer);
        return stream;
 error:
        BT_PUT(stream);
-       bt_put(trace);
+       BT_PUT(trace);
+       BT_PUT(writer);
        return stream;
 }
 
-BT_HIDDEN
-int bt_ctf_stream_set_fd(struct bt_ctf_stream *stream, int fd)
-{
-       int ret = 0;
-
-       if (stream->pos.fd != -1) {
-               ret = -1;
-               goto end;
-       }
-
-       ctf_init_pos(&stream->pos, NULL, fd, O_RDWR);
-       stream->pos.fd = fd;
-end:
-       return ret;
-}
-
 struct bt_ctf_stream_class *bt_ctf_stream_get_class(
                struct bt_ctf_stream *stream)
 {
index 2c0e7670f627600ef4bf7dc8ab3e7cbbd1aa02be..686ba798c4a9c1428f6dcc110208433086c16d92 100644 (file)
@@ -136,43 +136,6 @@ void bt_ctf_trace_destroy(struct bt_object *obj)
        g_free(trace);
 }
 
-struct bt_ctf_stream *bt_ctf_trace_create_stream(struct bt_ctf_trace *trace,
-               struct bt_ctf_stream_class *stream_class)
-{
-       int ret;
-       int stream_class_found = 0;
-       size_t i;
-       struct bt_ctf_stream *stream = NULL;
-
-       if (!trace || !stream_class) {
-               goto error;
-       }
-
-       for (i = 0; i < trace->stream_classes->len; i++) {
-               if (trace->stream_classes->pdata[i] == stream_class) {
-                       stream_class_found = 1;
-               }
-       }
-
-       if (!stream_class_found) {
-               ret = bt_ctf_trace_add_stream_class(trace, stream_class);
-               if (ret) {
-                       goto error;
-               }
-       }
-
-       stream = bt_ctf_stream_create(stream_class, trace);
-       if (!stream) {
-               goto error;
-       }
-
-       g_ptr_array_add(trace->streams, stream);
-       return stream;
-error:
-        BT_PUT(stream);
-       return stream;
-}
-
 int bt_ctf_trace_set_environment_field(struct bt_ctf_trace *trace,
                const char *name, struct bt_value *value)
 {
index babe033b03931e6e9219cd54c2ee02ff0cf231ae..fe6f52cbf918372094a18d95c00e65702c150a01 100644 (file)
@@ -33,6 +33,7 @@
 #include <babeltrace/ctf-writer/functor-internal.h>
 #include <babeltrace/ctf-ir/stream-class-internal.h>
 #include <babeltrace/ctf-ir/stream-internal.h>
+#include <babeltrace/ctf-ir/trace-internal.h>
 #include <babeltrace/ref.h>
 #include <babeltrace/compiler.h>
 #include <stdio.h>
 static
 void bt_ctf_writer_destroy(struct bt_object *obj);
 
-static
-int create_stream_file(struct bt_ctf_writer *writer,
-               struct bt_ctf_stream *stream);
-
 struct bt_ctf_writer *bt_ctf_writer_create(const char *path)
 {
        struct bt_ctf_writer *writer = NULL;
@@ -74,6 +71,7 @@ struct bt_ctf_writer *bt_ctf_writer_create(const char *path)
                goto error_destroy;
        }
 
+       writer->trace->is_created_by_writer = 1;
        bt_object_set_parent(writer->trace, writer);
        bt_put(writer->trace);
        /* Create trace directory if necessary and open a metadata file */
@@ -144,24 +142,50 @@ end:
 struct bt_ctf_stream *bt_ctf_writer_create_stream(struct bt_ctf_writer *writer,
                struct bt_ctf_stream_class *stream_class)
 {
-       int stream_fd;
        struct bt_ctf_stream *stream = NULL;
+       int stream_class_count;
+       bool stream_class_found = false;
+       int i;
 
        if (!writer || !stream_class) {
                goto error;
        }
 
-       stream = bt_ctf_trace_create_stream(writer->trace, stream_class);
-       if (!stream) {
+       /* Make sure the stream class is part of the writer's trace */
+       stream_class_count = bt_ctf_trace_get_stream_class_count(writer->trace);
+       if (stream_class_count < 0) {
                goto error;
        }
 
-       stream_fd = create_stream_file(writer, stream);
-       if (stream_fd < 0 || bt_ctf_stream_set_fd(stream, stream_fd)) {
+       for (i = 0; i < stream_class_count; i++) {
+               struct bt_ctf_stream_class *existing_stream_class =
+                       bt_ctf_trace_get_stream_class(writer->trace, i);
+
+               if (existing_stream_class == stream_class) {
+                       stream_class_found = true;
+               }
+
+               BT_PUT(existing_stream_class);
+
+               if (stream_class_found) {
+                       break;
+               }
+       }
+
+       if (!stream_class_found) {
+               int ret = bt_ctf_trace_add_stream_class(writer->trace,
+                       stream_class);
+
+               if (ret) {
+                       goto error;
+               }
+       }
+
+       stream = bt_ctf_stream_create(stream_class);
+       if (!stream) {
                goto error;
        }
 
-       writer->frozen = 1;
        return stream;
 
 error:
@@ -274,30 +298,8 @@ void bt_ctf_writer_put(struct bt_ctf_writer *writer)
        bt_put(writer);
 }
 
-static
-int create_stream_file(struct bt_ctf_writer *writer,
-               struct bt_ctf_stream *stream)
+BT_HIDDEN
+void bt_ctf_writer_freeze(struct bt_ctf_writer *writer)
 {
-       int fd;
-       GString *filename = g_string_new(stream->stream_class->name->str);
-
-       if (stream->stream_class->name->len == 0) {
-               int64_t ret;
-
-               ret = bt_ctf_stream_class_get_id(stream->stream_class);
-               if (ret < 0) {
-                       fd = -1;
-                       goto error;
-               }
-
-               g_string_printf(filename, "stream_%" PRId64, ret);
-       }
-
-       g_string_append_printf(filename, "_%" PRIu32, stream->id);
-       fd = openat(writer->trace_dir_fd, filename->str,
-               O_RDWR | O_CREAT | O_TRUNC,
-               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-error:
-       g_string_free(filename, TRUE);
-       return fd;
+       writer->frozen = 1;
 }
index 7461d321f0fe34c85c67a9898dd04fd29a25da8a..155794042d0eee1b89963d0e498ed9cd4257b2cd 100644 (file)
@@ -50,12 +50,6 @@ struct bt_ctf_stream {
        struct bt_ctf_field *event_context;
 };
 
-/* Stream class should be frozen by the caller after creating a stream */
-BT_HIDDEN
-struct bt_ctf_stream *bt_ctf_stream_create(
-               struct bt_ctf_stream_class *stream_class,
-               struct bt_ctf_trace *trace);
-
 BT_HIDDEN
 int bt_ctf_stream_set_fd(struct bt_ctf_stream *stream, int fd);
 
index 410aba7c1377742e77b5ed6d321967ead0256910..53f02da676dcad49444b5bcae776e3ce2f6751fe 100644 (file)
@@ -40,6 +40,9 @@ extern "C" {
 struct bt_ctf_event;
 struct bt_ctf_stream;
 
+extern struct bt_ctf_stream *bt_ctf_stream_create(
+               struct bt_ctf_stream_class *stream_class);
+
 /*
  * bt_ctf_stream_get_stream_class: get a stream's class.
  *
index eb8a256341dfa34f2ebac893631759620afdef51..f9091425b0d111523760620d4414861d769d7862 100644 (file)
@@ -58,6 +58,7 @@ struct bt_ctf_trace {
        GPtrArray *streams; /* Array of ptrs to bt_ctf_stream */
        struct bt_ctf_field_type *packet_header_type;
        uint64_t next_stream_id;
+       int is_created_by_writer;
 
        /*
         * This flag indicates if the trace is valid. A valid
index ec9d2a0532c82e540b1c54bcc244a18dad32817f..ee740039829052cf6367cca4d9feaba46c84e1f5 100644 (file)
@@ -58,21 +58,6 @@ struct bt_ctf_clock;
  */
 extern struct bt_ctf_trace *bt_ctf_trace_create(void);
 
-/*
- * bt_ctf_trace_create_stream: create a stream instance.
- *
- * Allocate a new stream instance and register it to the trace. The creation of
- * a stream sets its reference count to 1.
- *
- * @param trace Trace instance.
- * @param stream_class Stream class to instantiate.
- *
- * Returns a new stream on success, NULL on error.
- */
-extern struct bt_ctf_stream *bt_ctf_trace_create_stream(
-               struct bt_ctf_trace *trace,
-               struct bt_ctf_stream_class *stream_class);
-
 /*
  * bt_ctf_trace_set_environment_field: sets an environment field to the
  *     trace.
index 2857bdd939615794cfcc82054df94650df2c536d..3fa03b5953cc33bcdd5145ffe5edeb3fcbfe2a0e 100644 (file)
@@ -44,4 +44,7 @@ struct bt_ctf_writer {
        int metadata_fd;
 };
 
+BT_HIDDEN
+void bt_ctf_writer_freeze(struct bt_ctf_writer *writer);
+
 #endif /* BABELTRACE_CTF_WRITER_WRITER_INTERNAL_H */
This page took 0.032837 seconds and 4 git commands to generate.