551277
From 9e5a53d576765819d1c7c233515b9f6e5d77eb61 Mon Sep 17 00:00:00 2001
551277
From: Emmanuele Bassi <ebassi@gnome.org>
551277
Date: Wed, 17 Jan 2018 16:38:45 +0000
551277
Subject: [PATCH] Add reference counting types
551277
551277
We have a common pattern for reference counting in GLib, but we always
551277
implement it with ad hoc code. This is a good chance at trying to
551277
standardise the implementation and make it public, so that other code
551277
using GLib can take advantage of shared behaviour and semantics.
551277
551277
Instead of simply taking an integer variable, we should create type
551277
aliases, to immediately distinguish the reference counting semantics of
551277
the code; we can handle mixing atomic reference counting with a
551277
non-atomic type (and vice versa) by using differently signed values for
551277
the atomic and non-atomic cases.
551277
551277
The gatomicrefcount type is modelled on the Linux kernel refcount_t
551277
type; the grefcount type is added to let single-threaded code bases to
551277
avoid paying the price of atomic memory barriers on reference counting
551277
operations.
551277
---
551277
 docs/reference/glib/glib-docs.xml     |   1 +
551277
 docs/reference/glib/glib-sections.txt |  15 ++
551277
 glib/Makefile.am                      |   2 +
551277
 glib/glib.h                           |   1 +
551277
 glib/grefcount.c                      | 285 ++++++++++++++++++++++++++
551277
 glib/grefcount.h                      |  52 +++++
551277
 glib/gtypes.h                         |   3 +
551277
 glib/meson.build                      |   2 +
551277
 8 files changed, 361 insertions(+)
551277
 create mode 100644 glib/grefcount.c
551277
 create mode 100644 glib/grefcount.h
551277
551277
diff --git a/docs/reference/glib/glib-docs.xml b/docs/reference/glib/glib-docs.xml
551277
index a0716c1727..26cdafb67b 100644
551277
--- a/docs/reference/glib/glib-docs.xml
551277
+++ b/docs/reference/glib/glib-docs.xml
551277
@@ -119,6 +119,7 @@
551277
     <xi:include href="xml/gvariant.xml"/>
551277
     <xi:include href="gvariant-varargs.xml"/>
551277
     <xi:include href="gvariant-text.xml"/>
551277
+    <xi:include href="xml/refcount.xml"/>
551277
   </chapter>
551277
 
551277
   <chapter id="deprecated">
551277
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
551277
index 0183b0898a..331d92c75f 100644
551277
--- a/docs/reference/glib/glib-sections.txt
551277
+++ b/docs/reference/glib/glib-sections.txt
551277
@@ -3449,3 +3449,18 @@ g_hostname_is_ip_address
551277
 g_uuid_string_is_valid
551277
 g_uuid_string_random
551277
 </SECTION>
551277
+
551277
+<SECTION>
551277
+<FILE>refcount</FILE>
551277
+grefcount
551277
+g_ref_count_init
551277
+g_ref_count_inc
551277
+g_ref_count_dec
551277
+g_ref_count_compare
551277
+<SUBSECTION>
551277
+gatomicrefcount
551277
+g_atomic_ref_count_init
551277
+g_atomic_ref_count_inc
551277
+g_atomic_ref_count_dec
551277
+g_atomic_ref_count_compare
551277
+</SECTION>
551277
diff --git a/glib/Makefile.am b/glib/Makefile.am
551277
index 0497061265..4d04e09daa 100644
551277
--- a/glib/Makefile.am
551277
+++ b/glib/Makefile.am
551277
@@ -149,6 +149,7 @@ libglib_2_0_la_SOURCES = 	\
551277
 	gquark.c		\
551277
 	gqueue.c		\
551277
 	grand.c			\
551277
+	grefcount.c		\
551277
 	gregex.c		\
551277
 	gscanner.c		\
551277
 	gscripttable.h		\
551277
@@ -284,6 +285,7 @@ glibsubinclude_HEADERS = \
551277
 	gquark.h	\
551277
 	gqueue.h	\
551277
 	grand.h		\
551277
+	grefcount.h	\
551277
 	gregex.h	\
551277
 	gscanner.h	\
