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/ |