qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-block] [Qemu-devel] [PATCH 03/18] qemu-thread: introduce QemuL


From: Fam Zheng
Subject: Re: [Qemu-block] [Qemu-devel] [PATCH 03/18] qemu-thread: introduce QemuLockCnt
Date: Wed, 9 Sep 2015 16:49:47 +0800
User-agent: Mutt/1.5.23 (2014-03-12)

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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]