diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2024-11-28 13:21:13 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2024-12-10 18:49:24 +0100 |
commit | 4cc055039fc1c1ab18f172fa791aa3d48d7d20aa (patch) | |
tree | c5cad55830eeb50a00bc8927194394977d80af9f /hw/core | |
parent | a3057c52f45c280bffc22980f535799a12500d66 (diff) | |
download | qemu-4cc055039fc1c1ab18f172fa791aa3d48d7d20aa.zip qemu-4cc055039fc1c1ab18f172fa791aa3d48d7d20aa.tar.gz qemu-4cc055039fc1c1ab18f172fa791aa3d48d7d20aa.tar.bz2 |
clock: clear callback on unparent
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/core')
-rw-r--r-- | hw/core/clock.c | 22 | ||||
-rw-r--r-- | hw/core/qdev-clock.c | 5 |
2 files changed, 18 insertions, 9 deletions
diff --git a/hw/core/clock.c b/hw/core/clock.c index cbe7b1b..391095e 100644 --- a/hw/core/clock.c +++ b/hw/core/clock.c @@ -44,16 +44,12 @@ Clock *clock_new(Object *parent, const char *name) void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque, unsigned int events) { + assert(OBJECT(clk)->parent); clk->callback = cb; clk->callback_opaque = opaque; clk->callback_events = events; } -void clock_clear_callback(Clock *clk) -{ - clock_set_callback(clk, NULL, NULL, 0); -} - bool clock_set(Clock *clk, uint64_t period) { if (clk->period == period) { @@ -168,6 +164,16 @@ static void clock_period_prop_get(Object *obj, Visitor *v, const char *name, visit_type_uint64(v, name, &period, errp); } +static void clock_unparent(Object *obj) +{ + /* + * Callback are registered by the parent, which might die anytime after + * it's unparented the children. Avoid having a callback to a deleted + * object in case the clock is still referenced somewhere else (eg: by + * a clock output). + */ + clock_set_callback(CLOCK(obj), NULL, NULL, 0); +} static void clock_initfn(Object *obj) { @@ -200,11 +206,17 @@ static void clock_finalizefn(Object *obj) g_free(clk->canonical_path); } +static void clock_class_init(ObjectClass *klass, void *data) +{ + klass->unparent = clock_unparent; +} + static const TypeInfo clock_info = { .name = TYPE_CLOCK, .parent = TYPE_OBJECT, .instance_size = sizeof(Clock), .instance_init = clock_initfn, + .class_init = clock_class_init, .instance_finalize = clock_finalizefn, }; diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c index 8279957..ca65685 100644 --- a/hw/core/qdev-clock.c +++ b/hw/core/qdev-clock.c @@ -87,11 +87,8 @@ void qdev_finalize_clocklist(DeviceState *dev) if (!ncl->output && !ncl->alias) { /* * We kept a reference on the input clock to ensure it lives up to - * this point so we can safely remove the callback. - * It avoids having a callback to a deleted object if ncl->clock - * is still referenced somewhere else (eg: by a clock output). + * this point; it is used by the monitor to show the frequency. */ - clock_clear_callback(ncl->clock); object_unref(OBJECT(ncl->clock)); } g_free(ncl->name); |