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; cl->sock.fd = client_fd;
INIT_LIST_HEAD(&cl->objects); INIT_LIST_HEAD(&cl->objects);
if (!ubus_alloc_id(&clients, &cl->id)) if (!ubus_alloc_id(&clients, &cl->id, 0))
goto error; goto error;
cl->sock.cb = client_cb; cl->sock.cb = client_cb;

View file

@ -3,6 +3,7 @@
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include "ubusmsg.h"
#include "ubusd_id.h" #include "ubusd_id.h"
static int random_fd = -1; 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); 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; id->avl.key = &id->id;
if (val) {
id->id = val;
return avl_insert(tree, &id->avl) == 0;
}
do { do {
if (read(random_fd, &id->id, sizeof(id->id)) != sizeof(id->id)) if (read(random_fd, &id->id, sizeof(id->id)) != sizeof(id->id))
return false; return false;
if (!id->id) if (id->id < UBUS_SYSTEM_OBJECT_MAX)
continue; continue;
} while (avl_insert(tree, &id->avl) != 0); } 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); 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) 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 = calloc(1, sizeof(*type));
type->refcount = 1; type->refcount = 1;
if (!ubus_alloc_id(&obj_types, &type->id)) if (!ubus_alloc_id(&obj_types, &type->id, 0))
goto error_free; goto error_free;
INIT_LIST_HEAD(&type->methods); INIT_LIST_HEAD(&type->methods);
@ -85,6 +85,28 @@ static struct ubus_object_type *ubus_get_obj_type(uint32_t obj_id)
return type; 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 *ubusd_create_object(struct ubus_client *cl, struct blob_attr **attr)
{ {
struct ubus_object *obj; struct ubus_object *obj;
@ -98,28 +120,30 @@ struct ubus_object *ubusd_create_object(struct ubus_client *cl, struct blob_attr
if (!type) if (!type)
return NULL; return NULL;
obj = calloc(1, sizeof(*obj)); obj = ubusd_create_object_internal(type, 0);
if (!ubus_alloc_id(&objects, &obj->id)) ubus_unref_object_type(type);
goto error_free;
if (!obj)
return NULL;
if (attr[UBUS_ATTR_OBJPATH]) { if (attr[UBUS_ATTR_OBJPATH]) {
obj->path.key = strdup(blob_data(attr[UBUS_ATTR_OBJPATH])); obj->path.key = strdup(blob_data(attr[UBUS_ATTR_OBJPATH]));
if (avl_insert(&path, &obj->path) != 0) if (!obj->path.key)
goto error_del_id; 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; obj->client = cl;
list_add(&obj->list, &cl->objects); list_add(&obj->list, &cl->objects);
return obj; return obj;
error_del_id: free:
free(obj->path.key); ubusd_free_object(obj);
ubus_free_id(&objects, &obj->id);
error_free:
ubus_unref_object_type(type);
free(obj);
return NULL; return NULL;
} }
@ -129,7 +153,8 @@ void ubusd_free_object(struct ubus_object *obj)
avl_delete(&path, &obj->path); avl_delete(&path, &obj->path);
free(obj->path.key); free(obj->path.key);
} }
list_del(&obj->list); if (!list_empty(&obj->list))
list_del(&obj->list);
ubus_free_id(&objects, &obj->id); ubus_free_id(&objects, &obj->id);
ubus_unref_object_type(obj->type); ubus_unref_object_type(obj->type);
free(obj); free(obj);

View file

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