hdb.c   hdb.c 
skipping to change at line 32 skipping to change at line 32
#include <qb/qbhdb.h> #include <qb/qbhdb.h>
#include <qb/qbatomic.h> #include <qb/qbatomic.h>
enum QB_HDB_HANDLE_STATE { enum QB_HDB_HANDLE_STATE {
QB_HDB_HANDLE_STATE_EMPTY, QB_HDB_HANDLE_STATE_EMPTY,
QB_HDB_HANDLE_STATE_PENDINGREMOVAL, QB_HDB_HANDLE_STATE_PENDINGREMOVAL,
QB_HDB_HANDLE_STATE_ACTIVE QB_HDB_HANDLE_STATE_ACTIVE
}; };
static void qb_hdb_create_first_run(struct qb_hdb *hdb) static void
qb_hdb_create_first_run(struct qb_hdb *hdb)
{ {
if (hdb->first_run == 1) { if (hdb->first_run == 1) {
hdb->first_run = 0; hdb->first_run = 0;
qb_atomic_init(); qb_atomic_init();
hdb->handles = qb_array_create(32, sizeof(struct qb_hdb_hand le)); hdb->handles = qb_array_create(32, sizeof(struct qb_hdb_hand le));
} }
} }
void qb_hdb_create(struct qb_hdb *hdb) void
qb_hdb_create(struct qb_hdb *hdb)
{ {
memset(hdb, 0, sizeof(struct qb_hdb)); memset(hdb, 0, sizeof(struct qb_hdb));
hdb->first_run = 1; hdb->first_run = 1;
qb_hdb_create_first_run(hdb); qb_hdb_create_first_run(hdb);
} }
void qb_hdb_destroy(struct qb_hdb *hdb) void
qb_hdb_destroy(struct qb_hdb *hdb)
{ {
qb_array_free(hdb->handles); qb_array_free(hdb->handles);
memset(hdb, 0, sizeof(struct qb_hdb)); memset(hdb, 0, sizeof(struct qb_hdb));
} }
int32_t qb_hdb_handle_create(struct qb_hdb *hdb, int32_t instance_size, int32_t
qb_handle_t * handle_id_out) qb_hdb_handle_create(struct qb_hdb *hdb, int32_t instance_size,
qb_handle_t * handle_id_out)
{ {
int32_t handle; int32_t handle;
int32_t res = 0; int32_t res = 0;
uint32_t check; uint32_t check;
int32_t found = 0; int32_t found = 0;
void *instance; void *instance;
int32_t i; int32_t i;
struct qb_hdb_handle *entry = NULL; struct qb_hdb_handle *entry = NULL;
int32_t handle_count; int32_t handle_count;
skipping to change at line 83 skipping to change at line 87
qb_atomic_int_inc(&entry->ref_count); qb_atomic_int_inc(&entry->ref_count);
break; break;
} }
} }
if (found == 0) { if (found == 0) {
res = qb_array_grow(hdb->handles, handle_count + 1); res = qb_array_grow(hdb->handles, handle_count + 1);
if (res != 0) { if (res != 0) {
return res; return res;
} }
res = qb_array_index(hdb->handles, handle_count, (void**)&en res = qb_array_index(hdb->handles, handle_count,
try); (void **)&entry);
if (res != 0) { if (res != 0) {
return res; return res;
} }
qb_atomic_int_inc((int32_t*)&hdb->handle_count); qb_atomic_int_inc((int32_t *)&hdb->handle_count);
} }
instance = malloc(instance_size); instance = malloc(instance_size);
if (instance == 0) { if (instance == 0) {
return -ENOMEM; return -ENOMEM;
} }
/* /*
* This code makes sure the random number isn't zero * This code makes sure the random number isn't zero
* We use 0 to specify an invalid handle out of the 1^64 address spa ce * We use 0 to specify an invalid handle out of the 1^64 address spa ce
skipping to change at line 120 skipping to change at line 125
entry->state = QB_HDB_HANDLE_STATE_ACTIVE; entry->state = QB_HDB_HANDLE_STATE_ACTIVE;
entry->instance = instance; entry->instance = instance;
entry->ref_count = 1; entry->ref_count = 1;
entry->check = check; entry->check = check;
*handle_id_out = (((uint64_t) (check)) << 32) | handle; *handle_id_out = (((uint64_t) (check)) << 32) | handle;
return res; return res;
} }
int32_t qb_hdb_handle_get(struct qb_hdb * hdb, qb_handle_t handle_in, int32_t
void **instance) qb_hdb_handle_get(struct qb_hdb * hdb, qb_handle_t handle_in, void **instan
ce)
{ {
uint32_t check = ((uint32_t) (((uint64_t) handle_in) >> 32)); uint32_t check = ((uint32_t) (((uint64_t) handle_in) >> 32));
uint32_t handle = handle_in & 0xffffffff; uint32_t handle = handle_in & 0xffffffff;
struct qb_hdb_handle *entry; struct qb_hdb_handle *entry;
int32_t handle_count; int32_t handle_count;
qb_hdb_create_first_run(hdb); qb_hdb_create_first_run(hdb);
*instance = NULL; *instance = NULL;
handle_count = qb_atomic_int_get(&hdb->handle_count); handle_count = qb_atomic_int_get(&hdb->handle_count);
if (handle >= handle_count) { if (handle >= handle_count) {
return (-EBADF); return (-EBADF);
} }
if (qb_array_index(hdb->handles, handle, (void**)&entry) != 0 || if (qb_array_index(hdb->handles, handle, (void **)&entry) != 0 ||
entry->state != QB_HDB_HANDLE_STATE_ACTIVE) { entry->state != QB_HDB_HANDLE_STATE_ACTIVE) {
return (-EBADF); return (-EBADF);
} }
if (check != 0xffffffff && check != entry->check) { if (check != 0xffffffff && check != entry->check) {
return (-EBADF); return (-EBADF);
} }
qb_atomic_int_inc(&entry->ref_count); qb_atomic_int_inc(&entry->ref_count);
*instance = entry->instance; *instance = entry->instance;
return (0); return (0);
} }
int32_t qb_hdb_handle_get_always(struct qb_hdb * hdb, qb_handle_t handle_in int32_t
, qb_hdb_handle_get_always(struct qb_hdb * hdb, qb_handle_t handle_in,
void **instance) void **instance)
{ {
return qb_hdb_handle_get(hdb, handle_in, instance); return qb_hdb_handle_get(hdb, handle_in, instance);
} }
int32_t qb_hdb_handle_put(struct qb_hdb * hdb, qb_handle_t handle_in) int32_t
qb_hdb_handle_put(struct qb_hdb * hdb, qb_handle_t handle_in)
{ {
uint32_t check = ((uint32_t) (((uint64_t) handle_in) >> 32)); uint32_t check = ((uint32_t) (((uint64_t) handle_in) >> 32));
uint32_t handle = handle_in & 0xffffffff; uint32_t handle = handle_in & 0xffffffff;
struct qb_hdb_handle *entry; struct qb_hdb_handle *entry;
int32_t handle_count; int32_t handle_count;
qb_hdb_create_first_run(hdb); qb_hdb_create_first_run(hdb);
handle_count = qb_atomic_int_get(&hdb->handle_count); handle_count = qb_atomic_int_get(&hdb->handle_count);
if (handle >= handle_count) { if (handle >= handle_count) {
return (-EBADF); return (-EBADF);
} }
if (qb_array_index(hdb->handles, handle, (void**)&entry) != 0 || if (qb_array_index(hdb->handles, handle, (void **)&entry) != 0 ||
(check != 0xffffffff && check != entry->check)) { (check != 0xffffffff && check != entry->check)) {
return (-EBADF); return (-EBADF);
} }
if (qb_atomic_int_dec_and_test(&entry->ref_count)) { if (qb_atomic_int_dec_and_test(&entry->ref_count)) {
if (hdb->destructor) { if (hdb->destructor) {
hdb->destructor(entry->instance); hdb->destructor(entry->instance);
} }
free(entry->instance); free(entry->instance);
memset(entry, 0, sizeof(struct qb_hdb_handle)); memset(entry, 0, sizeof(struct qb_hdb_handle));
} }
return (0); return (0);
} }
int32_t qb_hdb_handle_destroy(struct qb_hdb * hdb, qb_handle_t handle_in) int32_t
qb_hdb_handle_destroy(struct qb_hdb * hdb, qb_handle_t handle_in)
{ {
uint32_t check = ((uint32_t) (((uint64_t) handle_in) >> 32)); uint32_t check = ((uint32_t) (((uint64_t) handle_in) >> 32));
uint32_t handle = handle_in & 0xffffffff; uint32_t handle = handle_in & 0xffffffff;
int32_t res; int32_t res;
struct qb_hdb_handle *entry; struct qb_hdb_handle *entry;
int32_t handle_count; int32_t handle_count;
qb_hdb_create_first_run(hdb); qb_hdb_create_first_run(hdb);
handle_count = qb_atomic_int_get(&hdb->handle_count); handle_count = qb_atomic_int_get(&hdb->handle_count);
if (handle >= handle_count) { if (handle >= handle_count) {
return (-EBADF); return (-EBADF);
} }
if (qb_array_index(hdb->handles, handle, (void**)&entry) != 0 || if (qb_array_index(hdb->handles, handle, (void **)&entry) != 0 ||
(check != 0xffffffff && check != entry->check)) { (check != 0xffffffff && check != entry->check)) {
return (-EBADF); return (-EBADF);
} }
entry->state = QB_HDB_HANDLE_STATE_PENDINGREMOVAL; entry->state = QB_HDB_HANDLE_STATE_PENDINGREMOVAL;
res = qb_hdb_handle_put(hdb, handle_in); res = qb_hdb_handle_put(hdb, handle_in);
return (res); return (res);
} }
int32_t qb_hdb_handle_refcount_get(struct qb_hdb * hdb, qb_handle_t handle_ int32_t
in) qb_hdb_handle_refcount_get(struct qb_hdb * hdb, qb_handle_t handle_in)
{ {
uint32_t check = ((uint32_t) (((uint64_t) handle_in) >> 32)); uint32_t check = ((uint32_t) (((uint64_t) handle_in) >> 32));
uint32_t handle = handle_in & 0xffffffff; uint32_t handle = handle_in & 0xffffffff;
struct qb_hdb_handle *entry; struct qb_hdb_handle *entry;
int32_t handle_count; int32_t handle_count;
int32_t refcount = 0; int32_t refcount = 0;
qb_hdb_create_first_run(hdb); qb_hdb_create_first_run(hdb);
handle_count = qb_atomic_int_get(&hdb->handle_count); handle_count = qb_atomic_int_get(&hdb->handle_count);
if (handle >= handle_count) { if (handle >= handle_count) {
return (-EBADF); return (-EBADF);
} }
if (qb_array_index(hdb->handles, handle, (void**)&entry) != 0 || if (qb_array_index(hdb->handles, handle, (void **)&entry) != 0 ||
(check != 0xffffffff && check != entry->check)) { (check != 0xffffffff && check != entry->check)) {
return (-EBADF); return (-EBADF);
} }
refcount = qb_atomic_int_get(&entry->ref_count); refcount = qb_atomic_int_get(&entry->ref_count);
return (refcount); return (refcount);
} }
void qb_hdb_iterator_reset(struct qb_hdb *hdb) void
qb_hdb_iterator_reset(struct qb_hdb *hdb)
{ {
hdb->iterator = 0; hdb->iterator = 0;
} }
int32_t qb_hdb_iterator_next(struct qb_hdb *hdb, void **instance, int32_t
qb_handle_t * handle) qb_hdb_iterator_next(struct qb_hdb *hdb, void **instance, qb_handle_t * han
dle)
{ {
int32_t res = -1; int32_t res = -1;
uint64_t checker; uint64_t checker;
struct qb_hdb_handle *entry; struct qb_hdb_handle *entry;
int32_t handle_count; int32_t handle_count;
handle_count = qb_atomic_int_get(&hdb->handle_count); handle_count = qb_atomic_int_get(&hdb->handle_count);
while (hdb->iterator < handle_count) { while (hdb->iterator < handle_count) {
res = qb_array_index(hdb->handles, hdb->iterator, (void**)&e res = qb_array_index(hdb->handles,
ntry); hdb->iterator,
(void **)&entry);
if (res != 0) { if (res != 0) {
break; break;
} }
checker = (uint64_t) (entry->check); checker = (uint64_t) (entry->check);
*handle = (checker << 32) | hdb->iterator; *handle = (checker << 32) | hdb->iterator;
res = qb_hdb_handle_get(hdb, *handle, instance); res = qb_hdb_handle_get(hdb, *handle, instance);
hdb->iterator += 1; hdb->iterator += 1;
if (res == 0) { if (res == 0) {
break; break;
} }
} }
return (res); return (res);
} }
uint32_t qb_hdb_base_convert(qb_handle_t handle) uint32_t
qb_hdb_base_convert(qb_handle_t handle)
{ {
return (handle & 0xffffffff); return (handle & 0xffffffff);
} }
uint64_t qb_hdb_nocheck_convert(uint32_t handle) uint64_t
qb_hdb_nocheck_convert(uint32_t handle)
{ {
uint64_t retvalue = 0xffffffffULL << 32 | handle; uint64_t retvalue = 0xffffffffULL << 32 | handle;
return (retvalue); return (retvalue);
} }
 End of changes. 20 change blocks. 
28 lines changed or deleted 40 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/