Skip to contentSkip to conversation

Add objpool data structure to libsepol

PATCH New Karl MacMillan 1 participant 1 message Apr 20, 2007 SELinux security module

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Add objpool data structure to libsepol

Add a reference counted object pool data structure to libsepol. Object pools allow the storage of reference counted pools of objects. This allows, for example, for many data structures to reference a single copy of an object (e.g., a string).

This version is updated to remove improper use of void** based on comments from James Antill.

---

 libsepol/include/sepol/objpool.h |  141 ++++++++++++++++++++++++++++++++++++++
 libsepol/src/objpool.c           |  135 ++++++++++++++++++++++++++++++++++++
 libsepol/tests/libsepol-tests.c  |    2 +
 libsepol/tests/test-objpool.c    |  117 ++++++++++++++++++++++++++++++++
 libsepol/tests/test-objpool.h    |   12 +++
 5 files changed, 407 insertions(+), 0 deletions(-)
libsepol/include/sepol/objpool.h new file +141 -0
new file mode 100644
index 0000000..624fa38
@@ -0,0 +1,141 @@
+/* Author : Karl MacMillan <[email protected]> */
+
+#ifndef __objpool_h__
+#define __objpool_h__
+
+#include <sepol/handle.h>
+
+/**
+ * \defgroup libsepol_objpool sepol_objpool: reference counted object pooling
+ * Object pools allow the storage of reference counted pools of objects. This
+ * allows, for example, for many data structures to reference a single
+ * copy of an object (e.g., a string).
+ *
+ * Each object pool stores a single type of object. Hashing, comparison,
+ * and freeing functions must be provided by the user for the object
+ * to be stored. The objects are treated as generic void pointers by
+ * the object pool, and are not manipulated or interpreted in any way.
+ *
+ * The object pool manages the memory for objects. For example, consider
+ * the following example (error handling omitted for brevity):
+ *
+ * \code
+ * struct sepol_objpool *p;
+ * char *a = strdup("foo");
+ * char *b = strdup("foo");
+ * char *c = strdup("bar");
+ *
+ * // creation of object pool ommitted
+ * a = sepol_object_add(p, a);
+ * b = sepol_object_add(p, b);
+ * assert(a == b);
+ * // a and b now point to a single copy for the string "foo".
+ * // The copy originally pointed to by b has been destroyed.
+ * c = sepol_object_add(p, c);
+ * sepol_object_del(p, c);
+ * // The object pool has destroyed its copy of the string "bar"
+ * // because the reference count became 0. The pointer c is no
+ * // longer valid.
+ * sepol_object_del(p, "foo");
+ * sepol_object_del(p, a);
+ * // deletion can use objects that compare as equal in addition
+ * // to pointers. The object pool is now empty.
+ * \endcode
+ */
+
+/* FIXME: These are the same as the hashing and key compare functions
+ * in policydb/hashtab.h - when hashtab.h is properly encapsulated and
+ * exported these should be merged.
+ */
+typedef unsigned int (*sepol_objpool_hash_t)(void *h, const void *key);
+typedef int (*sepol_objpool_cmp_t)(void *h, const void *key1, const void *key2);
+typedef void (*sepol_objpool_free_t)(void *obj);
+
+/**
+ * \ingroup libsepol_objpool
+ * \struct sepol_objpool
+ * The object pool data structure.
+ */
+struct sepol_objpool;
+
+/**
+ * \ingroup libsepol_objpool
+ * Create an object pool.
+ *
+ * Create an object pool with the appropriate functions for hashing,
+ * comparing, and freeing of the object type to be stored in the pool.
+ *
+ * @param h sepol handle (may be NULL)
+ * @param s pointer that will be set to the newly created object pool.
+ * @param hash pointer to a function to hash objects that will be managed
+ *  by the object pool. See sepol_symhash defined policydb/symtab.h for
+ *  an example hashing function.
+ * @param cmp pointer to a function to compare object that will be managed
+ *  by the object pool.
+ * @param obj_free pointer to a function to free the memory for objects
+ *  managed by the object pool.
+ * @param size size of the underlying hash table used to hold the objects.
+ *
+ * \retval SEPOL_OK success
+ * \retval SEPOL_ENOMEM out of memory
+ */
+extern int sepol_objpool_create(struct sepol_handle * h, struct sepol_objpool **s,
+				sepol_objpool_hash_t hash, sepol_objpool_cmp_t cmp,
+				sepol_objpool_free_t obj_free, unsigned int size);
+
+/**
+ * \ingroup libsepol_objpool
+ * Destroy an object pool. All of the memory associated with the object
+ * pool and all of the objects that it is managing is freed.
+ *
+ * @param h sepol handle (may be NULL)
+ * @param s object pool to destroy
+ *
+ * \retval SEPOL_OK success
+ * \retval SEPOL_ENOMEM out of memory
+ */
+extern int sepol_objpool_free(struct sepol_handle *h, struct sepol_objpool *s);
+
+/**
+ * \ingroup libsepol_objpool
+ *
+ * Add an object to the object pool. The pointer returned will point
+ * to the object pool copy of the object (the pointer may or may not
+ * equal the passed in pointer depending upon whether the object pool
+ * already contains a copy of the object). If the object pool already
+ * contains a copy of the passed in object the passed in copy will be
+ * freed and the reference count of the existing object will be
+ * incremented.
+ *
+ * @param h sepol handle (may be NULL)
+ * @param s object pool to which to add the object
+ * @param obj object to be added
+ *
+ * \retval non-NULL success (pointer to shared object)
+ * \retval NULL error
+ */
+extern void *sepol_objpool_add(struct sepol_handle *h, struct sepol_objpool *s,
+			       void *obj);
+
+/**
+ * \ingroup libsepol_objpool
+ *
+ * Delete an object from the object pool. If other references to the
+ * object remain (from calls to sepol_objpool_add) the object will not
+ * be destroyed. However, the caller should *never* depend upon the
+ * object persisting beyond a call sepol_objpool_del. The object
+ * passed in does is not required to be a pointer returned by
+ * sepol_objpool_add; however, it is required to compare as equal to
+ * an existing object.
+ *
+ * @param h sepol handle (may be NULL)
+ * @param s object pool from which to delete object
+ * @param obj object to delete
+ *
+ * \retval SEPOL_OK success
+ * \retval SEPOL_ENOENT object does not exist in pool
+ * \retval SEPOL_ENOMEM out of memory
+ */
+extern int sepol_objpool_del(struct sepol_handle *h, struct sepol_objpool *s, void *obj);
+
+#endif
libsepol/src/objpool.c new file +135 -0

