Add objpool data structure to libsepol
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.
Signed-off-by Karl MacMillan <[email protected]>
---
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
@@ -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
@@ -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
@@ -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.