551277
 	gsequence.h	\
551277
diff --git a/glib/glib.h b/glib/glib.h
551277
index 4f5a7f702f..84299c4f90 100644
551277
--- a/glib/glib.h
551277
+++ b/glib/glib.h
551277
@@ -69,6 +69,7 @@
551277
 #include <glib/gquark.h>
551277
 #include <glib/gqueue.h>
551277
 #include <glib/grand.h>
551277
+#include <glib/grefcount.h>
551277
 #include <glib/gregex.h>
551277
 #include <glib/gscanner.h>
551277
 #include <glib/gsequence.h>
551277
diff --git a/glib/grefcount.c b/glib/grefcount.c
551277
new file mode 100644
551277
index 0000000000..10e35a217d
551277
--- /dev/null
551277
+++ b/glib/grefcount.c
551277
@@ -0,0 +1,285 @@
551277
+/* grefcount.c: Reference counting
551277
+ *
551277
+ * Copyright 2018  Emmanuele Bassi
551277
+ *
551277
+ * This library is free software; you can redistribute it and/or
551277
+ * modify it under the terms of the GNU Lesser General Public
551277
+ * License as published by the Free Software Foundation; either
551277
+ * version 2.1 of the License, or (at your option) any later version.
551277
+ *
551277
+ * This library is distributed in the hope that it will be useful,
551277
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
551277
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
551277
+ * Lesser General Public License for more details.
551277
+ *
551277
+ * You should have received a copy of the GNU Lesser General Public
551277
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
551277
+ */
551277
+
551277
+/**
551277
+ * SECTION:refcount
551277
+ * @Title: Reference counting
551277
+ * @Short_description: Reference counting types and functions
551277
+ *
551277
+ * Reference counting is a garbage collection mechanism that is based on
551277
+ * assigning a counter to a data type, or any memory area; the counter is
551277
+ * increased whenever a new reference to that data type is acquired, and
551277
+ * decreased whenever the reference is released. Once the last reference
551277
+ * is released, the resources associated to that data type are freed.
551277
+ *
551277
+ * GLib uses reference counting in many of its data types, and provides
551277
+ * the #grefcount and #gatomicrefcount types to implement safe and atomic
551277
+ * reference counting semantics in new data types.
551277
+ *
551277
+ * It is important to note that #grefcount and #gatomicrefcount should be
551277
+ * considered completely opaque types; you should always use the provided
551277
+ * API to increase and decrease the counters, and you should never check
551277
+ * their content directly, or compare their content with other values.
551277
+ *
551277
+ * Since: 2.58
551277
+ */
551277
+
551277
+#include "config.h"
551277
+
551277
+#include "grefcount.h"
551277
+
551277
+#include "gatomic.h"
551277
+#include "gmessages.h"
551277
+
551277
+/**
551277
+ * grefcount:
551277
+ *
551277
+ * A type for implementing non-atomic reference count semantics.
551277
+ *
551277
+ * Use g_ref_count_init() to initialize it; g_ref_count_inc() to
551277
+ * increase the counter, and g_ref_count_dec() to decrease it.
551277
+ *
551277
+ * It is safe to use #grefcount only if you're expecting to operate
551277
+ * on the reference counter from a single thread. It is entirely up
551277
+ * to you to ensure that all reference count changes happen in the
551277
+ * same thread.
551277
+ *
551277
+ * See also: #gatomicrefcount
551277
+ *
551277
+ * Since: 2.58
551277
+ */
551277
+
551277
+/**
551277
+ * gatomicrefcount:
551277
+ *
551277
+ * A type for implementing atomic reference count semantics.
551277
+ *
551277
+ * Use g_atomic_ref_count_init() to initialize it; g_atomic_ref_count_inc()
551277
+ * to increase the counter, and g_atomic_ref_count_dec() to decrease it.
551277
+ *
551277
+ * It is safe to use #gatomicrefcount if you're expecting to operate on the
551277
+ * reference counter from multiple threads.
551277
+ *
551277
+ * See also: #grefcount
551277
+ *
551277
+ * Since: 2.58
551277
+ */
551277
+
551277
+/**
551277
+ * g_ref_count_init:
551277
+ * @rc: the address of a reference count variable
551277
+ *
551277
+ * Initializes a reference count variable.
551277
+ *
551277
+ * Since: 2.58
551277
+ */
551277
+void
551277
+g_ref_count_init (grefcount *rc)
551277
+{
551277
+  g_return_if_fail (rc != NULL);
551277
+
551277
+  /* Non-atomic refcounting is implemented using the negative range
551277
+   * of signed integers:
551277
+   *
551277
+   * G_MININT                 Z¯< 0 > Z⁺                G_MAXINT
551277
+   * |----------------------------|----------------------------|
551277
+   *
551277
+   * Acquiring a reference moves us towards MININT, and releasing a
551277
+   * reference moves us towards 0.
551277
+   */
551277
+  *rc = -1;
551277
+}
551277
+
551277
+/**
551277
+ * g_ref_count_inc:
551277
+ * @rc: the address of a reference count variable
551277
+ *
551277
+ * Increases the reference count.
551277
+ *
551277
+ * Since: 2.58
551277
+ */
551277
+void
551277
+g_ref_count_inc (grefcount *rc)
551277
+{
551277
+  grefcount rrc;
551277
+
551277
+  g_return_if_fail (rc != NULL);
551277
+
551277
+  rrc = *rc;
551277
+
551277
+  g_return_if_fail (rrc < 0);
551277
+
551277
+  /* Check for saturation */
551277
+  if (rrc == G_MININT)
551277
+    {
551277
+      g_critical ("Reference count %p has reached saturation", rc);
551277
+      return;
551277
+    }
551277
+
551277
+  rrc -= 1;
551277
+
551277
+  *rc = rrc;
551277
+}
551277
+
551277
+/**
551277
+ * g_ref_count_dec:
551277
+ * @rc: the address of a reference count variable
551277
+ *
551277
+ * Decreases the reference count.
551277
+ *
551277
+ * Returns: %TRUE if the reference count reached 0, and %FALSE otherwise
551277
+ *
551277
+ * Since: 2.58
551277
+ */
551277
+gboolean
551277
+g_ref_count_dec (grefcount *rc)
551277
+{
551277
+  grefcount rrc;
551277
+
551277
+  g_return_val_if_fail (rc != NULL, FALSE);
551277
+
551277
+  rrc = *rc;
551277
+
551277
+  g_return_val_if_fail (rrc < 0, FALSE);
551277
+
551277
+  rrc += 1;
551277
+  if (rrc == 0)
551277
+    return TRUE;
551277
+
551277
+  *rc = rrc;
551277
+
551277
+  return FALSE;
551277
+}
551277
+
551277
+/**
551277
+ * g_ref_count_compare:
551277
+ * @rc: the address of a reference count variable
551277
+ * @val: the value to compare
551277
+ *
551277
+ * Compares the current value of @rc with @val.
551277
+ *
551277
+ * Returns: %TRUE if the reference count is the same
551277
+ *   as the given value
551277
+ *
551277
+ * Since: 2.58
551277
+ */
551277
+gboolean
551277
+g_ref_count_compare (grefcount *rc,
551277
+                     gint       val)
551277
+{
551277
+  grefcount rrc;
551277
+
551277
+  g_return_val_if_fail (rc != NULL, FALSE);
551277
+  g_return_val_if_fail (val >= 0, FALSE);
551277
+
551277
+  rrc = *rc;
551277
+
551277
+  if (val == G_MAXINT)
551277
+    return rrc == G_MININT;
551277
+
551277
+  return rrc == -val;
551277
+}
551277
+
551277
+/**
551277
+ * g_atomic_ref_count_init:
551277
+ * @arc: the address of an atomic reference count variable
551277
+ *
551277
+ * Atomically initializes a reference count variable.
551277
+ *
551277
+ * Since: 2.58
551277
+ */
551277
+void
551277
+g_atomic_ref_count_init (gatomicrefcount *arc)
551277
+{
551277
+  g_return_if_fail (arc != NULL);
551277
+
551277
+  /* Atomic refcounting is implemented using the positive range
551277
+   * of signed integers:
551277
+   *
551277
+   * G_MININT                 Z¯< 0 > Z⁺                G_MAXINT
551277
+   * |----------------------------|----------------------------|
551277
+   *
551277
+   * Acquiring a reference moves us towards MAXINT, and releasing a
551277
+   * reference moves us towards 0.
551277
+   */
551277
+  g_atomic_int_set (arc, 1);
551277
+}
551277
+
551277
+/**
551277
+ * g_atomic_ref_count_inc:
551277
+ * @arc: the address of an atomic reference count variable
551277
+ *
551277
+ * Atomically increases the reference count.
551277
+ *
551277
+ * Since: 2.58
551277
+ */
551277
+void
551277
+g_atomic_ref_count_inc (gatomicrefcount *arc)
551277
+{
551277
+  g_return_if_fail (arc != NULL);
551277
+  g_return_if_fail (g_atomic_int_get (arc) > 0);
551277
+
551277
+  if (g_atomic_int_get (arc) == G_MAXINT)
551277
+    {
551277
+      g_critical ("Reference count has reached saturation");
551277
+      return;
551277
+    }
551277
+
551277
+  g_atomic_int_inc (arc);
551277
+}
551277
+
551277
+/**
551277
+ * g_atomic_ref_count_dec:
551277
+ * @arc: the address of an atomic reference count variable
551277
+ *
551277
+ * Atomically decreases the reference count.
551277
+ *
551277
+ * Returns: %TRUE if the reference count reached 0, and %FALSE otherwise
551277
+ *
551277
+ * Since: 2.58
551277
+ */
551277
+gboolean
551277
+g_atomic_ref_count_dec (gatomicrefcount *arc)
551277
+{
551277
+  g_return_val_if_fail (arc != NULL, FALSE);
551277
+  g_return_val_if_fail (g_atomic_int_get (arc) > 0, FALSE);
551277
+
551277
+  return g_atomic_int_dec_and_test (arc);
551277
+}
551277
+
551277
+/**
551277
+ * g_atomic_ref_count_compare:
551277
+ * @arc: the address of an atomic reference count variable
551277
+ * @val: the value to compare
551277
+ *
551277
+ * Atomically compares the current value of @arc with @val.
551277
+ *
551277
+ * Returns: %TRUE if the reference count is the same
551277
+ *   as the given value
551277
+ *
551277
+ * Since: 2.58
551277
+ */
551277
+gboolean
551277
+g_atomic_ref_count_compare (gatomicrefcount *arc,
551277
+                            gint             val)
551277
+{
551277
+  g_return_val_if_fail (arc != NULL, FALSE);
551277
+  g_return_val_if_fail (val >= 0, FALSE);
551277
+
551277
+  return g_atomic_int_get (arc) == val;
551277
+}
551277
diff --git a/glib/grefcount.h b/glib/grefcount.h
551277
new file mode 100644
551277
index 0000000000..b24c71e8cb
551277
--- /dev/null
551277
+++ b/glib/grefcount.h
551277
@@ -0,0 +1,52 @@
551277
+/* grefcount.h: Reference counting
551277
+ *
551277
+ * Copyright 2018  Emmanuele Bassi
551277
+ *
551277
+ * This library is free software; you can redistribute it and/or
551277
+ * modify it under the terms of the GNU Lesser General Public
551277
+ * License as published by the Free Software Foundation; either
551277
+ * version 2.1 of the License, or (at your option) any later version.
551277
+ *
551277
+ * This library is distributed in the hope that it will be useful,
551277
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
551277
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
551277
+ * Lesser General Public License for more details.
551277
+ *
551277
+ * You should have received a copy of the GNU Lesser General Public
551277
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
551277
+ */
551277
+
551277
+#ifndef __GREFCOUNT_H__
551277
+#define __GREFCOUNT_H__
551277
+
551277
+#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
551277
+#error "Only <glib.h> can be included directly."
551277
+#endif
551277
+
551277
+#include <glib/gtypes.h>
551277
+
551277
+G_BEGIN_DECLS
551277
+
551277
+GLIB_AVAILABLE_IN_2_56
551277
+void            g_ref_count_init                (grefcount       *rc);
551277
+GLIB_AVAILABLE_IN_2_56
551277
+void            g_ref_count_inc                 (grefcount       *rc);
551277
+GLIB_AVAILABLE_IN_2_56
551277
+gboolean        g_ref_count_dec                 (grefcount       *rc);
551277
+GLIB_AVAILABLE_IN_2_56
551277
+gboolean        g_ref_count_compare             (grefcount       *rc,
551277
+                                                 gint             val);
551277
+
551277
+GLIB_AVAILABLE_IN_2_56
551277
+void            g_atomic_ref_count_init         (gatomicrefcount *arc);
551277
+GLIB_AVAILABLE_IN_2_56
551277
+void            g_atomic_ref_count_inc          (gatomicrefcount *arc);
551277
+GLIB_AVAILABLE_IN_2_56
551277
+gboolean        g_atomic_ref_count_dec          (gatomicrefcount *arc);
551277
+GLIB_AVAILABLE_IN_2_56
551277
+gboolean        g_atomic_ref_count_compare      (gatomicrefcount *arc,
551277
+                                                 gint             val);
551277
+
551277
+G_END_DECLS
551277
+
551277
+#endif /* __GREFCOUNT_H__ */
551277
diff --git a/glib/gtypes.h b/glib/gtypes.h
551277
index 09d9bd1456..67adb7f1f8 100644
551277
--- a/glib/gtypes.h
551277
+++ b/glib/gtypes.h
551277
@@ -510,6 +510,9 @@ struct _GTimeVal
551277
   glong tv_usec;
