Add handle checking to the hdb system.

git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1842 fd59a12c-fef9-0310-b244-a6a79926bd2f
This commit is contained in:
Steven Dake 2009-03-11 23:28:01 +00:00
parent 2a4c53dc1b
commit 2b84d1075b
4 changed files with 77 additions and 13 deletions

View File

@ -430,7 +430,7 @@ static inline void app_deliver_fn (
for (i = 0; i <= totempg_max_handle; i++) {
res = hdb_handle_get (&totempg_groups_instance_database,
i, (void *)&instance);
hdb_nocheck_convert (i), (void *)&instance);
if (res == 0) {
assert (iov_len == 1);
@ -459,7 +459,7 @@ static inline void app_deliver_fn (
endian_conversion_required);
}
hdb_handle_put (&totempg_groups_instance_database, i);
hdb_handle_put (&totempg_groups_instance_database, hdb_nocheck_convert(i));
}
}
}

View File

@ -44,7 +44,7 @@
*/
typedef uint64_t confdb_handle_t;
#define OBJECT_PARENT_HANDLE 0
#define OBJECT_PARENT_HANDLE 0xFFFFFFFF00000000ULL
typedef enum {
CONFDB_TRACK_DEPTH_ONE,

View File

@ -36,7 +36,7 @@
#ifndef OBJDB_H_DEFINED
#define OBJDB_H_DEFINED
#define OBJECT_PARENT_HANDLE 0
#define OBJECT_PARENT_HANDLE 0xFFFFFFFF00000000ULL
#include <stdio.h>
#include <corosync/hdb.h>

View File

@ -52,6 +52,7 @@ enum HDB_HANDLE_STATE {
struct hdb_handle {
int state;
void *instance;
int check;
int ref_count;
};
@ -86,9 +87,11 @@ static inline int hdb_handle_create (
hdb_handle_t *handle_id_out)
{
int handle;
unsigned int check;
void *new_handles;
int found = 0;
void *instance;
int i;
pthread_mutex_lock (&handle_database->mutex);
@ -114,6 +117,20 @@ static inline int hdb_handle_create (
if (instance == 0) {
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;
@ -122,7 +139,9 @@ static inline int hdb_handle_create (
handle_database->handles[handle].ref_count = 1;
*handle_id_out = handle;
handle_database->handles[handle].check = check;
*handle_id_out = (((unsigned long long)(check)) << 32) | handle;
pthread_mutex_unlock (&handle_database->mutex);
@ -131,11 +150,21 @@ static inline int hdb_handle_create (
static inline int hdb_handle_get (
struct hdb_handle_database *handle_database,
hdb_handle_t handle,
hdb_handle_t handle_in,
void **instance)
{
unsigned int check = ((unsigned int)(((unsigned long long)handle_in) >> 32));
unsigned int handle = handle_in & 0xffffffff;
pthread_mutex_lock (&handle_database->mutex);
if (check != 0xffffffff &&
check != handle_database->handles[handle].check) {
pthread_mutex_unlock (&handle_database->mutex);
return (-1);
}
*instance = NULL;
if (handle >= handle_database->handle_count) {
pthread_mutex_unlock (&handle_database->mutex);
@ -155,11 +184,22 @@ static inline int hdb_handle_get (
return (0);
}
static inline void hdb_handle_put (
static inline int hdb_handle_put (
struct hdb_handle_database *handle_database,
hdb_handle_t handle)
hdb_handle_t handle_in)
{
unsigned int check = ((unsigned int)(((unsigned long long)handle_in) >> 32));
unsigned int handle = handle_in & 0xffffffff;
pthread_mutex_lock (&handle_database->mutex);
if (check != 0xffffffff &&
check != handle_database->handles[handle].check) {
pthread_mutex_unlock (&handle_database->mutex);
return (-1);
}
handle_database->handles[handle].ref_count -= 1;
assert (handle_database->handles[handle].ref_count >= 0);
@ -168,17 +208,29 @@ static inline void hdb_handle_put (
memset (&handle_database->handles[handle], 0, sizeof (struct hdb_handle));
}
pthread_mutex_unlock (&handle_database->mutex);
return (0);
}
static inline void hdb_handle_destroy (
static inline int hdb_handle_destroy (
struct hdb_handle_database *handle_database,
unsigned int handle)
hdb_handle_t handle_in)
{
unsigned int check = ((unsigned int)(((unsigned long long)handle_in) >> 32));
unsigned int handle = handle_in & 0xffffffff;
int res;
pthread_mutex_lock (&handle_database->mutex);
if (check != 0xffffffff &&
check != handle_database->handles[handle].check) {
pthread_mutex_unlock (&handle_database->mutex);
return (-1);
}
handle_database->handles[handle].state = HDB_HANDLE_STATE_PENDINGREMOVAL;
pthread_mutex_unlock (&handle_database->mutex);
hdb_handle_put (handle_database, handle);
res = hdb_handle_put (handle_database, handle);
return (res);
}
static inline void hdb_iterator_reset (
@ -195,10 +247,10 @@ static inline int hdb_iterator_next (
int res = -1;
while (handle_database->iterator < handle_database->handle_count) {
*handle = handle_database->iterator;
*handle = ((unsigned long long)(handle_database->handles[handle_database->iterator].check) << 32) | handle_database->iterator;
res = hdb_handle_get (
handle_database,
handle_database->iterator,
*handle,
instance);
handle_database->iterator += 1;
@ -209,4 +261,16 @@ static inline int hdb_iterator_next (
return (res);
}
static inline unsigned int hdb_base_convert (hdb_handle_t handle)
{
return (handle & 0xffffffff);
}
static inline unsigned long long hdb_nocheck_convert (unsigned int handle)
{
unsigned long long retvalue = 0xffffffffULL << 32 | handle;
return (retvalue);
}
#endif /* HDB_H_DEFINED */