qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@redhat.com>
To: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>, Fam Zheng <fam@euphon.net>,
	Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
	qemu-block@nongnu.org, Wen Congyang <wencongyang2@huawei.com>,
	Xie Changlong <xiechanglong.d@gmail.com>,
	Markus Armbruster <armbru@redhat.com>,
	qemu-devel@nongnu.org, Hanna Reitz <hreitz@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>, John Snow <jsnow@redhat.com>
Subject: Re: [RFC PATCH v2 03/14] job.h: define locked functions
Date: Thu, 16 Dec 2021 16:48:39 +0000	[thread overview]
Message-ID: <Ybtt591Fe+PgDCFm@stefanha-x1.localdomain> (raw)
In-Reply-To: <20211104145334.1346363-4-eesposit@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 2491 bytes --]

On Thu, Nov 04, 2021 at 10:53:23AM -0400, Emanuele Giuseppe Esposito wrote:
>  /** Returns whether the job is ready to be completed. */
>  bool job_is_ready(Job *job);
>  
> +/** Same as job_is_ready(), but assumes job_lock is held. */
> +bool job_is_ready_locked(Job *job);

What I see here is that some functions assume job_lock is held but don't
have _locked in their name (job_ref()), some assume job_lock is held and
have _locked in their name (job_is_ready_locked()), and some assume
job_lock is not held (job_is_ready()).

That means when _locked is not in the name I don't know whether this
function requires job_lock or will deadlock if called under job_lock.

Two ways to it obvious:

1. Always have _locked in the name if the function requires job_lock.
   Functions without _locked must not be called under job_lock.

2. Don't change the name but use the type system instead:

   /*
    * Define a unique type so the compiler warns us. It's just a pointer
    * so it can be efficiently passed by value.
    */
   typedef struct { Job *job; } LockedJob;

   LockedJob job_lock(Job *job);
   Job *job_unlock(LockedJob job);

   Now the compiler catches mistakes:

   bool job_is_completed(LockedJob job);
   bool job_is_ready(Job *job);

   Job *j;
   LockedJob l;
   job_is_completed(j) -> compiler error
   job_is_completed(l) -> ok
   job_is_ready(j) -> ok
   job_is_ready(l) -> compiler error

   This approach assumes per-Job locks but a similar API is possible
   with a global job_mutex too. There just needs to be a function to
   turn Job * into LockedJob and LockedJob back into Job*.

   This is slightly exotic. It's not an approach I've seen used in C, so
   it's not idiomatic and people might find it unfamiliar.

These are just ideas. If you want to keep it the way it is, that's okay
too (although a little confusing).

> diff --git a/job.c b/job.c
> index 0e4dacf028..e393c1222f 100644
> --- a/job.c
> +++ b/job.c
> @@ -242,7 +242,8 @@ bool job_cancel_requested(Job *job)
>      return job->cancelled;
>  }
>  
> -bool job_is_ready(Job *job)
> +/* Called with job_mutex held. */

This information should go with the doc comments (and it's already there
in job.h!). There is no rule on where to put doc comments but in this
case you already added them to job.h, so they are not needed here in
job.c. Leaving them could confuse other people into adding doc comments
into job.c instead of job.h.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

  reply	other threads:[~2021-12-16 16:50 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-04 14:53 [RFC PATCH v2 00/14] job: replace AioContext lock with job_mutex Emanuele Giuseppe Esposito
2021-11-04 14:53 ` [RFC PATCH v2 01/14] job.c: make job_lock/unlock public Emanuele Giuseppe Esposito
2021-12-16 16:18   ` Stefan Hajnoczi
2021-11-04 14:53 ` [RFC PATCH v2 02/14] job.h: categorize fields in struct Job Emanuele Giuseppe Esposito
2021-12-16 16:21   ` Stefan Hajnoczi
2021-12-21 14:23     ` Emanuele Giuseppe Esposito
2021-11-04 14:53 ` [RFC PATCH v2 03/14] job.h: define locked functions Emanuele Giuseppe Esposito
2021-12-16 16:48   ` Stefan Hajnoczi [this message]
2021-12-16 17:11     ` Vladimir Sementsov-Ogievskiy
2021-12-20 10:15       ` Emanuele Giuseppe Esposito
2021-11-04 14:53 ` [RFC PATCH v2 04/14] job.h: define unlocked functions Emanuele Giuseppe Esposito
2021-12-16 16:51   ` Stefan Hajnoczi
2021-11-04 14:53 ` [RFC PATCH v2 05/14] block/mirror.c: use of job helpers in drivers to avoid TOC/TOU Emanuele Giuseppe Esposito
2021-12-18 11:53   ` Vladimir Sementsov-Ogievskiy
2021-12-20 10:34     ` Emanuele Giuseppe Esposito
2021-12-20 10:47       ` Vladimir Sementsov-Ogievskiy
2021-12-23 11:37         ` Emanuele Giuseppe Esposito
2021-11-04 14:53 ` [RFC PATCH v2 06/14] job.c: make job_event_* functions static Emanuele Giuseppe Esposito
2021-12-16 16:54   ` Stefan Hajnoczi
2021-11-04 14:53 ` [RFC PATCH v2 07/14] job.c: move inner aiocontext lock in callbacks Emanuele Giuseppe Esposito
2021-11-04 14:53 ` [RFC PATCH v2 08/14] aio-wait.h: introduce AIO_WAIT_WHILE_UNLOCKED Emanuele Giuseppe Esposito
2021-11-04 14:53 ` [RFC PATCH v2 09/14] jobs: remove aiocontext locks since the functions are under BQL Emanuele Giuseppe Esposito
2021-11-04 14:53 ` [RFC PATCH v2 10/14] jobs: protect jobs with job_lock/unlock Emanuele Giuseppe Esposito
2021-12-18 11:57   ` Vladimir Sementsov-Ogievskiy
2021-11-04 14:53 ` [RFC PATCH v2 11/14] block_job_query: remove atomic read Emanuele Giuseppe Esposito
2021-12-18 12:07   ` Vladimir Sementsov-Ogievskiy
2021-12-23 11:37     ` Emanuele Giuseppe Esposito
2021-11-04 14:53 ` [RFC PATCH v2 12/14] jobs: use job locks and helpers also in the unit tests Emanuele Giuseppe Esposito
2021-11-04 14:53 ` [RFC PATCH v2 13/14] jobs: add job lock in find_* functions Emanuele Giuseppe Esposito
2021-12-18 12:11   ` Vladimir Sementsov-Ogievskiy
2021-12-18 12:22     ` Vladimir Sementsov-Ogievskiy
2021-11-04 14:53 ` [RFC PATCH v2 14/14] job.c: enable job lock/unlock and remove Aiocontext locks Emanuele Giuseppe Esposito
2021-12-18 12:24   ` Vladimir Sementsov-Ogievskiy
2021-12-23 14:59     ` Emanuele Giuseppe Esposito

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Ybtt591Fe+PgDCFm@stefanha-x1.localdomain \
    --to=stefanha@redhat.com \
    --cc=armbru@redhat.com \
    --cc=eesposit@redhat.com \
    --cc=fam@euphon.net \
    --cc=hreitz@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.com \
    --cc=wencongyang2@huawei.com \
    --cc=xiechanglong.d@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).