diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 88d5af05ae7b..bd9b74d8eae4 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8309,7 +8309,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, TaskState *ts = cpu->opaque; object_property_set_bool(OBJECT(cpu), "realized", false, NULL); - object_unref(OBJECT(cpu)); + object_unparent(OBJECT(cpu)); + /* * At this point the CPU should be unrealized and removed * from cpu lists. We can clean-up the rest of the thread @@ -8323,6 +8324,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, do_sys_futex(g2h(cpu, ts->child_tidptr), FUTEX_WAKE, INT_MAX, NULL, NULL, 0); } + + object_unref(OBJECT(cpu)); thread_cpu = NULL; g_free(ts); rcu_unregister_thread(); diff --git a/qom/object.c b/qom/object.c index 6a01d5654696..9f532f5497ac 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1179,10 +1179,10 @@ void object_unref(void *objptr) if (!obj) { return; } - g_assert(obj->ref > 0); + g_assert(qatomic_mb_read(&obj->ref) > 0); /* parent always holds a reference to its children */ - if (qatomic_fetch_dec(&obj->ref) == 1) { + if (qatomic_dec_fetch(&obj->ref) == 0) { object_finalize(obj); } }