551277
 };
551277
 
551277
+typedef gint            grefcount;
551277
+typedef volatile gint   gatomicrefcount;
551277
+
551277
 G_END_DECLS
551277
 
551277
 /* We prefix variable declarations so they can
551277
diff --git a/glib/meson.build b/glib/meson.build
551277
index 036d1f4d60..76d354c2a7 100644
551277
--- a/glib/meson.build
551277
+++ b/glib/meson.build
551277
@@ -76,6 +76,7 @@ glib_sub_headers = files(
551277
   'gquark.h',
551277
   'gqueue.h',
551277
   'grand.h',
551277
+  'grefcount.h',
551277
   'gregex.h',
551277
   'gscanner.h',
551277
   'gsequence.h',
551277
@@ -159,6 +160,7 @@ glib_sources = files(
551277
   'gquark.c',
551277
   'gqueue.c',
551277
   'grand.c',
551277
+  'grefcount.c',
551277
   'gregex.c',
551277
   'gscanner.c',
551277
   'gsequence.c',
551277
-- 
551277
GitLab
551277
551277
From 827c208cbf9cc0ef17b8c4531a40aafe1edc3f01 Mon Sep 17 00:00:00 2001
551277
From: Emmanuele Bassi <ebassi@gnome.org>
551277
Date: Mon, 4 Jun 2018 11:38:40 +0100
551277
Subject: [PATCH] Use macros for refcount types API
551277
551277
If we're using GCC we can use __extension__ to inline the grefcount and
551277
gatomicrefcount API, and avoid the function call.
551277
551277
These macros are only enabled if G_DISABLE_CHECKS is defined, as they
551277
remove critical warnings when the reference counters achieve saturation.
551277
---
551277
 glib/grefcount.c | 20 +++++++-------
551277
 glib/grefcount.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++
551277
 2 files changed, 80 insertions(+), 10 deletions(-)
551277
551277
diff --git a/glib/grefcount.c b/glib/grefcount.c
551277
index 10e35a217d..37085316b9 100644
551277
--- a/glib/grefcount.c
551277
+++ b/glib/grefcount.c
551277
@@ -89,7 +89,7 @@
551277
  * Since: 2.58
551277
  */
