add functions for internal object allocation
authorFelix Fietkau <nbd@openwrt.org>
Fri, 4 Feb 2011 23:21:27 +0000 (00:21 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Fri, 4 Feb 2011 23:21:27 +0000 (00:21 +0100)
ubusd.c
ubusd_id.c
ubusd_id.h
ubusd_obj.c
ubusmsg.h

diff --git a/ubusd.c b/ubusd.c
index 87b95199e71c314631b6967885c56eb992ef6919..798761dc7b51508463374ecd12f0b99dfbd41de8 100644 (file)
--- a/ubusd.c
+++ b/ubusd.c
@@ -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;
index 9443db9297941b50e80247b905bbf791948c626b..44b509e531083cec743dd6050403242d2d24fb58 100644 (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);
 
index ca69d9a326039dedfe89eb537cbac0821fe8956b..2b4cb6d8669332fe7d51566fc40bdc2f554acfef 100644 (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)
 {
index a702fa6a4df345adbd025e7bb6d7e3cba6daf358..7fc795128a11b373af357bd6448dfb99d61764d5 100644 (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,7 +153,8 @@ void ubusd_free_object(struct ubus_object *obj)
                avl_delete(&path, &obj->path);
                free(obj->path.key);
        }
-       list_del(&obj->list);
+       if (!list_empty(&obj->list))
+               list_del(&obj->list);
        ubus_free_id(&objects, &obj->id);
        ubus_unref_object_type(obj->type);
        free(obj);
index 3e107973312d7fdbed5ce004d49877f94fe91a6a..9da330e5287b749ec7b56f46549ff1572d64a194 100644 (file)
--- a/ubusmsg.h
+++ b/ubusmsg.h
@@ -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;