135 lines not on this page · raw message

libsepol/tests/libsepol-tests.c +2 -0
index d2f7e8a..2fee01d 100644
@@ -24,6 +24,7 @@
 #include "test-deps.h"
 #include "test-list.h"
 #include "test-hashtab.h"
+#include "test-objpool.h"
 
 #include <CUnit/Basic.h>
 #include <CUnit/Console.h>
@@ -65,6 +66,7 @@ static int do_tests(int interactive, int verbose)
 	DECLARE_SUITE(deps);
 	DECLARE_SUITE(list);
 	DECLARE_SUITE(hashtab);
+	DECLARE_SUITE(objpool);
 
 	if (verbose)
 		CU_basic_set_mode(CU_BRM_VERBOSE);
libsepol/tests/test-objpool.c new file +117 -0

117 lines not on this page · raw message

libsepol/tests/test-objpool.h new file +12 -0
new file mode 100644
index 0000000..4ed81f2
@@ -0,0 +1,12 @@
+/* Author : Karl MacMillan <[email protected]> */
+
+#ifndef __test_objpool_h__
+#define __test_objpool_h__
+
+#include <CUnit/Basic.h>
+
+int objpool_test_init(void);
+int objpool_test_cleanup(void);
+int objpool_add_tests(CU_pSuite suite);
+
+#endif

--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.