|
|
@@ -47,36 +47,17 @@
|
|
|
#include <pthread.h>
|
|
|
#include <stdint.h>
|
|
|
#include <inttypes.h>
|
|
|
+#include <qb/qbhdb.h>
|
|
|
|
|
|
-typedef uint64_t hdb_handle_t;
|
|
|
+typedef qb_handle_t hdb_handle_t;
|
|
|
|
|
|
/*
|
|
|
* Formatting for string printing on 32/64 bit systems
|
|
|
*/
|
|
|
-#define HDB_D_FORMAT "%"PRIu64
|
|
|
-#define HDB_X_FORMAT "%"PRIx64
|
|
|
+#define HDB_D_FORMAT QB_HDB_D_FORMAT
|
|
|
+#define HDB_X_FORMAT QB_HDB_X_FORMAT
|
|
|
|
|
|
-enum HDB_HANDLE_STATE {
|
|
|
- HDB_HANDLE_STATE_EMPTY,
|
|
|
- HDB_HANDLE_STATE_PENDINGREMOVAL,
|
|
|
- HDB_HANDLE_STATE_ACTIVE
|
|
|
-};
|
|
|
-
|
|
|
-struct hdb_handle {
|
|
|
- int state;
|
|
|
- void *instance;
|
|
|
- int check;
|
|
|
- int ref_count;
|
|
|
-};
|
|
|
-
|
|
|
-struct hdb_handle_database {
|
|
|
- unsigned int handle_count;
|
|
|
- struct hdb_handle *handles;
|
|
|
- unsigned int iterator;
|
|
|
- void (*destructor) (void *);
|
|
|
- pthread_mutex_t lock;
|
|
|
- unsigned int first_run;
|
|
|
-};
|
|
|
+#define hdb_handle_database qb_hdb
|
|
|
|
|
|
static inline void hdb_database_lock (pthread_mutex_t *mutex)
|
|
|
{
|
|
|
@@ -97,28 +78,18 @@ static inline void hdb_database_lock_destroy (pthread_mutex_t *mutex)
|
|
|
pthread_mutex_destroy (mutex);
|
|
|
}
|
|
|
|
|
|
-#define DECLARE_HDB_DATABASE(database_name,destructor_function) \
|
|
|
-static struct hdb_handle_database (database_name) = { \
|
|
|
- .handle_count = 0, \
|
|
|
- .handles = NULL, \
|
|
|
- .iterator = 0, \
|
|
|
- .destructor = destructor_function, \
|
|
|
- .first_run = 1 \
|
|
|
-}; \
|
|
|
+#define DECLARE_HDB_DATABASE QB_HDB_DECLARE
|
|
|
|
|
|
static inline void hdb_create (
|
|
|
struct hdb_handle_database *handle_database)
|
|
|
{
|
|
|
- memset (handle_database, 0, sizeof (struct hdb_handle_database));
|
|
|
- hdb_database_lock_init (&handle_database->lock);
|
|
|
+ qb_hdb_create (handle_database);
|
|
|
}
|
|
|
|
|
|
static inline void hdb_destroy (
|
|
|
struct hdb_handle_database *handle_database)
|
|
|
{
|
|
|
- free (handle_database->handles);
|
|
|
- hdb_database_lock_destroy (&handle_database->lock);
|
|
|
- memset (handle_database, 0, sizeof (struct hdb_handle_database));
|
|
|
+ qb_hdb_destroy (handle_database);
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -127,72 +98,8 @@ static inline int hdb_handle_create (
|
|
|
int instance_size,
|
|
|
hdb_handle_t *handle_id_out)
|
|
|
{
|
|
|
- int handle;
|
|
|
- unsigned int check;
|
|
|
- void *new_handles;
|
|
|
- int found = 0;
|
|
|
- void *instance;
|
|
|
- int i;
|
|
|
-
|
|
|
- if (handle_database->first_run == 1) {
|
|
|
- handle_database->first_run = 0;
|
|
|
- hdb_database_lock_init (&handle_database->lock);
|
|
|
- }
|
|
|
- hdb_database_lock (&handle_database->lock);
|
|
|
-
|
|
|
- for (handle = 0; handle < handle_database->handle_count; handle++) {
|
|
|
- if (handle_database->handles[handle].state == HDB_HANDLE_STATE_EMPTY) {
|
|
|
- found = 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (found == 0) {
|
|
|
- handle_database->handle_count += 1;
|
|
|
- new_handles = (struct hdb_handle *)realloc (handle_database->handles,
|
|
|
- sizeof (struct hdb_handle) * handle_database->handle_count);
|
|
|
- if (new_handles == NULL) {
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- errno = ENOMEM;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
- handle_database->handles = new_handles;
|
|
|
- }
|
|
|
-
|
|
|
- instance = (void *)malloc (instance_size);
|
|
|
- if (instance == 0) {
|
|
|
- errno = ENOMEM;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * This code makes sure the random number isn't zero
|
|
|
- * We use 0 to specify an invalid handle out of the 1^64 address space
|
|
|
- * If we get 0 200 times in a row, the RNG may be broken
|
|
|
- */
|
|
|
- for (i = 0; i < 200; i++) {
|
|
|
- check = random();
|
|
|
-
|
|
|
- if (check != 0 && check != 0xffffffff) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- memset (instance, 0, instance_size);
|
|
|
-
|
|
|
- handle_database->handles[handle].state = HDB_HANDLE_STATE_ACTIVE;
|
|
|
-
|
|
|
- handle_database->handles[handle].instance = instance;
|
|
|
-
|
|
|
- handle_database->handles[handle].ref_count = 1;
|
|
|
-
|
|
|
- handle_database->handles[handle].check = check;
|
|
|
-
|
|
|
- *handle_id_out = (((unsigned long long)(check)) << 32) | handle;
|
|
|
-
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
-
|
|
|
- return (0);
|
|
|
+ return (qb_hdb_handle_create (handle_database, instance_size,
|
|
|
+ handle_id_out));
|
|
|
}
|
|
|
|
|
|
static inline int hdb_handle_get (
|
|
|
@@ -200,42 +107,7 @@ static inline int hdb_handle_get (
|
|
|
hdb_handle_t handle_in,
|
|
|
void **instance)
|
|
|
{
|
|
|
- unsigned int check = ((unsigned int)(((unsigned long long)handle_in) >> 32));
|
|
|
- unsigned int handle = handle_in & 0xffffffff;
|
|
|
-
|
|
|
- if (handle_database->first_run == 1) {
|
|
|
- handle_database->first_run = 0;
|
|
|
- hdb_database_lock_init (&handle_database->lock);
|
|
|
- }
|
|
|
- hdb_database_lock (&handle_database->lock);
|
|
|
-
|
|
|
- *instance = NULL;
|
|
|
- if (handle >= handle_database->handle_count) {
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- errno = EBADF;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-
|
|
|
- if (handle_database->handles[handle].state != HDB_HANDLE_STATE_ACTIVE) {
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- errno = EBADF;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-
|
|
|
- if (check != 0xffffffff &&
|
|
|
- check != handle_database->handles[handle].check) {
|
|
|
-
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- errno = EBADF;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-
|
|
|
- *instance = handle_database->handles[handle].instance;
|
|
|
-
|
|
|
- handle_database->handles[handle].ref_count += 1;
|
|
|
-
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- return (0);
|
|
|
+ return (qb_hdb_handle_get (handle_database, handle_in, instance));
|
|
|
}
|
|
|
|
|
|
static inline int hdb_handle_get_always (
|
|
|
@@ -243,159 +115,34 @@ static inline int hdb_handle_get_always (
|
|
|
hdb_handle_t handle_in,
|
|
|
void **instance)
|
|
|
{
|
|
|
- unsigned int check = ((unsigned int)(((unsigned long long)handle_in) >> 32));
|
|
|
- unsigned int handle = handle_in & 0xffffffff;
|
|
|
-
|
|
|
- if (handle_database->first_run == 1) {
|
|
|
- handle_database->first_run = 0;
|
|
|
- hdb_database_lock_init (&handle_database->lock);
|
|
|
- }
|
|
|
- hdb_database_lock (&handle_database->lock);
|
|
|
-
|
|
|
- *instance = NULL;
|
|
|
- if (handle >= handle_database->handle_count) {
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- errno = EBADF;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-
|
|
|
- if (handle_database->handles[handle].state == HDB_HANDLE_STATE_EMPTY) {
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- errno = EBADF;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-
|
|
|
- if (check != 0xffffffff &&
|
|
|
- check != handle_database->handles[handle].check) {
|
|
|
-
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- errno = EBADF;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-
|
|
|
- *instance = handle_database->handles[handle].instance;
|
|
|
-
|
|
|
- handle_database->handles[handle].ref_count += 1;
|
|
|
-
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- return (0);
|
|
|
+ return (qb_hdb_handle_get_always (handle_database, handle_in, instance));
|
|
|
}
|
|
|
|
|
|
static inline int hdb_handle_put (
|
|
|
struct hdb_handle_database *handle_database,
|
|
|
hdb_handle_t handle_in)
|
|
|
{
|
|
|
- unsigned int check = ((unsigned int)(((unsigned long long)handle_in) >> 32));
|
|
|
- unsigned int handle = handle_in & 0xffffffff;
|
|
|
-
|
|
|
- if (handle_database->first_run == 1) {
|
|
|
- handle_database->first_run = 0;
|
|
|
- hdb_database_lock_init (&handle_database->lock);
|
|
|
- }
|
|
|
- hdb_database_lock (&handle_database->lock);
|
|
|
-
|
|
|
- if (handle >= handle_database->handle_count) {
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
-
|
|
|
- errno = EBADF;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-
|
|
|
- if (check != 0xffffffff &&
|
|
|
- check != handle_database->handles[handle].check) {
|
|
|
-
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- errno = EBADF;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-
|
|
|
- handle_database->handles[handle].ref_count -= 1;
|
|
|
- assert (handle_database->handles[handle].ref_count >= 0);
|
|
|
-
|
|
|
- if (handle_database->handles[handle].ref_count == 0) {
|
|
|
- if (handle_database->destructor) {
|
|
|
- handle_database->destructor (handle_database->handles[handle].instance);
|
|
|
- }
|
|
|
- free (handle_database->handles[handle].instance);
|
|
|
- memset (&handle_database->handles[handle], 0, sizeof (struct hdb_handle));
|
|
|
- }
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- return (0);
|
|
|
+ return (qb_hdb_handle_put (handle_database, handle_in));
|
|
|
}
|
|
|
|
|
|
static inline int hdb_handle_destroy (
|
|
|
struct hdb_handle_database *handle_database,
|
|
|
hdb_handle_t handle_in)
|
|
|
{
|
|
|
- unsigned int check = ((unsigned int)(((unsigned long long)handle_in) >> 32));
|
|
|
- unsigned int handle = handle_in & 0xffffffff;
|
|
|
- int res;
|
|
|
-
|
|
|
- if (handle_database->first_run == 1) {
|
|
|
- handle_database->first_run = 0;
|
|
|
- hdb_database_lock_init (&handle_database->lock);
|
|
|
- }
|
|
|
- hdb_database_lock (&handle_database->lock);
|
|
|
-
|
|
|
- if (handle >= handle_database->handle_count) {
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
-
|
|
|
- errno = EBADF;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-
|
|
|
- if (check != 0xffffffff &&
|
|
|
- check != handle_database->handles[handle].check) {
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- errno = EBADF;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-
|
|
|
- handle_database->handles[handle].state = HDB_HANDLE_STATE_PENDINGREMOVAL;
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- res = hdb_handle_put (handle_database, handle_in);
|
|
|
- return (res);
|
|
|
+ return (qb_hdb_handle_destroy (handle_database, handle_in));
|
|
|
}
|
|
|
|
|
|
static inline int hdb_handle_refcount_get (
|
|
|
struct hdb_handle_database *handle_database,
|
|
|
hdb_handle_t handle_in)
|
|
|
{
|
|
|
- unsigned int check = ((unsigned int)(((unsigned long long)handle_in) >> 32));
|
|
|
- unsigned int handle = handle_in & 0xffffffff;
|
|
|
-
|
|
|
- int refcount = 0;
|
|
|
-
|
|
|
- if (handle_database->first_run == 1) {
|
|
|
- handle_database->first_run = 0;
|
|
|
- hdb_database_lock_init (&handle_database->lock);
|
|
|
- }
|
|
|
- hdb_database_lock (&handle_database->lock);
|
|
|
-
|
|
|
- if (handle >= handle_database->handle_count) {
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- errno = EBADF;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-
|
|
|
- if (check != 0xffffffff &&
|
|
|
- check != handle_database->handles[handle].check) {
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
- errno = EBADF;
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-
|
|
|
- refcount = handle_database->handles[handle].ref_count;
|
|
|
-
|
|
|
- hdb_database_unlock (&handle_database->lock);
|
|
|
-
|
|
|
- return (refcount);
|
|
|
+ return (qb_hdb_handle_refcount_get (handle_database, handle_in));
|
|
|
}
|
|
|
|
|
|
static inline void hdb_iterator_reset (
|
|
|
struct hdb_handle_database *handle_database)
|
|
|
{
|
|
|
- handle_database->iterator = 0;
|
|
|
+ qb_hdb_iterator_reset (handle_database);
|
|
|
}
|
|
|
|
|
|
static inline int hdb_iterator_next (
|
|
|
@@ -403,33 +150,17 @@ static inline int hdb_iterator_next (
|
|
|
void **instance,
|
|
|
hdb_handle_t *handle)
|
|
|
{
|
|
|
- int res = -1;
|
|
|
-
|
|
|
- while (handle_database->iterator < handle_database->handle_count) {
|
|
|
- *handle = ((unsigned long long)(handle_database->handles[handle_database->iterator].check) << 32) | handle_database->iterator;
|
|
|
- res = hdb_handle_get (
|
|
|
- handle_database,
|
|
|
- *handle,
|
|
|
- instance);
|
|
|
-
|
|
|
- handle_database->iterator += 1;
|
|
|
- if (res == 0) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- return (res);
|
|
|
+ return (qb_hdb_iterator_next (handle_database, instance, handle));
|
|
|
}
|
|
|
|
|
|
static inline unsigned int hdb_base_convert (hdb_handle_t handle)
|
|
|
{
|
|
|
- return (handle & 0xffffffff);
|
|
|
+ return (qb_hdb_base_convert (handle));
|
|
|
}
|
|
|
|
|
|
static inline unsigned long long hdb_nocheck_convert (unsigned int handle)
|
|
|
{
|
|
|
- unsigned long long retvalue = 0xffffffffULL << 32 | handle;
|
|
|
-
|
|
|
- return (retvalue);
|
|
|
+ return (qb_hdb_nocheck_convert (handle));
|
|
|
}
|
|
|
|
|
|
#endif /* HDB_H_DEFINED */
|