diff --git a/docs/reference/glib/glib-docs.xml b/docs/reference/glib/glib-docs.xml
index a0716c172..26cdafb67 100644
--- a/docs/reference/glib/glib-docs.xml
+++ b/docs/reference/glib/glib-docs.xml
@@ -119,6 +119,7 @@
+
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 0183b0898..331d92c75 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -3449,3 +3449,18 @@ g_hostname_is_ip_address
g_uuid_string_is_valid
g_uuid_string_random
+
+
+refcount
+grefcount
+g_ref_count_init
+g_ref_count_inc
+g_ref_count_dec
+g_ref_count_compare
+
+gatomicrefcount
+g_atomic_ref_count_init
+g_atomic_ref_count_inc
+g_atomic_ref_count_dec
+g_atomic_ref_count_compare
+
diff --git a/glib/Makefile.am b/glib/Makefile.am
index 049706126..4d04e09da 100644
--- a/glib/Makefile.am
+++ b/glib/Makefile.am
@@ -149,6 +149,7 @@ libglib_2_0_la_SOURCES = \
gquark.c \
gqueue.c \
grand.c \
+ grefcount.c \
gregex.c \
gscanner.c \
gscripttable.h \
@@ -284,6 +285,7 @@ glibsubinclude_HEADERS = \
gquark.h \
gqueue.h \
grand.h \
+ grefcount.h \
gregex.h \
gscanner.h \
gsequence.h \
diff --git a/glib/glib.h b/glib/glib.h
index 4f5a7f702..84299c4f9 100644
--- a/glib/glib.h
+++ b/glib/glib.h
@@ -69,6 +69,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/glib/grefcount.c b/glib/grefcount.c
new file mode 100644
index 000000000..10e35a217
--- /dev/null
+++ b/glib/grefcount.c
@@ -0,0 +1,285 @@
+/* grefcount.c: Reference counting
+ *
+ * Copyright 2018 Emmanuele Bassi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+/**
+ * SECTION:refcount
+ * @Title: Reference counting
+ * @Short_description: Reference counting types and functions
+ *
+ * Reference counting is a garbage collection mechanism that is based on
+ * assigning a counter to a data type, or any memory area; the counter is
+ * increased whenever a new reference to that data type is acquired, and
+ * decreased whenever the reference is released. Once the last reference
+ * is released, the resources associated to that data type are freed.
+ *
+ * GLib uses reference counting in many of its data types, and provides
+ * the #grefcount and #gatomicrefcount types to implement safe and atomic
+ * reference counting semantics in new data types.
+ *
+ * It is important to note that #grefcount and #gatomicrefcount should be
+ * considered completely opaque types; you should always use the provided
+ * API to increase and decrease the counters, and you should never check
+ * their content directly, or compare their content with other values.
+ *
+ * Since: 2.58
+ */
+
+#include "config.h"
+
+#include "grefcount.h"
+
+#include "gatomic.h"
+#include "gmessages.h"
+
+/**
+ * grefcount:
+ *
+ * A type for implementing non-atomic reference count semantics.
+ *
+ * Use g_ref_count_init() to initialize it; g_ref_count_inc() to
+ * increase the counter, and g_ref_count_dec() to decrease it.
+ *
+ * It is safe to use #grefcount only if you're expecting to operate
+ * on the reference counter from a single thread. It is entirely up
+ * to you to ensure that all reference count changes happen in the
+ * same thread.
+ *
+ * See also: #gatomicrefcount
+ *
+ * Since: 2.58
+ */
+
+/**
+ * gatomicrefcount:
+ *
+ * A type for implementing atomic reference count semantics.
+ *
+ * Use g_atomic_ref_count_init() to initialize it; g_atomic_ref_count_inc()
+ * to increase the counter, and g_atomic_ref_count_dec() to decrease it.
+ *
+ * It is safe to use #gatomicrefcount if you're expecting to operate on the
+ * reference counter from multiple threads.
+ *
+ * See also: #grefcount
+ *
+ * Since: 2.58
+ */
+
+/**
+ * g_ref_count_init:
+ * @rc: the address of a reference count variable
+ *
+ * Initializes a reference count variable.
+ *
+ * Since: 2.58
+ */
+void
+g_ref_count_init (grefcount *rc)
+{
+ g_return_if_fail (rc != NULL);
+
+ /* Non-atomic refcounting is implemented using the negative range
+ * of signed integers:
+ *
+ * G_MININT Z¯< 0 > Z⁺ G_MAXINT
+ * |----------------------------|----------------------------|
+ *
+ * Acquiring a reference moves us towards MININT, and releasing a
+ * reference moves us towards 0.
+ */
+ *rc = -1;
+}
+
+/**
+ * g_ref_count_inc:
+ * @rc: the address of a reference count variable
+ *
+ * Increases the reference count.
+ *
+ * Since: 2.58
+ */
+void
+g_ref_count_inc (grefcount *rc)
+{
+ grefcount rrc;
+
+ g_return_if_fail (rc != NULL);
+
+ rrc = *rc;
+
+ g_return_if_fail (rrc < 0);
+
+ /* Check for saturation */
+ if (rrc == G_MININT)
+ {
+ g_critical ("Reference count %p has reached saturation", rc);
+ return;
+ }
+
+ rrc -= 1;
+
+ *rc = rrc;
+}
+
+/**
+ * g_ref_count_dec:
+ * @rc: the address of a reference count variable
+ *
+ * Decreases the reference count.
+ *
+ * Returns: %TRUE if the reference count reached 0, and %FALSE otherwise
+ *
+ * Since: 2.58
+ */
+gboolean
+g_ref_count_dec (grefcount *rc)
+{
+ grefcount rrc;
+
+ g_return_val_if_fail (rc != NULL, FALSE);
+
+ rrc = *rc;
+
+ g_return_val_if_fail (rrc < 0, FALSE);
+
+ rrc += 1;
+ if (rrc == 0)
+ return TRUE;
+
+ *rc = rrc;
+
+ return FALSE;
+}
+
+/**
+ * g_ref_count_compare:
+ * @rc: the address of a reference count variable
+ * @val: the value to compare
+ *
+ * Compares the current value of @rc with @val.
+ *
+ * Returns: %TRUE if the reference count is the same
+ * as the given value
+ *
+ * Since: 2.58
+ */
+gboolean
+g_ref_count_compare (grefcount *rc,
+ gint val)
+{
+ grefcount rrc;
+
+ g_return_val_if_fail (rc != NULL, FALSE);
+ g_return_val_if_fail (val >= 0, FALSE);
+
+ rrc = *rc;
+
+ if (val == G_MAXINT)
+ return rrc == G_MININT;
+
+ return rrc == -val;
+}
+
+/**
+ * g_atomic_ref_count_init:
+ * @arc: the address of an atomic reference count variable
+ *
+ * Atomically initializes a reference count variable.
+ *
+ * Since: 2.58
+ */
+void
+g_atomic_ref_count_init (gatomicrefcount *arc)
+{
+ g_return_if_fail (arc != NULL);
+
+ /* Atomic refcounting is implemented using the positive range
+ * of signed integers:
+ *
+ * G_MININT Z¯< 0 > Z⁺ G_MAXINT
+ * |----------------------------|----------------------------|
+ *
+ * Acquiring a reference moves us towards MAXINT, and releasing a
+ * reference moves us towards 0.
+ */
+ g_atomic_int_set (arc, 1);
+}
+
+/**
+ * g_atomic_ref_count_inc:
+ * @arc: the address of an atomic reference count variable
+ *
+ * Atomically increases the reference count.
+ *
+ * Since: 2.58
+ */
+void
+g_atomic_ref_count_inc (gatomicrefcount *arc)
+{
+ g_return_if_fail (arc != NULL);
+ g_return_if_fail (g_atomic_int_get (arc) > 0);
+
+ if (g_atomic_int_get (arc) == G_MAXINT)
+ {
+ g_critical ("Reference count has reached saturation");
+ return;
+ }
+
+ g_atomic_int_inc (arc);
+}
+
+/**
+ * g_atomic_ref_count_dec:
+ * @arc: the address of an atomic reference count variable
+ *
+ * Atomically decreases the reference count.
+ *
+ * Returns: %TRUE if the reference count reached 0, and %FALSE otherwise
+ *
+ * Since: 2.58
+ */
+gboolean
+g_atomic_ref_count_dec (gatomicrefcount *arc)
+{
+ g_return_val_if_fail (arc != NULL, FALSE);
+ g_return_val_if_fail (g_atomic_int_get (arc) > 0, FALSE);
+
+ return g_atomic_int_dec_and_test (arc);
+}
+
+/**
+ * g_atomic_ref_count_compare:
+ * @arc: the address of an atomic reference count variable
+ * @val: the value to compare
+ *
+ * Atomically compares the current value of @arc with @val.
+ *
+ * Returns: %TRUE if the reference count is the same
+ * as the given value
+ *
+ * Since: 2.58
+ */
+gboolean
+g_atomic_ref_count_compare (gatomicrefcount *arc,
+ gint val)
+{
+ g_return_val_if_fail (arc != NULL, FALSE);
+ g_return_val_if_fail (val >= 0, FALSE);
+
+ return g_atomic_int_get (arc) == val;
+}
diff --git a/glib/grefcount.h b/glib/grefcount.h
new file mode 100644
index 000000000..b24c71e8c
--- /dev/null
+++ b/glib/grefcount.h
@@ -0,0 +1,52 @@
+/* grefcount.h: Reference counting
+ *
+ * Copyright 2018 Emmanuele Bassi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#ifndef __GREFCOUNT_H__
+#define __GREFCOUNT_H__
+
+#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#include
+
+G_BEGIN_DECLS
+
+GLIB_AVAILABLE_IN_2_58
+void g_ref_count_init (grefcount *rc);
+GLIB_AVAILABLE_IN_2_58
+void g_ref_count_inc (grefcount *rc);
+GLIB_AVAILABLE_IN_2_58
+gboolean g_ref_count_dec (grefcount *rc);
+GLIB_AVAILABLE_IN_2_58
+gboolean g_ref_count_compare (grefcount *rc,
+ gint val);
+
+GLIB_AVAILABLE_IN_2_58
+void g_atomic_ref_count_init (gatomicrefcount *arc);
+GLIB_AVAILABLE_IN_2_58
+void g_atomic_ref_count_inc (gatomicrefcount *arc);
+GLIB_AVAILABLE_IN_2_58
+gboolean g_atomic_ref_count_dec (gatomicrefcount *arc);
+GLIB_AVAILABLE_IN_2_58
+gboolean g_atomic_ref_count_compare (gatomicrefcount *arc,
+ gint val);
+
+G_END_DECLS
+
+#endif /* __GREFCOUNT_H__ */
diff --git a/glib/gtypes.h b/glib/gtypes.h
index 09d9bd145..67adb7f1f 100644
--- a/glib/gtypes.h
+++ b/glib/gtypes.h
@@ -510,6 +510,9 @@ struct _GTimeVal
glong tv_usec;
};
+typedef gint grefcount;
+typedef volatile gint gatomicrefcount;
+
G_END_DECLS
/* We prefix variable declarations so they can
diff --git a/glib/meson.build b/glib/meson.build
index 036d1f4d6..76d354c2a 100644
--- a/glib/meson.build
+++ b/glib/meson.build
@@ -76,6 +76,7 @@ glib_sub_headers = files(
'gquark.h',
'gqueue.h',
'grand.h',
+ 'grefcount.h',
'gregex.h',
'gscanner.h',
'gsequence.h',
@@ -159,6 +160,7 @@ glib_sources = files(
'gquark.c',
'gqueue.c',
'grand.c',
+ 'grefcount.c',
'gregex.c',
'gscanner.c',
'gsequence.c',