CMakeLists.txt: bump minimum cmake version
[project/ubus.git] / libubus-io.c
index 3561ac462eb960fbbd828d9100d0656f101131cb..d190b67795eef5ebf96dc58df5366cb2e88f5352 100644 (file)
@@ -314,12 +314,20 @@ void __hidden ubus_handle_data(struct uloop_fd *u, unsigned int events)
        struct ubus_context *ctx = container_of(u, struct ubus_context, sock);
        int recv_fd = -1;
 
-       while (get_next_msg(ctx, &recv_fd)) {
+       while (1) {
+               if (!ctx->stack_depth)
+                       ctx->pending_timer.cb(&ctx->pending_timer);
+
+               if (!get_next_msg(ctx, &recv_fd))
+                       break;
                ubus_process_msg(ctx, &ctx->msgbuf, recv_fd);
                if (uloop_cancelling() || ctx->cancel_poll)
                        break;
        }
 
+       if (!ctx->stack_depth)
+               ctx->pending_timer.cb(&ctx->pending_timer);
+
        if (u->eof)
                ctx->connection_lost(ctx);
 }
@@ -336,6 +344,29 @@ void __hidden ubus_poll_data(struct ubus_context *ctx, int timeout)
        ubus_handle_data(&ctx->sock, ULOOP_READ);
 }
 
+static void
+ubus_auto_sub_lookup(struct ubus_context *ctx, struct ubus_object_data *obj,
+                    void *priv)
+{
+       struct ubus_subscriber *s;
+
+       list_for_each_entry(s, &ctx->auto_subscribers, list)
+               if (s->new_obj_cb(ctx, s, obj->path))
+                       ubus_subscribe(ctx, s, obj->id);
+}
+
+static void
+ubus_refresh_auto_subscribe(struct ubus_context *ctx)
+{
+       struct ubus_event_handler *ev = &ctx->auto_subscribe_event_handler;
+
+       if (list_empty(&ctx->auto_subscribers))
+               return;
+
+       ubus_register_event_handler(ctx, ev, "ubus.object.add");
+       ubus_lookup(ctx, NULL, ubus_auto_sub_lookup, NULL);
+}
+
 static void
 ubus_refresh_state(struct ubus_context *ctx)
 {
@@ -357,6 +388,8 @@ ubus_refresh_state(struct ubus_context *ctx)
 
        for (n = i, i = 0; i < n; i++)
                ubus_add_object(ctx, objs[i]);
+
+       ubus_refresh_auto_subscribe(ctx);
 }
 
 int ubus_reconnect(struct ubus_context *ctx, const char *path)