Export consumer ABI, implement ring buffer modifications for consumer
[lttng-ust.git] / libust / lttng-ust-abi.c
index 01512128f24b478e9bea2bef795ba89eb04e97b7..cea8c30bffe8d29e39d4792bbfd6032b62c21d4c 100644 (file)
  * by the caller.
  */
 
-struct obj;
-
-struct objd_ops {
-       long (*cmd)(int objd, unsigned int cmd, unsigned long arg);
-       int (*release)(int objd);
-};
-
 struct obj {
        union {
                struct {
@@ -131,10 +124,10 @@ void objd_set_private(int id, void *private_data)
        obj->u.s.private_data = private_data;
 }
 
-static
 const struct objd_ops *objd_ops(int id)
 {
        struct obj *obj = _objd_get(id);
+
        if (!obj)
                return NULL;
        return obj->u.s.ops;
@@ -195,6 +188,10 @@ void objd_table_destroy(void)
                        ops->release(i);
        }
        free(objd_table.array);
+       objd_table.array = NULL;
+       objd_table.len = 0;
+       objd_table.allocated_len = 0;
+       objd_table.freelist_head = -1;
 }
 
 /*
@@ -207,12 +204,23 @@ static const struct objd_ops lttng_session_ops;
 static const struct objd_ops lttng_channel_ops;
 static const struct objd_ops lttng_metadata_ops;
 static const struct objd_ops lttng_event_ops;
+static const struct objd_ops lib_ring_buffer_objd_ops;
 
 enum channel_type {
        PER_CPU_CHANNEL,
        METADATA_CHANNEL,
 };
 
+int lttng_abi_create_root_handle(void)
+{
+       int root_handle;
+
+       root_handle = objd_alloc(NULL, &lttng_ops);
+       assert(root_handle == 0);
+       return root_handle;
+}
+
+static
 int lttng_abi_create_session(void)
 {
        struct ltt_session *session;
@@ -355,7 +363,6 @@ create_error:
        return;         /* not allowed to return error */
 }
 
-static
 int lttng_abi_create_channel(int session_objd,
                             struct lttng_ust_channel *chan_param,
                             enum channel_type channel_type)
@@ -401,7 +408,10 @@ int lttng_abi_create_channel(int session_objd,
                                  chan_param->subbuf_size,
                                  chan_param->num_subbuf,
                                  chan_param->switch_timer_interval,
-                                 chan_param->read_timer_interval);
+                                 chan_param->read_timer_interval,
+                                 &chan_param->shm_fd,
+                                 &chan_param->wait_fd,
+                                 &chan_param->memory_map_size);
        if (!chan) {
                ret = -EINVAL;
                goto chan_error;
@@ -499,35 +509,46 @@ static const struct objd_ops lttng_session_ops = {
        .cmd = lttng_session_cmd,
 };
 
-#if 0
+struct stream_priv_data {
+       struct lib_ring_buffer *buf;
+       struct ltt_channel *ltt_chan;
+};
+
 static
-int lttng_abi_open_stream(int channel_objd)
+int lttng_abi_open_stream(int channel_objd, struct lttng_ust_stream *info)
 {
        struct ltt_channel *channel = objd_private(channel_objd);
        struct lib_ring_buffer *buf;
+       struct stream_priv_data *priv;
        int stream_objd, ret;
 
-       buf = channel->ops->buffer_read_open(channel->chan);
+       buf = channel->ops->buffer_read_open(channel->chan, channel->handle,
+                       &info->shm_fd, &info->wait_fd, &info->memory_map_size);
        if (!buf)
                return -ENOENT;
 
-       stream_objd = objd_alloc(buf, &lib_ring_buffer_objd_ops);
+       priv = zmalloc(sizeof(*priv));
+       if (!priv) {
+               ret = -ENOMEM;
+               goto alloc_error;
+       }
+       priv->buf = buf;
+       priv->ltt_chan = channel;
+       stream_objd = objd_alloc(priv, &lib_ring_buffer_objd_ops);
        if (stream_objd < 0) {
                ret = stream_objd;
                goto objd_error;
        }
-       /*
-        * The stream holds a reference to the channel within the generic ring
-        * buffer library, so no need to hold a refcount on the channel and
-        * session files here.
-        */
+       /* Hold a reference on the channel object descriptor */
+       objd_ref(channel_objd);
        return stream_objd;
 
 objd_error:
-       channel->ops->buffer_read_close(buf);
+       free(priv);
+alloc_error:
+       channel->ops->buffer_read_close(buf, channel->handle);
        return ret;
 }
-#endif //0
 
 static
 int lttng_abi_create_event(int channel_objd,
@@ -597,8 +618,13 @@ long lttng_channel_cmd(int objd, unsigned int cmd, unsigned long arg)
 
        switch (cmd) {
        case LTTNG_UST_STREAM:
-               return -ENOSYS; //TODO
-               //return lttng_abi_open_stream(objd);
+       {
+               struct lttng_ust_stream *stream;
+
+               stream = (struct lttng_ust_stream *) arg;
+               /* stream used as output */
+               return lttng_abi_open_stream(objd, stream);
+       }
        case LTTNG_UST_EVENT:
                return lttng_abi_create_event(objd, (struct lttng_ust_event *) arg);
        case LTTNG_UST_CONTEXT:
@@ -632,8 +658,13 @@ long lttng_metadata_cmd(int objd, unsigned int cmd, unsigned long arg)
 {
        switch (cmd) {
        case LTTNG_UST_STREAM:
-               return -ENOSYS; //TODO
-               //return lttng_abi_open_stream(objd);
+       {
+               struct lttng_ust_stream *stream;
+
+               stream = (struct lttng_ust_stream *) arg;
+               /* stream used as output */
+               return lttng_abi_open_stream(objd, stream);
+       }
        default:
                return -EINVAL;
        }
@@ -690,6 +721,50 @@ static const struct objd_ops lttng_metadata_ops = {
        .cmd = lttng_metadata_cmd,
 };
 
+/**
+ *     lttng_rb_cmd - lttng ring buffer control through object descriptors
+ *
+ *     @objd: the object descriptor
+ *     @cmd: the command
+ *     @arg: command arg
+ *
+ *     This object descriptor implements lttng commands:
+ *             (None for now. Access is done directly though shm.)
+ *             TODO: Add buffer flush.
+ */
+static
+long lttng_rb_cmd(int objd, unsigned int cmd, unsigned long arg)
+{
+       struct stream_priv_data *priv = objd_private(objd);
+
+       switch (cmd) {
+       default:
+               return -EINVAL;
+       }
+}
+
+static
+int lttng_rb_release(int objd)
+{
+       struct stream_priv_data *priv = objd_private(objd);
+       struct lib_ring_buffer *buf;
+       struct ltt_channel *channel;
+
+       if (priv) {
+               buf = priv->buf;
+               channel = priv->ltt_chan;
+               free(priv);
+
+               return objd_unref(channel->objd);
+       }
+       return 0;
+}
+
+static const struct objd_ops lib_ring_buffer_objd_ops = {
+       .release = lttng_rb_release,
+       .cmd = lttng_rb_cmd,
+};
+
 /**
  *     lttng_event_cmd - lttng control through object descriptors
  *
This page took 0.027046 seconds and 4 git commands to generate.