[asterisk-commits] rizzo: branch rizzo/astobj2 r45894 -
/team/rizzo/astobj2/main/astobj2.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Sun Oct 22 12:58:50 MST 2006
Author: rizzo
Date: Sun Oct 22 14:58:49 2006
New Revision: 45894
URL: http://svn.digium.com/view/asterisk?rev=45894&view=rev
Log:
more debugging...
Modified:
team/rizzo/astobj2/main/astobj2.c
Modified: team/rizzo/astobj2/main/astobj2.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/main/astobj2.c?rev=45894&r1=45893&r2=45894&view=diff
==============================================================================
--- team/rizzo/astobj2/main/astobj2.c (original)
+++ team/rizzo/astobj2/main/astobj2.c Sun Oct 22 14:58:49 2006
@@ -63,30 +63,30 @@
*/
#define EXTERNAL_OBJ(_p) ((_p) == NULL ? NULL : (_p)->user_data)
-int astobj2_lock(void *a)
-{
- return ast_mutex_lock( &INTERNAL_OBJ(a)->priv_data.lock );
-}
-
-int astobj2_unlock(void *a)
-{
- return ast_mutex_unlock( &INTERNAL_OBJ(a)->priv_data.lock );
-}
-
-/*
- * we expect a to be non-NULL
- */
-int astobj2_ref(void *a, const int delta)
+int astobj2_lock(void *user_data)
+{
+ return ast_mutex_lock( &INTERNAL_OBJ(user_data)->priv_data.lock );
+}
+
+int astobj2_unlock(void *user_data)
+{
+ return ast_mutex_unlock( &INTERNAL_OBJ(user_data)->priv_data.lock );
+}
+
+/*
+ * The argument is a pointer to the user portion.
+ */
+int astobj2_ref(void *user_data, const int delta)
{
#if 0
ast_log(LOG_NOTICE, "Reference counter changed by %i\n", delta);
#endif
- struct astobj2 *obj = INTERNAL_OBJ(a);
+ struct astobj2 *obj = INTERNAL_OBJ(user_data);
int current_value;
int ret;
- assert(a != NULL);
+ assert(user_data != NULL);
/* if delta is 0, just return the refcount */
if (delta == 0)
return (obj->priv_data.ref_counter);
@@ -94,19 +94,19 @@
/* we modify with an atomic operation the reference counter */
ret = ast_atomic_fetchadd_int( &obj->priv_data.ref_counter, delta );
current_value = ret + delta;
- ast_log(LOG_NOTICE, "+++ refcount %d for %p\n", current_value, a);
+ ast_log(LOG_NOTICE, "+++ refcount %d for %p\n", current_value, user_data);
/* this case must never happen */
if (current_value < 0) {
- ast_log(LOG_ERROR, "refcount %d on object %p\n", current_value, a);
+ ast_log(LOG_ERROR, "refcount %d on object %p\n", current_value, user_data);
sleep(1);
}
if (current_value <= 0) { /* last reference, destroy the object */
- ast_log(LOG_DEBUG, "refcount %d on object %p, we destroy the object\n", current_value, a);
+ ast_log(LOG_DEBUG, "refcount %d on object %p, we destroy the object\n", current_value, user_data);
if (obj->priv_data.destructor_fn != NULL)
- obj->priv_data.destructor_fn(a);
+ obj->priv_data.destructor_fn(user_data);
ast_mutex_destroy(&obj->priv_data.lock);
/* for safety, zero-out the astobj2 header and also the
@@ -127,23 +127,23 @@
void *astobj2_obj_alloc(size_t data_size, astobj2_destructor_fn destructor_fn)
{
/* allocation */
- struct astobj2 *a;
+ struct astobj2 *obj;
if (data_size < sizeof(void *))
data_size = sizeof(void *);
- a = ast_calloc( 1, sizeof(struct astobj2) + data_size );
-
- if ( a == NULL)
+ obj = ast_calloc( 1, sizeof(struct astobj2) + data_size );
+
+ if (obj == NULL)
return NULL;
/* init */
- ast_mutex_init(&a->priv_data.lock);
- a->priv_data.ref_counter = 1;
- a->priv_data.destructor_fn = destructor_fn; /* can be NULL */
+ ast_mutex_init(&obj->priv_data.lock);
+ obj->priv_data.ref_counter = 1;
+ obj->priv_data.destructor_fn = destructor_fn; /* can be NULL */
/* return a pointer to the user data */
- return EXTERNAL_OBJ(a);
+ return EXTERNAL_OBJ(obj);
}
/* internal callback to destroy a container. */
@@ -167,10 +167,11 @@
* This is basically used when we want to have a container that is
* a simple linked list.
*/
-static int hash_zero(const void *obj, const int flags)
+static int hash_zero(const void *user_obj, const int flags)
{
return 0;
}
+
/*
* A container is just an object, after all!
*/
@@ -196,7 +197,9 @@
return c;
}
-/* XXX better to keep a global count of elements */
+/*!
+ * return the number of elements in the container
+ */
int astobj2_container_count(struct container *c)
{
return c->elements;
@@ -208,14 +211,14 @@
* XXX this should be private to the container code
*/
struct bucket_list {
- struct bucket_list *next; /* pointer to next bucket_list */
- struct astobj2 *obj; /* pointer to internal data */
+ struct bucket_list *next; /* pointer to next bucket_list */
+ struct astobj2 *astobj; /* pointer to internal data */
};
/*!
* link an object to a container
*/
-void *astobj2_link(struct container *c, void *obj)
+void *astobj2_link(struct container *c, void *user_data)
{
int i;
/* create a new list entry */
@@ -224,13 +227,13 @@
if (p == NULL) /* alloc failure, die */
return NULL;
/* apply the hash function */
- i = c->hash_fn(obj, OBJ_POINTER);
+ i = c->hash_fn(user_data, OBJ_POINTER);
astobj2_lock(c);
i %= c->n_buckets;
p->next = NULL;
- p->obj = INTERNAL_OBJ(obj);
+ p->astobj = INTERNAL_OBJ(user_data);
if (c->buckets[i].head == NULL)
c->buckets[i].head = p;
else
@@ -244,23 +247,27 @@
/*
* another convenience function is a callback that matches on address
*/
-static int match_by_addr(void *obj, void *arg, int flags)
-{
- return (obj == arg) ? CMP_MATCH | CMP_STOP : 0;
+static int match_by_addr(void *user_data, void *arg, int flags)
+{
+ int i = (user_data == arg) ? CMP_MATCH | CMP_STOP : 0;
+ // ast_verbose("match_by_addr u %p arg %p ret %d\n", user_data, arg, i);
+ return i;
}
/*!
- * \brief Unlink an object from the list
+ * \brief Unlink an object from the container
* and destroy the associated * astobj2_bucket_list structure.
*/
-void *astobj2_unlink(struct container *c, void *arg)
-{
- astobj2_callback(c, OBJ_SINGLE | OBJ_UNLINK | OBJ_POINTER, match_by_addr, arg);
+void *astobj2_unlink(struct container *c, void *user_data)
+{
+ // ast_verbose("unlinking %p from container\n", user_data);
+ astobj2_callback(c, OBJ_SINGLE | OBJ_UNLINK | OBJ_POINTER, match_by_addr, user_data);
+ astobj2_ref(user_data, -1);
return NULL;
}
/* special callback that matches all */
-static int cb_true(void *obj, void *arg, int flags)
+static int cb_true(void *user_data, void *arg, int flags)
{
return CMP_MATCH;
}
@@ -274,8 +281,8 @@
const enum search_flags flags,
astobj2_callback_fn cb_fn, void *arg)
{
- int i, last;
- struct astobj2 *ret = NULL;
+ int i, last; /* search boundaries */
+ void *ret = NULL;
if ( (flags & (OBJ_SINGLE | OBJ_DATA)) == OBJ_DATA) {
ast_log(LOG_WARNING, "multiple data return not implemented yet");
@@ -298,6 +305,7 @@
else /* don't know, let's scan all buckets */
i = -1; /* XXX this must be fixed later. */
+ // ast_verbose("-- callback flags %x hash at %d\n", flags, i);
/* determine the search boundaries: i..last-1 */
if (i < 0) {
i = 0;
@@ -309,35 +317,41 @@
astobj2_lock(c); /* avoid modifications to the content */
for(; i < last ; i++) {
+ /* scan the list with prev-cur pointers */
struct bucket_list *prev = NULL, *cur = c->buckets[i].head;
+
while (cur) {
- int match = cb_fn(EXTERNAL_OBJ(cur->obj), arg, flags );
+ int match = cb_fn(EXTERNAL_OBJ(cur->astobj), arg, flags) & (CMP_MATCH | CMP_STOP);
/* we found the object, performing operations according flags */
if (match == 0) { /* no match, no stop, continue */
prev = cur;
cur = cur->next;
continue;
- } else if (match == CMP_STOP) { /* we are done */
+ } else if (match == CMP_STOP) { /* no match but stop, we are done */
i = last;
break;
}
- /* we know CMP_MATCH is set here */
- if (flags & OBJ_DATA) /* must return the object, mark the value */
- ret = cur->obj;
+ /* we have a match (CMP_MATCH) here */
+ if (flags & OBJ_DATA) /* if must return the object, record the value */
+ ret = EXTERNAL_OBJ(cur->astobj);
+
if (flags & OBJ_UNLINK) { /* must unlink */
struct bucket_list *x = cur;
+ // ast_verbose("++ unlink u %p at %p\n", EXTERNAL_OBJ(cur->astobj), cur);
if (prev == NULL) /* gone from head */
c->buckets[i].head = cur->next;
else /* gone from the middle */
prev->next = cur->next;
- /* update tail if needed needed */
- if (c->buckets[i].tail == cur)
+ if (c->buckets[i].tail == cur) /* update tail if needed */
c->buckets[i].tail = prev;
- cur = cur->next ;
- free(x);
+ cur = cur->next ; /* prepare for next cycle */
+ free(x); /* free the link record */
ast_atomic_fetchadd_int(&c->elements, -1);
+ } else { /* prepare for next cycle */
+ prev = cur;
+ cur = cur->next;
}
if ((match & CMP_STOP) || (flags & OBJ_SINGLE)) {
@@ -348,41 +362,29 @@
if (flags & OBJ_DATA) {
#if 0 /* XXX to be completed */
/* here build a list of object pointers and increase
- * the reference counter for each reference created */
- struct astobj2_list *new_obj;
- new_obj = ast_calloc(1, sizeof(struct astobj2_list));
- if ( new_obj == NULL ) {
- ast_log(LOG_WARNING, "No list created, out of memory\n");
- continue;
- }
- astobj2_ref(EXTERNAL_OBJ(list_pointer->obj), 1);
- new_obj->next = (struct astobj2_list *)ret;
- ret = new_obj;
+ * the reference counter for each reference created
+ */
#endif
}
- prev = cur;
- cur = cur->next;
}
}
astobj2_unlock(c);
/* increase the reference counter, unlock the container and return */
- if ( ret != NULL ) {
+ if ( ret != NULL )
astobj2_ref(ret, 1);
- ret = (void *)EXTERNAL_OBJ(ret);
- }
return ret;
}
/*!
* the find function just invokes the default callback with some reasonable flags.
*/
-void *astobj2_find(struct container *c, void *p, enum search_flags flags)
+void *astobj2_find(struct container *c, void *arg, enum search_flags flags)
{
if (flags == 0)
flags = OBJ_SINGLE | OBJ_DATA; /* reasonable default */
ast_log(LOG_NOTICE, "astobj2_find\n");
- return astobj2_callback(c, flags, c->cmp_fn, p);
+ return astobj2_callback(c, flags, c->cmp_fn, arg);
}
/*!
@@ -429,7 +431,7 @@
if (a->pos == -1) { /* found at the beginning of the bucket */
a->pos = 0;
- a->cur = p->obj;
+ a->cur = p->astobj;
break;
}
@@ -439,7 +441,7 @@
* The next element to return will be cand->next.
*/
for (i = 0; p; i++, p = p->next) {
- if (p->obj == a->cur) { /* found current element */
+ if (p->astobj == a->cur) { /* found current element */
a->pos = i; /* mark new position */
cand = p;
break;
@@ -451,7 +453,7 @@
continue;
/* ok, what we want is at cand->next */
a->pos++;
- a->cur = cand->next->obj;
+ a->cur = cand->next->astobj;
break;
}
@@ -528,25 +530,25 @@
sprintf(obj, "-- this is obj %d --", i);
astobj2_link(c1, obj);
}
- ast_cli(fd, "testing callbacks");
- astobj2_callback(c1, 0, print_cb, (void*)fd);
-
- ast_cli(fd, "testing iterators, remove every second object");
+ ast_cli(fd, "testing callbacks\n");
+ astobj2_callback(c1, 0, print_cb, (void *)fd);
+
+ ast_cli(fd, "testing iterators, remove every second object\n");
astobj2_iterator_init(c1, &ai);
{
int x = 0;
while ( (obj = astobj2_iterator_next(&ai)) ) {
- ast_cli(fd, "iterator on <%s>", obj);
+ ast_cli(fd, "iterator on <%s>\n", obj);
if (x++ & 1) {
astobj2_unlink(c1, obj);
- astobj2_ref(obj, -1);
}
}
}
- ast_cli(fd, "testing callbacks again");
+ ast_cli(fd, "testing callbacks again\n");
astobj2_callback(c1, 0, print_cb, (void*)fd);
- astobj2_ref(c1, -1); /* destroy all */
+ ast_cli(fd, "destroy container\n");
+ astobj2_ref(c1, -1); /* destroy container */
return 0;
}
More information about the asterisk-commits
mailing list