add functions for internal object allocation

This commit is contained in:
Felix Fietkau 2011-02-05 00:21:27 +01:00
parent ba6082bab5
commit d80ebf55af
5 changed files with 53 additions and 19 deletions

View file

@ -258,7 +258,7 @@ static bool get_next_connection(int fd)
cl->sock.fd = client_fd;
INIT_LIST_HEAD(&cl->objects);
if (!ubus_alloc_id(&clients, &cl->id))
if (!ubus_alloc_id(&clients, &cl->id, 0))
goto error;
cl->sock.cb = client_cb;

View file

@ -3,6 +3,7 @@
#include <unistd.h>
#include <fcntl.h>
#include "ubusmsg.h"
#include "ubusd_id.h"
static int random_fd = -1;
@ -30,14 +31,19 @@ void ubus_init_id_tree(struct avl_tree *tree)
avl_init(tree, ubus_cmp_id, false, NULL);
}
bool ubus_alloc_id(struct avl_tree *tree, struct ubus_id *id)
bool ubus_alloc_id(struct avl_tree *tree, struct ubus_id *id, uint32_t val)
{
id->avl.key = &id->id;
if (val) {
id->id = val;
return avl_insert(tree, &id->avl) == 0;
}
do {
if (read(random_fd, &id->id, sizeof(id->id)) != sizeof(id->id))
return false;
if (!id->id)
if (id->id < UBUS_SYSTEM_OBJECT_MAX)
continue;
} while (avl_insert(tree, &id->avl) != 0);

View file

@ -10,7 +10,7 @@ struct ubus_id {
};
void ubus_init_id_tree(struct avl_tree *tree);
bool ubus_alloc_id(struct avl_tree *tree, struct ubus_id *id);
bool ubus_alloc_id(struct avl_tree *tree, struct ubus_id *id, uint32_t val);
static inline void ubus_free_id(struct avl_tree *tree, struct ubus_id *id)
{

View file

@ -47,7 +47,7 @@ static struct ubus_object_type *ubus_create_obj_type(struct blob_attr *sig)
type = calloc(1, sizeof(*type));
type->refcount = 1;
if (!ubus_alloc_id(&obj_types, &type->id))
if (!ubus_alloc_id(&obj_types, &type->id, 0))
goto error_free;
INIT_LIST_HEAD(&type->methods);
@ -85,6 +85,28 @@ static struct ubus_object_type *ubus_get_obj_type(uint32_t obj_id)
return type;
}
struct ubus_object *ubusd_create_object_internal(struct ubus_object_type *type, uint32_t id)
{
struct ubus_object *obj;
obj = calloc(1, sizeof(*obj));
if (!obj)
return NULL;
if (!ubus_alloc_id(&objects, &obj->id, id))
goto error_free;
obj->type = type;
INIT_LIST_HEAD(&obj->list);
type->refcount++;
return obj;
error_free:
free(obj);
return NULL;
}
struct ubus_object *ubusd_create_object(struct ubus_client *cl, struct blob_attr **attr)
{
struct ubus_object *obj;
@ -98,28 +120,30 @@ struct ubus_object *ubusd_create_object(struct ubus_client *cl, struct blob_attr
if (!type)
return NULL;
obj = calloc(1, sizeof(*obj));
if (!ubus_alloc_id(&objects, &obj->id))
goto error_free;
obj = ubusd_create_object_internal(type, 0);
ubus_unref_object_type(type);
if (!obj)
return NULL;
if (attr[UBUS_ATTR_OBJPATH]) {
obj->path.key = strdup(blob_data(attr[UBUS_ATTR_OBJPATH]));
if (avl_insert(&path, &obj->path) != 0)
goto error_del_id;
if (!obj->path.key)
goto free;
if (avl_insert(&path, &obj->path) != 0) {
free(obj->path.key);
obj->path.key = NULL;
goto free;
}
}
obj->type = type;
obj->client = cl;
list_add(&obj->list, &cl->objects);
return obj;
error_del_id:
free(obj->path.key);
ubus_free_id(&objects, &obj->id);
error_free:
ubus_unref_object_type(type);
free(obj);
free:
ubusd_free_object(obj);
return NULL;
}
@ -129,6 +153,7 @@ void ubusd_free_object(struct ubus_object *obj)
avl_delete(&path, &obj->path);
free(obj->path.key);
}
if (!list_empty(&obj->list))
list_del(&obj->list);
ubus_free_id(&objects, &obj->id);
ubus_unref_object_type(obj->type);

View file

@ -8,6 +8,9 @@
#define UBUS_MAX_MSGLEN 65535
#define UBUS_SYSTEM_OBJECT_EVENT 1
#define UBUS_SYSTEM_OBJECT_MAX 1024
struct ubus_msghdr {
uint8_t version;
uint8_t type;