On Thu, 08/06 15:36, Paolo Bonzini wrote: > +QemuLockCnt usage > +----------------- > + > +The typical pattern for QemuLockCnt functions is as follows. > + > + qemu_lockcnt_inc(&xyz_lockcnt); > + if (xyz) { > + ... access xyz ... > + } > + > + if (qemu_lockcnt_dec_and_lock(&xyz_lockcnt)) { > + g_free(xyz); > + xyz = NULL; > + qemu_lockcnt_unlock(&xyz_lockcnt); > + } > + > +Modifications are done using qemu_lockcnt_lock and qemu_lockcnt_unlock: > + > + qemu_lockcnt_lock(&xyz_lockcnt); > + xyz = g_malloc(xyz); > + qemu_lockcnt_unlock(&xyz_lockcnt); > + > +If an object has to be freed outside a visit, you can use the following > +scheme: > + > + qemu_lockcnt_lock(&xyz_lockcnt); > + if (!qemu_lockcnt_count(&xyz_lockcnt)) { > + g_free(xyz); > + xyz = NULL; > + } > + qemu_lockcnt_unlock(&xyz_lockcnt); > + > +In both the first and the third code snippets, g_free is only executed > +if count is zero. qemu_lockcnt_inc prevents the count from becoming > +non-zero while the object is being freed. > + > + > +QemuLockCnt can also be used to access a list as follows: > + > + qemu_lockcnt_inc(&io_handlers_lockcnt); > + QLIST_FOREACH_RCU(ioh, &io_handlers, pioh) { > + if (ioh->revents & G_IO_OUT) { > + ioh->fd_write(ioh->opaque); > + } > + }
I'm confused, the comment of QLIST_FOREACH_RCU says "list traversal must occur within an RCU critical section.", but there is not rcu_read_lock here. Why? Fam > + > + if (qemu_lockcnt_dec_and_lock(&io_handlers_lockcnt)) { > + QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) { > + if (ioh->deleted) { > + QLIST_REMOVE(ioh, next); > + g_free(ioh); > + } > + } > + qemu_lockcnt_unlock(&io_handlers_lockcnt); > + } > + > +An alternative pattern uses qemu_lockcnt_dec_if_lock: > + > + qemu_lockcnt_inc(&io_handlers_lockcnt); > + QLIST_FOREACH_SAFE_RCU(ioh, &io_handlers, next, pioh) { > + if (ioh->deleted && qemu_lockcnt_dec_if_lock(&io_handlers_lockcnt)) { > + QLIST_REMOVE(ioh, next); > + g_free(ioh); > + qemu_lockcnt_inc_and_unlock(&io_handlers_lockcnt); > + continue; > + } > + > + if (ioh->revents & G_IO_OUT) { > + ioh->fd_write(ioh->opaque); > + } > + } > + qemu_lockcnt_dec(&io_handlers_lockcnt); > + > +Here you can use qemu_lockcnt_dec because there is no special task > +to do if the count goes from 1 to 0.