libubus: fix deadlock in recursive synchronous ubus requests
authorFelix Fietkau <nbd@openwrt.org>
Sat, 11 May 2013 18:39:54 +0000 (20:39 +0200)
committerFelix Fietkau <nbd@openwrt.org>
Sat, 11 May 2013 18:39:54 +0000 (20:39 +0200)
When synchronous request completion loops are running, the innermost
loop can receive events that can unblock the outer loops, however the
loop clears uloop_cancelled (which is set by the request completion).

This causes the event loop to continue running even while a completion
loop has already been unblocked.

Fix this by not clearing uloop_cancelled for inner loops

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
libubus-req.c

index f02af8e..2f2dce1 100644 (file)
@@ -157,6 +157,8 @@ int ubus_complete_request(struct ubus_context *ctx, struct ubus_request *req,
                uloop_cancelled = cancelled;
        }
        ctx->stack_depth--;
                uloop_cancelled = cancelled;
        }
        ctx->stack_depth--;
+       if (ctx->stack_depth)
+               uloop_cancelled = true;
 
        if (timeout)
                uloop_timeout_cancel(&cb.timeout);
 
        if (timeout)
                uloop_timeout_cancel(&cb.timeout);