[sysprof: 9/63] libsysprof-capture: Move MappedRingBufferSource to libsysprof



commit b449baa205e7ab7b06276bc83b1c759789fc607e
Author: Philip Withnall <withnall endlessm com>
Date:   Tue Jun 30 16:43:48 2020 +0100

    libsysprof-capture: Move MappedRingBufferSource to libsysprof
    
    As preparation for dropping the GLib dependency from libsysprof-capture,
    move the `GSource` which links a `MappedRingBuffer` to a `GMainContext`
    from libsysprof-capture to libsysprof.
    
    This requires adding one new piece of API to libsysprof-capture to check
    whether the `MappedRingBuffer` is empty.
    
    Signed-off-by: Philip Withnall <withnall endlessm com>
    
    Helps: #40

 src/libsysprof-capture/mapped-ring-buffer.c | 114 +++++---------------------
 src/libsysprof-capture/mapped-ring-buffer.h |  11 +--
 src/libsysprof/mapped-ring-buffer-source.c  | 121 ++++++++++++++++++++++++++++
 src/libsysprof/mapped-ring-buffer-source.h  |  47 +++++++++++
 src/libsysprof/meson.build                  |   1 +
 src/libsysprof/sysprof-control-source.c     |   1 +
 6 files changed, 189 insertions(+), 106 deletions(-)
---
diff --git a/src/libsysprof-capture/mapped-ring-buffer.c b/src/libsysprof-capture/mapped-ring-buffer.c
index 656845c..ebc3ee9 100644
--- a/src/libsysprof-capture/mapped-ring-buffer.c
+++ b/src/libsysprof-capture/mapped-ring-buffer.c
@@ -530,107 +530,29 @@ mapped_ring_buffer_drain (MappedRingBuffer         *self,
   return TRUE;
 }
 
-typedef struct _MappedRingSource
-{
-  GSource           source;
-  MappedRingBuffer *self;
-} MappedRingSource;
-
-static gboolean
-mapped_ring_source_dispatch (GSource     *source,
-                             GSourceFunc  callback,
-                             gpointer     user_data)
-{
-  MappedRingSource *real_source = (MappedRingSource *)source;
-
-  g_assert (source != NULL);
-
-  return mapped_ring_buffer_drain (real_source->self,
-                                   (MappedRingBufferCallback)callback,
-                                   user_data);
-}
-
-static void
-mapped_ring_source_finalize (GSource *source)
-{
-  MappedRingSource *real_source = (MappedRingSource *)source;
-
-  if (real_source != NULL)
-    g_clear_pointer (&real_source->self, mapped_ring_buffer_unref);
-}
-
-static gboolean
-mapped_ring_source_check (GSource *source)
-{
-  MappedRingSource *real_source = (MappedRingSource *)source;
-  MappedRingHeader *header;
-
-  g_assert (real_source != NULL);
-  g_assert (real_source->self != NULL);
-
-  header = get_header (real_source->self);
-
-  if (g_atomic_int_get (&header->head) != g_atomic_int_get (&header->tail))
-    return TRUE;
-
-  return FALSE;
-}
-
-static gboolean
-mapped_ring_source_prepare (GSource *source,
-                            gint    *timeout_)
+/**
+ * mapped_ring_buffer_is_empty:
+ * @self: a #MappedRingBuffer
+ *
+ * Checks whether the ring buffer is currently empty.
+ *
+ * This should only be called by a reader created with
+ * mapped_ring_buffer_new_reader().
+ *
+ * Returns: %TRUE if the buffer is empty, %FALSE otherwise
+ */
+gboolean
+mapped_ring_buffer_is_empty (MappedRingBuffer *self)
 {
-  MappedRingSource *real_source = (MappedRingSource *)source;
   MappedRingHeader *header;
+  guint32 headpos, tailpos;
 
-  g_assert (real_source != NULL);
-  g_assert (real_source->self != NULL);
-
-  header = get_header (real_source->self);
-
-  if (g_atomic_int_get (&header->head) != g_atomic_int_get (&header->tail))
-    return TRUE;
-
-  *timeout_ = 5;
-
-  return FALSE;
-}
-
-static GSourceFuncs mapped_ring_source_funcs = {
-  .prepare  = mapped_ring_source_prepare,
-  .check    = mapped_ring_source_check,
-  .dispatch = mapped_ring_source_dispatch,
-  .finalize = mapped_ring_source_finalize,
-};
-
-guint
-mapped_ring_buffer_create_source_full (MappedRingBuffer         *self,
-                                       MappedRingBufferCallback  source_func,
-                                       gpointer                  user_data,
-                                       GDestroyNotify            destroy)
-{
-  MappedRingSource *source;
-  guint ret;
-
-  g_return_val_if_fail (self != NULL, 0);
-  g_return_val_if_fail (source_func != NULL, 0);
-
-  source = (MappedRingSource *)g_source_new (&mapped_ring_source_funcs, sizeof (MappedRingSource));
-  source->self = mapped_ring_buffer_ref (self);
-  g_source_set_callback ((GSource *)source, (GSourceFunc)source_func, user_data, destroy);
-  g_source_set_name ((GSource *)source, "MappedRingSource");
-  ret = g_source_attach ((GSource *)source, g_main_context_default ());
-  g_source_unref ((GSource *)source);
+  header = get_header (self);
 
-  return ret;
-}
+  headpos = g_atomic_int_get (&header->head);
+  tailpos = g_atomic_int_get (&header->tail);
 
