aboutsummaryrefslogtreecommitdiff
path: root/include/sqfs
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2022-12-04 01:33:45 +0100
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-01-19 16:24:56 +0100
commit47f24f2a8faf71395a1d054e9823beb000442cce (patch)
treedd01d8b69125b3dda444c9b92437ad0c5a0af9bc /include/sqfs
parent4160b50a0b4c51f8b7191928cdf38d9fb0147fe2 (diff)
Implement rudimentary reference counting for sqfs_object_t
Implement grab/drop functions to increase/decrease reference count and destroy the object if the count drops to 0. Make sure that all objects that maintain internal references actually grab that reference, duplicate it in the copy function, drop it in the destroy handler. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'include/sqfs')
-rw-r--r--include/sqfs/dir_reader.h3
-rw-r--r--include/sqfs/predef.h34
2 files changed, 32 insertions, 5 deletions
diff --git a/include/sqfs/dir_reader.h b/include/sqfs/dir_reader.h
index e6b23f2..ace7bad 100644
--- a/include/sqfs/dir_reader.h
+++ b/include/sqfs/dir_reader.h
@@ -206,8 +206,7 @@ extern "C" {
* version 1.2 introduced the @ref SQFS_DIR_READER_DOT_ENTRIES flag,
* earlier versions require the flags field to be set to zero.
*
- * @param super A pointer to the super block. Kept internally an used for
- * resolving table positions.
+ * @param super A pointer to the super block.
* @param cmp A compressor to use for unpacking meta data blocks.
* @param file The input file to read from.
* @param flags A combination of @ref SQFS_DIR_READER_FLAGS
diff --git a/include/sqfs/predef.h b/include/sqfs/predef.h
index 39da692..7a7eef8 100644
--- a/include/sqfs/predef.h
+++ b/include/sqfs/predef.h
@@ -124,22 +124,49 @@ typedef struct sqfs_xattr_id_table_t sqfs_xattr_id_table_t;
* @brief Base interface for all libsquashfs in-memory data structures.
*/
typedef struct sqfs_object_t {
+ size_t refcount;
+
void (*destroy)(struct sqfs_object_t *instance);
struct sqfs_object_t *(*copy)(const struct sqfs_object_t *orig);
} sqfs_object_t;
/**
- * @brief Destroy an object and free all its memory
+ * @brief Grab a reference to an object
*
* @memberof sqfs_object_t
*
* @param obj A pointer to an object or NULL
+ *
+ * @return The original pointer passed into the function
*/
-static SQFS_INLINE void sqfs_destroy(void *obj)
+static SQFS_INLINE void *sqfs_grab(void *obj)
{
if (obj)
- ((sqfs_object_t *)obj)->destroy((sqfs_object_t *)obj);
+ ((sqfs_object_t *)obj)->refcount += 1;
+ return obj;
+}
+
+/**
+ * @brief Drop a reference to an object, release it if it was the last reference
+ *
+ * @memberof sqfs_object_t
+ *
+ * @param obj A pointer to an object or NULL
+ *
+ * @return A NULL pointer.
+ */
+static SQFS_INLINE void *sqfs_drop(void *obj)
+{
+ if (obj) {
+ if (((sqfs_object_t *)obj)->refcount <= 1) {
+ ((sqfs_object_t *)obj)->destroy((sqfs_object_t *)obj);
+ } else {
+ ((sqfs_object_t *)obj)->refcount -= 1;
+ }
+ }
+
+ return NULL;
}
/**
@@ -174,6 +201,7 @@ void sqfs_object_init(void *obj,
void (*destroy_fn)(sqfs_object_t *),
sqfs_object_t *(*copy_fn)(const sqfs_object_t *))
{
+ ((sqfs_object_t *)obj)->refcount = 1;
((sqfs_object_t *)obj)->destroy = destroy_fn;
((sqfs_object_t *)obj)->copy = copy_fn;
}