From 41f0c0f9089ec941ceb70e2a6ad1b958483eb2ae Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 28 Mar 2025 05:45:19 +0100
Subject: Add a locking feature to thick objects.

---
 plugins/pychrysalide/glibext/objhole.c | 102 ++++++++++++++++++++++++++++++++-
 src/glibext/objhole-int.h              |   3 +
 src/glibext/objhole.c                  |  85 +++++++++++++++++++++++----
 src/glibext/objhole.h                  |  16 ++++++
 4 files changed, 195 insertions(+), 11 deletions(-)

diff --git a/plugins/pychrysalide/glibext/objhole.c b/plugins/pychrysalide/glibext/objhole.c
index 2a3ad6f..6bea5d1 100644
--- a/plugins/pychrysalide/glibext/objhole.c
+++ b/plugins/pychrysalide/glibext/objhole.c
@@ -37,12 +37,25 @@
 
 
 
-CREATE_DYN_CONSTRUCTOR(thick_object, G_TYPE_THICK_OBJECT);
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
 
+CREATE_DYN_CONSTRUCTOR(thick_object, G_TYPE_THICK_OBJECT);
 
 /* Initialise une instance sur la base du dérivé de GObject. */
 static int py_thick_object_init(PyObject *, PyObject *, PyObject *);
 
+
+
+/* ------------------ LIAISON DE FONCTIONNALITES AVEC L'API PYTHON ------------------ */
+
+
+/* Pose un verrou à l'aide du bit dédié de GObject. */
+static PyObject *py_thick_object_lock(PyObject *, PyObject *);
+
+/* Retire un verrou via le bit dédié de GObject. */
+static PyObject *py_thick_object_unlock(PyObject *, PyObject *);
+
 /* Indique le nombre de bits accaparés par la GLib. */
 static PyObject *py_thick_object_get__GOBJECT_RESERVED_EXTRA_BITS(PyObject *, void *);
 
@@ -54,6 +67,11 @@ static int py_thick_object_set_extra(PyObject *, PyObject *, void *);
 
 
 
+/* ---------------------------------------------------------------------------------- */
+/*                          GLUE POUR CREATION DEPUIS PYTHON                          */
+/* ---------------------------------------------------------------------------------- */
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : self = objet à initialiser (théoriquement).                  *
@@ -92,6 +110,86 @@ static int py_thick_object_init(PyObject *self, PyObject *args, PyObject *kwds)
 }
 
 