-guint
-mapped_ring_buffer_create_source (MappedRingBuffer         *self,
-                                  MappedRingBufferCallback  source_func,
-                                  gpointer                  user_data)
-{
-  return mapped_ring_buffer_create_source_full (self, source_func, user_data, NULL);
+  return headpos == tailpos;
 }
 
 /**
diff --git a/src/libsysprof-capture/mapped-ring-buffer.h b/src/libsysprof-capture/mapped-ring-buffer.h
index 4eee695..19740e1 100644
--- a/src/libsysprof-capture/mapped-ring-buffer.h
+++ b/src/libsysprof-capture/mapped-ring-buffer.h
@@ -78,15 +78,6 @@ gboolean          mapped_ring_buffer_drain              (MappedRingBuffer
                                                          MappedRingBufferCallback  callback,
                                                          gpointer                  user_data);
 G_GNUC_INTERNAL
-guint             mapped_ring_buffer_create_source      (MappedRingBuffer         *self,
-                                                         MappedRingBufferCallback  callback,
-                                                         gpointer                  user_data);
-G_GNUC_INTERNAL
-guint             mapped_ring_buffer_create_source_full (MappedRingBuffer         *self,
-                                                         MappedRingBufferCallback  callback,
-                                                         gpointer                  user_data,
-                                                         GDestroyNotify            destroy);
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (MappedRingBuffer, mapped_ring_buffer_unref)
+gboolean          mapped_ring_buffer_is_empty           (MappedRingBuffer         *self);
 
 G_END_DECLS
diff --git a/src/libsysprof/mapped-ring-buffer-source.c b/src/libsysprof/mapped-ring-buffer-source.c
new file mode 100644
index 0000000..fdeb4b7
--- /dev/null
+++ b/src/libsysprof/mapped-ring-buffer-source.c
@@ -0,0 +1,121 @@
+/* mapped-ring-buffer-source.c
+ *
+ * Copyright 2020 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "sysprof-mapped-ring-buffer-source"
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "mapped-ring-buffer-source.h"
+
+typedef struct _MappedRingSource
+{
+  GSource           source;
+  MappedRingBuffer *buffer;
+} MappedRingSource;
+
+static gboolean
+mapped_ring_source_dispatch (GSource     *source,
+                             GSourceFunc  callback,
+                             gpointer     user_data)
+{
+  MappedRingSource *real_source = (MappedRingSource *)source;
+
+  g_assert (source != NULL);
+
+  return mapped_ring_buffer_drain (real_source->buffer,
+                                   (MappedRingBufferCallback)callback,
+                                   user_data);
+}
+
+static void
+mapped_ring_source_finalize (GSource *source)
+{
+  MappedRingSource *real_source = (MappedRingSource *)source;
+
+  if (real_source != NULL)
+    g_clear_pointer (&real_source->buffer, mapped_ring_buffer_unref);
+}
+
+static gboolean
+mapped_ring_source_check (GSource *source)
+{
+  MappedRingSource *real_source = (MappedRingSource *)source;
+
+  g_assert (real_source != NULL);
+  g_assert (real_source->buffer != NULL);
+
+  return !mapped_ring_buffer_is_empty (real_source->buffer);
+}
+
+static gboolean
+mapped_ring_source_prepare (GSource *source,
+                            gint    *timeout_)
+{
+  MappedRingSource *real_source = (MappedRingSource *)source;
+
+  g_assert (real_source != NULL);
+  g_assert (real_source->buffer != NULL);
+
+  if (!mapped_ring_buffer_is_empty (real_source->buffer))
+    return TRUE;
+
+  *timeout_ = 5;
+
+  return FALSE;
+}
+
+static GSourceFuncs mapped_ring_source_funcs = {
+  .prepare  = mapped_ring_source_prepare,
+  .check    = mapped_ring_source_check,
+  .dispatch = mapped_ring_source_dispatch,
+  .finalize = mapped_ring_source_finalize,
+};
+
+guint
+mapped_ring_buffer_create_source_full (MappedRingBuffer         *self,
+                                       MappedRingBufferCallback  source_func,
+                                       gpointer                  user_data,
+                                       GDestroyNotify            destroy)
+{
+  MappedRingSource *source;
+  guint ret;
+
+  g_return_val_if_fail (self != NULL, 0);
+  g_return_val_if_fail (source_func != NULL, 0);
+
+  source = (MappedRingSource *)g_source_new (&mapped_ring_source_funcs, sizeof (MappedRingSource));
+  source->buffer = mapped_ring_buffer_ref (self);
+  g_source_set_callback ((GSource *)source, (GSourceFunc)source_func, user_data, destroy);
+  g_source_set_name ((GSource *)source, "MappedRingSource");
+  ret = g_source_attach ((GSource *)source, g_main_context_default ());
+  g_source_unref ((GSource *)source);
+
+  return ret;
+}
+
+guint
+mapped_ring_buffer_create_source (MappedRingBuffer         *self,
+                                  MappedRingBufferCallback  source_func,
+                                  gpointer                  user_data)
+{
+  return mapped_ring_buffer_create_source_full (self, source_func, user_data, NULL);
+}
diff --git a/src/libsysprof/mapped-ring-buffer-source.h b/src/libsysprof/mapped-ring-buffer-source.h
new file mode 100644
index 0000000..167f4c8
--- /dev/null
+++ b/src/libsysprof/mapped-ring-buffer-source.h
@@ -0,0 +1,47 @@
+/* mapped-ring-buffer-source.h
+ *
+ * Copyright 2020 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#if !defined (SYSPROF_INSIDE) && !defined (SYSPROF_COMPILATION)
+# error "Only <sysprof.h> can be included directly."
+#endif
+
+#include <glib.h>
+
+#include "sysprof-version-macros.h"
+
+#include "mapped-ring-buffer.h"
+
+G_BEGIN_DECLS
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (MappedRingBuffer, mapped_ring_buffer_unref)
+
+G_GNUC_INTERNAL
+guint             mapped_ring_buffer_create_source      (MappedRingBuffer         *self,
+                                                         MappedRingBufferCallback  callback,
+                                                         gpointer                  user_data);
+G_GNUC_INTERNAL
+guint             mapped_ring_buffer_create_source_full (MappedRingBuffer         *self,
+                                                         MappedRingBufferCallback  callback,
+                                                         gpointer                  user_data,
+                                                         GDestroyNotify            destroy);
+
+G_END_DECLS
diff --git a/src/libsysprof/meson.build b/src/libsysprof/meson.build
index e2df0b8..cc5f96f 100644
--- a/src/libsysprof/meson.build
+++ b/src/libsysprof/meson.build
@@ -72,6 +72,7 @@ libsysprof_private_sources = [
   'binfile.c',
   'demangle.cpp',
   'elfparser.c',
+  'mapped-ring-buffer-source.c',
   'sysprof-flatpak.c',
   'sysprof-helpers.c',
   'sysprof-kallsyms.c',
diff --git a/src/libsysprof/sysprof-control-source.c b/src/libsysprof/sysprof-control-source.c
index 4ccdc48..fdf8f50 100644
--- a/src/libsysprof/sysprof-control-source.c
+++ b/src/libsysprof/sysprof-control-source.c
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 
 #include "mapped-ring-buffer.h"
+#include "mapped-ring-buffer-source.h"
 
 #include "sysprof-control-source.h"
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]