Hello community, here is the log from the commit of package libdazzle for openSUSE:Factory checked in at 2018-06-22 13:28:36 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libdazzle (Old) and /work/SRC/openSUSE:Factory/.libdazzle.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libdazzle" Fri Jun 22 13:28:36 2018 rev:9 rq:617888 version:3.28.3 Changes: -------- --- /work/SRC/openSUSE:Factory/libdazzle/libdazzle.changes 2018-06-02 11:55:14.309199355 +0200 +++ /work/SRC/openSUSE:Factory/.libdazzle.new/libdazzle.changes 2018-06-22 13:28:38.857588637 +0200 @@ -1,0 +2,11 @@ +Tue Jun 19 16:47:10 UTC 2018 - [email protected] + +- Update to version 3.28.3: + + Animation uses g_signal_connect_object() to simplify lifecycle + tracking. + + CPU graph model now re-uses FDs and parse buffers. + + Realtime graphs now try harder to detect when the widget is + obscured to reduce overhead in that situation. + + GCancellable chaining tries harder to release state struct. + +------------------------------------------------------------------- Old: ---- libdazzle-3.28.2.tar.xz New: ---- libdazzle-3.28.3.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libdazzle.spec ++++++ --- /var/tmp/diff_new_pack.o6NtPW/_old 2018-06-22 13:28:39.805553602 +0200 +++ /var/tmp/diff_new_pack.o6NtPW/_new 2018-06-22 13:28:39.809553454 +0200 @@ -17,13 +17,14 @@ Name: libdazzle -Version: 3.28.2 +Version: 3.28.3 Release: 0 Summary: Collection of fancy features for GLib and Gtk+ License: GPL-3.0-or-later AND LGPL-2.1-or-later Group: Development/Tools/Other URL: https://gitlab.gnome.org/GNOME/libdazzle Source0: http://download.gnome.org/sources/libdazzle/3.28/%{name}-%{version}.tar.xz + BuildRequires: gtk-doc BuildRequires: meson BuildRequires: pkgconfig ++++++ libdazzle-3.28.2.tar.xz -> libdazzle-3.28.3.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdazzle-3.28.2/NEWS new/libdazzle-3.28.3/NEWS --- old/libdazzle-3.28.2/NEWS 2018-05-23 23:04:13.000000000 +0200 +++ new/libdazzle-3.28.3/NEWS 2018-06-19 05:31:27.000000000 +0200 @@ -1,4 +1,16 @@ ============== +Version 3.28.3 +============== + +Changes in this release: + + • Animation uses g_signal_connect_object() to simplify lifecycle tracking + • CPU graph model now re-uses FDs and parse buffers + • Realtime graphs now try harder to detect when the widget is obscured to + reduce overhead in that situation. + • GCancellable chaining tries harder to release state struct. + +============== Version 3.28.2 ============== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdazzle-3.28.2/meson.build new/libdazzle-3.28.3/meson.build --- old/libdazzle-3.28.2/meson.build 2018-05-23 23:04:13.000000000 +0200 +++ new/libdazzle-3.28.3/meson.build 2018-06-19 05:31:27.000000000 +0200 @@ -1,5 +1,5 @@ project('libdazzle', 'c', - version: '3.28.2', + version: '3.28.3', license: 'GPLv3+', meson_version: '>= 0.40.1', default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'c_std=gnu11' ], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdazzle-3.28.2/src/animation/dzl-animation.c new/libdazzle-3.28.3/src/animation/dzl-animation.c --- old/libdazzle-3.28.2/src/animation/dzl-animation.c 2018-05-23 23:04:13.000000000 +0200 +++ new/libdazzle-3.28.3/src/animation/dzl-animation.c 2018-06-19 05:31:27.000000000 +0200 @@ -629,15 +629,17 @@ animation->begin_time = gdk_frame_clock_get_frame_time (animation->frame_clock); animation->end_time = animation->begin_time + (animation->duration_msec * 1000L); animation->tween_handler = - g_signal_connect (animation->frame_clock, - "update", - G_CALLBACK (dzl_animation_widget_tick_cb), - animation); + g_signal_connect_object (animation->frame_clock, + "update", + G_CALLBACK (dzl_animation_widget_tick_cb), + animation, + 0); animation->after_paint_handler = - g_signal_connect (animation->frame_clock, - "after-paint", - G_CALLBACK (dzl_animation_widget_after_paint_cb), - animation); + g_signal_connect_object (animation->frame_clock, + "after-paint", + G_CALLBACK (dzl_animation_widget_after_paint_cb), + animation, + 0); gdk_frame_clock_begin_updating (animation->frame_clock); } else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdazzle-3.28.2/src/graphing/dzl-cpu-model.c new/libdazzle-3.28.3/src/graphing/dzl-cpu-model.c --- old/libdazzle-3.28.2/src/graphing/dzl-cpu-model.c 2018-05-23 23:04:13.000000000 +0200 +++ new/libdazzle-3.28.3/src/graphing/dzl-cpu-model.c 2018-06-19 05:31:27.000000000 +0200 @@ -19,6 +19,9 @@ #include "config.h" #include <ctype.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> #include <stdio.h> #if defined(__FreeBSD__) # include <errno.h> @@ -27,7 +30,12 @@ # include <sys/types.h> #endif -#include "dzl-cpu-model.h" +#include "graphing/dzl-cpu-model.h" +#include "util/dzl-macros.h" + +#ifdef __linux__ +# define PROC_STAT_BUF_SIZE 4096 +#endif typedef struct { @@ -52,6 +60,11 @@ GArray *cpu_info; guint n_cpu; +#ifdef __linux__ + gint stat_fd; + gchar *stat_buf; +#endif + guint poll_source; guint poll_interval_msec; }; @@ -59,6 +72,30 @@ G_DEFINE_TYPE (DzlCpuModel, dzl_cpu_model, DZL_TYPE_GRAPH_MODEL) #ifdef __linux__ +static gboolean +read_stat (DzlCpuModel *self) +{ + gssize len; + + g_assert (self != NULL); + g_assert (self->stat_fd != -1); + g_assert (self->stat_buf != NULL); + + if (lseek (self->stat_fd, 0, SEEK_SET) != 0) + return FALSE; + + len = read (self->stat_fd, self->stat_buf, PROC_STAT_BUF_SIZE); + if (len <= 0) + return FALSE; + + if (len < PROC_STAT_BUF_SIZE) + self->stat_buf[len] = 0; + else + self->stat_buf[PROC_STAT_BUF_SIZE-1] = 0; + + return TRUE; +} + static void dzl_cpu_model_poll (DzlCpuModel *self) { @@ -83,23 +120,23 @@ glong steal_calc; glong guest_calc; glong guest_nice_calc; - gchar *buf = NULL; glong total; gchar *line; gint ret; gint id; - gint i; - if (g_file_get_contents("/proc/stat", &buf, NULL, NULL)) + if (read_stat (self)) { - line = buf; - for (i = 0; buf[i]; i++) + line = self->stat_buf; + + for (gsize i = 0; self->stat_buf[i]; i++) { - if (buf[i] == '\n') { - buf[i] = '\0'; - if (g_str_has_prefix(line, "cpu")) + if (self->stat_buf[i] == '\n') { + self->stat_buf[i] = '\0'; + + if (strncmp (line, "cpu", 3) == 0) { - if (isdigit(line[3])) + if (isdigit (line[3])) { CpuInfo *cpu_info; @@ -147,15 +184,15 @@ break; } - next: - line = &buf[i + 1]; - } - } - } - - g_free (buf); + next: + line = &self->stat_buf[i + 1]; + } + } + } } + #elif defined(__FreeBSD__) + static void dzl_cpu_model_poll (DzlCpuModel *self) { @@ -250,7 +287,6 @@ DzlCpuModel *self = (DzlCpuModel *)object; gint64 timespan; guint max_samples; - guint i; G_OBJECT_CLASS (dzl_cpu_model_parent_class)->constructed (object); @@ -267,7 +303,7 @@ self->n_cpu = g_get_num_processors (); - for (i = 0; i < self->n_cpu; i++) + for (guint i = 0; i < self->n_cpu; i++) { CpuInfo cpu_info = { 0 }; DzlGraphColumn *column; @@ -293,12 +329,13 @@ { DzlCpuModel *self = (DzlCpuModel *)object; - if (self->poll_source != 0) - { - g_source_remove (self->poll_source); - self->poll_source = 0; - } +#ifdef __linux__ + g_clear_pointer (&self->stat_buf, g_free); + if (self->stat_fd != -1) + close (self->stat_fd); +#endif + dzl_clear_source (&self->poll_source); g_clear_pointer (&self->cpu_info, g_array_unref); G_OBJECT_CLASS (dzl_cpu_model_parent_class)->finalize (object); @@ -318,6 +355,11 @@ { self->cpu_info = g_array_new (FALSE, FALSE, sizeof (CpuInfo)); +#ifdef __linux__ + self->stat_fd = open ("/proc/stat", O_RDONLY); + self->stat_buf = g_malloc (PROC_STAT_BUF_SIZE); +#endif + g_object_set (self, "value-min", 0.0, "value-max", 100.0, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdazzle-3.28.2/src/graphing/dzl-graph-view.c new/libdazzle-3.28.3/src/graphing/dzl-graph-view.c --- old/libdazzle-3.28.2/src/graphing/dzl-graph-view.c 2018-05-23 23:04:13.000000000 +0200 +++ new/libdazzle-3.28.3/src/graphing/dzl-graph-view.c 2018-06-19 05:31:27.000000000 +0200 @@ -31,6 +31,7 @@ cairo_surface_t *surface; guint tick_handler; gdouble x_offset; + guint missed_count; guint surface_dirty : 1; } DzlGraphViewPrivate; @@ -125,6 +126,21 @@ if ((priv->surface == NULL) || (priv->model == NULL) || !gtk_widget_get_visible (widget)) goto remove_handler; + /* + * If we've missed drawings for the last 10 tick callbacks, chances are we're + * visible, but not being displayed to the user because we're not top-most. + * Disable ourselves in that case too so that we don't spin the frame-clock. + * + * We'll be re-enabled when the next ensure_surface() is called (upon a real + * draw by the system). + * + * The missed_count is reset on draw(). + */ + if (priv->missed_count > 10) + goto remove_handler; + else + priv->missed_count++; + timespan = dzl_graph_view_model_get_timespan (priv->model); if (timespan == 0) goto remove_handler; @@ -236,6 +252,8 @@ g_assert (DZL_IS_GRAPH_VIEW (self)); + priv->missed_count = 0; + gtk_widget_get_allocation (widget, &alloc); style_context = gtk_widget_get_style_context (widget); @@ -276,8 +294,8 @@ } static void -dzl_graph_view__model_changed (DzlGraphView *self, - DzlGraphModel *model) +dzl_graph_view__model__changed (DzlGraphView *self, + DzlGraphModel *model) { DzlGraphViewPrivate *priv = dzl_graph_view_get_instance_private (self); @@ -290,6 +308,20 @@ } static void +dzl_graph_view__model__notify_timespan (DzlGraphView *self, + GParamSpec *pspec, + DzlGraphModel *model) +{ + g_assert (DZL_IS_GRAPH_VIEW (self)); + g_assert (DZL_IS_GRAPH_MODEL (model)); + + /* Avoid this in a number of scenarios */ + if (gtk_widget_get_visible (GTK_WIDGET (self)) && + gtk_widget_get_child_visible (GTK_WIDGET (self))) + gtk_widget_queue_draw (GTK_WIDGET (self)); +} + +static void dzl_graph_view_destroy (GtkWidget *widget) { DzlGraphView *self = (DzlGraphView *)widget; @@ -301,6 +333,8 @@ priv->tick_handler = 0; } + g_clear_pointer (&priv->surface, cairo_surface_destroy); + GTK_WIDGET_CLASS (dzl_graph_view_parent_class)->destroy (widget); } @@ -312,7 +346,6 @@ g_clear_object (&priv->model); g_clear_object (&priv->model_signals); - g_clear_pointer (&priv->surface, cairo_surface_destroy); g_clear_pointer (&priv->renderers, g_ptr_array_unref); G_OBJECT_CLASS (dzl_graph_view_parent_class)->finalize (object); @@ -375,7 +408,7 @@ "Table", "The data model for the graph.", DZL_TYPE_GRAPH_MODEL, - (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS)); g_object_class_install_properties (object_class, LAST_PROP, properties); @@ -405,13 +438,13 @@ dzl_signal_group_connect_object (priv->model_signals, "notify::timespan", - G_CALLBACK (gtk_widget_queue_allocate), + G_CALLBACK (dzl_graph_view__model__notify_timespan), self, G_CONNECT_SWAPPED); dzl_signal_group_connect_object (priv->model_signals, "changed", - G_CALLBACK (dzl_graph_view__model_changed), + G_CALLBACK (dzl_graph_view__model__changed), self, G_CONNECT_SWAPPED); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdazzle-3.28.2/src/util/dzl-cancellable.c new/libdazzle-3.28.3/src/util/dzl-cancellable.c --- old/libdazzle-3.28.2/src/util/dzl-cancellable.c 2018-05-23 23:04:13.000000000 +0200 +++ new/libdazzle-3.28.3/src/util/dzl-cancellable.c 2018-06-19 05:31:27.000000000 +0200 @@ -25,11 +25,16 @@ #include "util/dzl-cancellable.h" #include "util/dzl-macros.h" +#define CHAINED_INFO_MAGIC 0x81734637 + typedef struct { - GWeakRef self; - GWeakRef other; - gulong other_handler; + guint magic; + volatile gint ref_count; + GMutex mutex; + GWeakRef self; + GWeakRef other; + gulong other_handler; } ChainedInfo; static void @@ -40,6 +45,10 @@ g_autoptr(GCancellable) other = NULL; g_assert (info != NULL); + g_assert (info->magic == CHAINED_INFO_MAGIC); + g_assert (info->ref_count == 0); + + info->magic = 0; self = g_weak_ref_get (&info->self); other = g_weak_ref_get (&info->other); @@ -52,10 +61,38 @@ g_weak_ref_clear (&info->other); g_weak_ref_clear (&info->self); + g_mutex_clear (&info->mutex); + g_slice_free (ChainedInfo, info); } static void +chained_info_unref (ChainedInfo *info) +{ + g_autoptr(GCancellable) other = NULL; + + g_assert (info != NULL); + g_assert (info->ref_count > 0); + g_assert (info->magic == CHAINED_INFO_MAGIC); + + if ((other = g_weak_ref_get (&info->other))) + { + gulong handler_id; + + g_mutex_lock (&info->mutex); + handler_id = info->other_handler; + info->other_handler = 0; + g_mutex_unlock (&info->mutex); + + if (handler_id) + g_signal_handler_disconnect (other, handler_id); + } + + if (g_atomic_int_dec_and_test (&info->ref_count)) + chained_info_free (info); +} + +static void dzl_cancellable_cancelled_cb (GCancellable *other, ChainedInfo *info) { @@ -63,6 +100,8 @@ g_assert (G_IS_CANCELLABLE (other)); g_assert (info != NULL); + g_assert (info->ref_count > 0); + g_assert (info->magic == CHAINED_INFO_MAGIC); self = g_weak_ref_get (&info->self); @@ -75,6 +114,19 @@ dzl_clear_signal_handler (other, &info->other_handler); } +static void +dzl_cancellable_weak_cb (gpointer data, + GObject *where_object_was) +{ + ChainedInfo *info = data; + + g_assert (info != NULL); + g_assert (info->ref_count > 0); + g_assert (info->magic == CHAINED_INFO_MAGIC); + + chained_info_unref (info); +} + /** * dzl_cancellable_chain: * @self: (nullable): a #GCancellable or %NULL @@ -122,12 +174,17 @@ */ info = g_slice_new0 (ChainedInfo); + info->magic = CHAINED_INFO_MAGIC; + info->ref_count = 3; + g_mutex_init (&info->mutex); g_weak_ref_init (&info->self, self); g_weak_ref_init (&info->other, other); + g_object_weak_ref (G_OBJECT (self), dzl_cancellable_weak_cb, info); + g_object_weak_ref (G_OBJECT (other), dzl_cancellable_weak_cb, info); info->other_handler = g_cancellable_connect (other, G_CALLBACK (dzl_cancellable_cancelled_cb), info, - chained_info_free); + (GDestroyNotify)chained_info_unref); return self; }