+
+/* ---------------------------------------------------------------------------------- */
+/*                    LIAISON DE FONCTIONNALITES AVEC L'API PYTHON                    */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = instance représentant une extension d'objet.          *
+*                args = arguments fournis à l'appel, non utilisé ici.         *
+*                                                                             *
+*  Description : Pose un verrou à l'aide du bit dédié de GObject.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_thick_object_lock(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Résultat à retourner        */
+    GThickObject *obj;                      /* Version GLib de l'instance  */
+
+#define THICK_OBJECT_LOCK_METHOD PYTHON_METHOD_DEF      \
+(                                                       \
+    lock, "$self",                                      \
+    METH_NOARGS, py_thick_object,                       \
+    "Lock the object using the internal GLib bit.\n"    \
+)
+
+    obj = G_THICK_OBJECT(pygobject_get(self));
+
+    g_thick_object_lock(obj);
+
+    result = Py_None;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = instance représentant une extension d'objet.          *
+*                args = arguments fournis à l'appel, non utilisé ici.         *
+*                                                                             *
+*  Description : Retire un verrou via le bit dédié de GObject.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_thick_object_unlock(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Résultat à retourner        */
+    GThickObject *obj;                      /* Version GLib de l'instance  */
+
+#define THICK_OBJECT_UNLOCK_METHOD PYTHON_METHOD_DEF    \
+(                                                       \
+    unlock, "$self",                                    \
+    METH_NOARGS, py_thick_object,                       \
+    "Unlock the object using the internal GLib bit.\n"  \
+)
+
+    obj = G_THICK_OBJECT(pygobject_get(self));
+
+    g_thick_object_unlock(obj);
+
+    result = Py_None;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : self    = objet Python concerné par l'appel.                 *
@@ -215,6 +313,8 @@ static int py_thick_object_set_extra(PyObject *self, PyObject *value, void *clos
 PyTypeObject *get_python_thick_object_type(void)
 {
     static PyMethodDef py_thick_object_methods[] = {
+        THICK_OBJECT_LOCK_METHOD,
+        THICK_OBJECT_UNLOCK_METHOD,
         { NULL }
     };
 
diff --git a/src/glibext/objhole-int.h b/src/glibext/objhole-int.h
index aa8a1f8..dbfb412 100644
--- a/src/glibext/objhole-int.h
+++ b/src/glibext/objhole-int.h
@@ -105,6 +105,9 @@
 #endif
 
 
+#define GOBJECT_LOCK_BIT 3
+
+
 /* Nouvelle version dense des objets (instance) */
 typedef struct _GThickObject
 {
diff --git a/src/glibext/objhole.c b/src/glibext/objhole.c
index 20bb2a8..fd6fbc9 100644
--- a/src/glibext/objhole.c
+++ b/src/glibext/objhole.c
@@ -38,10 +38,10 @@ static void g_thick_object_class_init(GThickObjectClass *);
 static void g_thick_object_init(GThickObject *);
 
 /* Supprime toutes les références externes. */
-static void g_thick_object_dispose(GThickObject *);
+static void g_thick_object_dispose(GObject *);
 
 /* Procède à la libération totale de la mémoire. */
-static void g_thick_object_finalize(GThickObject *);
+static void g_thick_object_finalize(GObject *);
 
 
 
@@ -66,8 +66,8 @@ static void g_thick_object_class_init(GThickObjectClass *klass)
 
     object = G_OBJECT_CLASS(klass);
 
-    object->dispose = (GObjectFinalizeFunc/* ! */)g_thick_object_dispose;
-    object->finalize = (GObjectFinalizeFunc)g_thick_object_finalize;
+    object->dispose = g_thick_object_dispose;
+    object->finalize = g_thick_object_finalize;
 
 }
 
@@ -93,7 +93,7 @@ static void g_thick_object_init(GThickObject *obj)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : obj = instance d'objet GLib à traiter.                       *
+*  Paramètres  : object = instance d'objet GLib à traiter.                    *
 *                                                                             *
 *  Description : Supprime toutes les références externes.                     *
 *                                                                             *
@@ -103,16 +103,16 @@ static void g_thick_object_init(GThickObject *obj)
 *                                                                             *
 ******************************************************************************/
 
-static void g_thick_object_dispose(GThickObject *obj)
+static void g_thick_object_dispose(GObject *object)
 {
-    G_OBJECT_CLASS(g_thick_object_parent_class)->dispose(G_OBJECT(obj));
+    G_OBJECT_CLASS(g_thick_object_parent_class)->dispose(object);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : obj = instance d'objet GLib à traiter.                       *
+*  Paramètres  : object = instance d'objet GLib à traiter.                    *
 *                                                                             *
 *  Description : Procède à la libération totale de la mémoire.                *
 *                                                                             *
@@ -122,15 +122,80 @@ static void g_thick_object_dispose(GThickObject *obj)
 *                                                                             *
 ******************************************************************************/
 
-static void g_thick_object_finalize(GThickObject *obj)
+static void g_thick_object_finalize(GObject *object)
 {
-    G_OBJECT_CLASS(g_thick_object_parent_class)->finalize(G_OBJECT(obj));
+    G_OBJECT_CLASS(g_thick_object_parent_class)->finalize(object);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : obj = instance d'objet GLib à manipuler.                     *
+*                                                                             *
+*  Description : Pose un verrou à l'aide du bit dédié de GObject.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_thick_object_lock(GThickObject *obj)
+{
+    g_bit_lock((gint *)&obj->extra, GOBJECT_LOCK_BIT);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : obj = instance d'objet GLib à manipuler.                     *
+*                                                                             *
+*  Description : Retire un verrou via le bit dédié de GObject.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_thick_object_unlock(GThickObject *obj)
+{
+    g_bit_unlock((gint *)&obj->extra, GOBJECT_LOCK_BIT);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : obj = instance d'objet GLib à manipuler.                     *
+*                                                                             *
+*  Description : Vérifie qu'un verrou est appliqué à l'aide du bit de GObject.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+#ifndef NDEBUG
+bool g_thick_object_check_lock(GThickObject *obj)
+{
+    bool result;                            /* Bilan à retourner           */
+    gboolean status;                        /* Bilan d'une tentative       */
+
+    status = g_bit_trylock((gint *)&obj->extra, GOBJECT_LOCK_BIT);
+
+    result = (status == FALSE);
+
+    return result;
+
+}
+#endif
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : obj = instance d'objet GLib à consulter.                     *
 *                                                                             *
 *  Description : Fournit la valeur courante de la zone de stockage d'un objet.*
diff --git a/src/glibext/objhole.h b/src/glibext/objhole.h
index c1e8cf1..461c37a 100644
--- a/src/glibext/objhole.h
+++ b/src/glibext/objhole.h
@@ -25,6 +25,11 @@
 #define _GLIBEXT_OBJHOLE_H
 
 
+#ifndef NDEBUG
+#   include <stdbool.h>
+#endif
+
+
 #include "../glibext/helpers.h"
 
 
@@ -34,6 +39,17 @@
 DECLARE_GTYPE(GThickObject, g_thick_object, G, THICK_OBJECT);
 
 
+/* Pose un verrou à l'aide du bit dédié de GObject. */
+void g_thick_object_lock(GThickObject *);
+
+/* Retire un verrou via le bit dédié de GObject. */
+void g_thick_object_unlock(GThickObject *);
+
+/* Vérifie qu'un verrou est appliqué à l'aide du bit de GObject. */
+#ifndef NDEBUG
+bool g_thick_object_check_lock(GThickObject *obj);
+#endif
+
 /* Fournit la valeur courante de la zone de stockage d'un objet. */
 guint g_thick_object_get_extra(const GThickObject *);
 
-- 
cgit v0.11.2-87-g4458