551277
 void
551277
-g_ref_count_init (grefcount *rc)
551277
+(g_ref_count_init) (grefcount *rc)
551277
 {
551277
   g_return_if_fail (rc != NULL);
551277
 
551277
@@ -114,7 +114,7 @@ g_ref_count_init (grefcount *rc)
551277
  * Since: 2.58
551277
  */
551277
 void
551277
-g_ref_count_inc (grefcount *rc)
551277
+(g_ref_count_inc) (grefcount *rc)
551277
 {
551277
   grefcount rrc;
551277
 
551277
@@ -147,7 +147,7 @@ g_ref_count_inc (grefcount *rc)
551277
  * Since: 2.58
551277
  */
551277
 gboolean
551277
-g_ref_count_dec (grefcount *rc)
551277
+(g_ref_count_dec) (grefcount *rc)
551277
 {
551277
   grefcount rrc;
551277
 
551277
@@ -179,8 +179,8 @@ g_ref_count_dec (grefcount *rc)
551277
  * Since: 2.58
551277
  */
551277
 gboolean
551277
-g_ref_count_compare (grefcount *rc,
551277
-                     gint       val)
551277
+(g_ref_count_compare) (grefcount *rc,
551277
+                       gint       val)
551277
 {
551277
   grefcount rrc;
551277
 
551277
@@ -204,7 +204,7 @@ g_ref_count_compare (grefcount *rc,
551277
  * Since: 2.58
551277
  */
551277
 void
551277
-g_atomic_ref_count_init (gatomicrefcount *arc)
551277
+(g_atomic_ref_count_init) (gatomicrefcount *arc)
551277
 {
551277
   g_return_if_fail (arc != NULL);
551277
 
551277
@@ -229,7 +229,7 @@ g_atomic_ref_count_init (gatomicrefcount *arc)
551277
  * Since: 2.58
551277
  */
551277
 void
551277
-g_atomic_ref_count_inc (gatomicrefcount *arc)
551277
+(g_atomic_ref_count_inc) (gatomicrefcount *arc)
551277
 {
551277
   g_return_if_fail (arc != NULL);
551277
   g_return_if_fail (g_atomic_int_get (arc) > 0);
551277
@@ -254,7 +254,7 @@ g_atomic_ref_count_inc (gatomicrefcount *arc)
551277
  * Since: 2.58
551277
  */
551277
 gboolean
551277
-g_atomic_ref_count_dec (gatomicrefcount *arc)
551277
+(g_atomic_ref_count_dec) (gatomicrefcount *arc)
551277
 {
551277
   g_return_val_if_fail (arc != NULL, FALSE);
551277
   g_return_val_if_fail (g_atomic_int_get (arc) > 0, FALSE);
551277
@@ -275,8 +275,8 @@ g_atomic_ref_count_dec (gatomicrefcount *arc)
551277
  * Since: 2.58
551277
  */
551277
 gboolean
551277
-g_atomic_ref_count_compare (gatomicrefcount *arc,
551277
-                            gint             val)
551277
+(g_atomic_ref_count_compare) (gatomicrefcount *arc,
551277
+                              gint             val)
551277
 {
551277
   g_return_val_if_fail (arc != NULL, FALSE);
551277
   g_return_val_if_fail (val >= 0, FALSE);
551277
diff --git a/glib/grefcount.h b/glib/grefcount.h
551277
index b24c71e8cb..dec9a5ffb8 100644
551277
--- a/glib/grefcount.h
551277
+++ b/glib/grefcount.h
551277
@@ -47,6 +47,76 @@ GLIB_AVAILABLE_IN_2_58
551277
 gboolean        g_atomic_ref_count_compare      (gatomicrefcount *arc,
551277
                                                  gint             val);
551277
 
551277
+/* On GCC we can use __extension__ to inline the API without using
551277
+ * ancillary functions; we only do this when disabling checks, as
551277
+ * it disables warnings when saturating the reference counters
551277
+ */
551277
+#if defined(__GNUC__) && defined(G_DISABLE_CHECKS)
551277
+
551277
+# define g_ref_count_init(rc) \
551277
+  (G_GNUC_EXTENSION ({ \
551277
+    G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \
551277
+    (void) (0 ? *(rc) ^ *(rc) : 1); \
551277
+    *(rc) = -1; \
551277
+  }))
551277
+
551277
+# define g_ref_count_inc(rc) \
551277
+  (G_GNUC_EXTENSION ({ \
551277
+    G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \
551277
+    (void) (0 ? *(rc) ^ *(rc) : 1); \
551277
+    if (*(rc) == G_MININT) ; else { \
551277
+      *(rc) -= 1; \
551277
+    } \
551277
+  }))
551277
+
551277
+# define g_ref_count_dec(rc) \
551277
+  (G_GNUC_EXTENSION ({ \
551277
+    G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \
551277
+    grefcount __rc = *(rc); \
551277
+    __rc += 1; \
551277
+    if (__rc == 0) ; else { \
551277
+      *(rc) = __rc; \
551277
+    } \
551277
+    (gboolean) (__rc == 0); \
551277
+  }))
551277
+
551277
+# define g_ref_count_compare(rc,val) \
551277
+  (G_GNUC_EXTENSION ({ \
551277
+    G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \
551277
+    (void) (0 ? *(rc) ^ (val) : 1); \
551277
+    (gboolean) (*(rc) == -(val)); \
551277
+  }))
551277
+
551277
+# define g_atomic_ref_count_init(rc) \
551277
+  (G_GNUC_EXTENSION ({ \
551277
+    G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \
551277
+    (void) (0 ? *(rc) ^ *(rc) : 1); \
551277
+    g_atomic_int_set ((rc), 1); \
551277
+  }))
551277
+
551277
+# define g_atomic_ref_count_inc(rc) \
551277
+  (G_GNUC_EXTENSION ({ \
551277
+    G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \
551277
+    (void) (0 ? *(rc) ^ *(rc) : 1); \
551277
+    (void) (g_atomic_int_get (rc) == G_MAXINT ? 0 : g_atomic_int_inc ((rc))); \
551277
+  }))
551277
+
551277
+# define g_atomic_ref_count_dec(rc) \
551277
+  (G_GNUC_EXTENSION ({ \
551277
+    G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \
551277
+    (void) (0 ? *(rc) ^ *(rc) : 1); \
551277
+    g_atomic_int_dec_and_test ((rc)); \
551277
+  }))
551277
+
551277
+# define g_atomic_ref_count_compare(rc,val) \
551277
+  (G_GNUC_EXTENSION ({ \
551277
+    G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \
551277
+    (void) (0 ? *(rc) ^ (val) : 1); \
551277
+    (gboolean) (g_atomic_int_get (rc) == (val)); \
551277
+  }))
551277
+
551277
+#endif /* __GNUC__ && G_DISABLE_CHECKS */
551277
+
551277
 G_END_DECLS
551277
 
551277
 #endif /* __GREFCOUNT_H__ */
551277
-- 
551277
GitLab
551277
551277
From 09c149453ac969dedb1cb2d15d489d1dd81412bf Mon Sep 17 00:00:00 2001
551277
From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
551277
Date: Sat, 13 Oct 2018 23:10:33 +0200
551277
Subject: [PATCH] grefcount: add missing gatomic.h
551277
MIME-Version: 1.0
551277
Content-Type: text/plain; charset=UTF-8
551277
Content-Transfer-Encoding: 8bit
551277
551277
Without gatomic.h, build fails on:
551277
In file included from garcbox.c:24:0:
551277
garcbox.c: In function ‘g_atomic_rc_box_acquire’:
551277
grefcount.h:101:13: error: implicit declaration of function ‘g_atomic_int_get’; did you mean ‘__atomic_store’? [-Werror=implicit-function-declaration]
551277
     (void) (g_atomic_int_get (rc) == G_MAXINT ? 0 : g_atomic_int_inc ((rc))); \
551277
             ^
551277
garcbox.c:292:3: note: in expansion of macro ‘g_atomic_ref_count_inc’
551277
   g_atomic_ref_count_inc (&real_box->ref_count);
551277
551277
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
551277
---
551277
 glib/grefcount.h | 1 +
551277
 1 file changed, 1 insertion(+)
551277
551277
diff --git a/glib/grefcount.h b/glib/grefcount.h
551277
index dec9a5ffb8..b6eced1b7d 100644
551277
--- a/glib/grefcount.h
551277
+++ b/glib/grefcount.h
551277
@@ -23,6 +23,7 @@
551277
 #error "Only <glib.h> can be included directly."
551277
 #endif
551277
 
551277
+#include <glib/gatomic.h>
551277
 #include <glib/gtypes.h>
551277
 
551277
 G_BEGIN_DECLS
551277
-- 
551277
GitLab
551277