From: Achilles Benetopoulos <abenetopoulos@gmail.com>
To: Eric Blake <eblake@redhat.com>, qemu-devel@nongnu.org
Cc: pbonzini@redhat.com, quintela@redhat.com, armbru@redhat.com,
crosthwaite.peter@gmail.com
Subject: Re: [Qemu-devel] [PATCH v3] qemu/thread: Add support for error reporting in qemu_thread_create
Date: Wed, 22 Mar 2017 21:01:48 +0200 [thread overview]
Message-ID: <dfda7306-0003-7e3c-f596-9f04586b6b8c@gmail.com> (raw)
In-Reply-To: <7cfc0f3b-2cd3-32b7-0274-90b2bcfc2efa@redhat.com>
Thank you for the detailed review. The indentation errors mentioned
were pure carelesness on my part, sorry about that.
On 3/22/17 2:20 PM, Eric Blake wrote:
>> @@ -342,13 +343,19 @@ static void pci_edu_realize(PCIDevice *pdev, Error **errp) >> { >> EduState *edu = DO_UPCAST(EduState, pdev, pdev); >> uint8_t *pci_conf = pdev->config; >> + Error *local_err = NULL; >> >> timer_init_ms(&edu->dma_timer, QEMU_CLOCK_VIRTUAL, edu_dma_timer, edu); >> >> qemu_mutex_init(&edu->thr_mutex); >> qemu_cond_init(&edu->thr_cond); >> qemu_thread_create(&edu->thread, "edu", edu_fact_thread, >> - edu, QEMU_THREAD_JOINABLE); >> + edu, QEMU_THREAD_JOINABLE, &local_err); >> + >> + if (local_err) { >> + error_propagate(errp, local_err); >> + return; >> + } > > Looking at code like this, I wonder if it would be easier to make > qemu_thread_create() return a value, rather than being void. Then you > could write: > > if (qemu_thread_create(..., errp) < 0) { > return; > } > > instead of having to futz around with local_err and error_propagate(). >
I don't know about it being easier, but it does seem like it would
make the code at the call site cleaner, when the function calling
qemu_thread_create was passed an error variable itself. However, in
all but four cases there is no preexisting error variable, so the code
would stay pretty much the same.
>> +++ b/hw/usb/ccid-card-emulated.c >> @@ -34,6 +34,7 @@ >> >> #include "qemu/thread.h" >> #include "sysemu/char.h" >> +#include "qapi/error.h" >> #include "ccid.h" >> >> #define DPRINTF(card, lvl, fmt, ...) \ >> @@ -485,6 +486,7 @@ static int emulated_initfn(CCIDCardState *base) >> EmulatedState *card = EMULATED_CCID_CARD(base); >> VCardEmulError ret; >> const EnumTable *ptable; >> + Error *err = NULL, *local_err = NULL; > > Huh? Why do you need two local error objects? One is generally sufficient. > >> >> QSIMPLEQ_INIT(&card->event_list); >> QSIMPLEQ_INIT(&card->guest_apdu_list); >> @@ -541,9 +543,17 @@ static int emulated_initfn(CCIDCardState *base) >> return -1; >> } >> qemu_thread_create(&card->event_thread_id, "ccid/event", event_thread, >> - card, QEMU_THREAD_JOINABLE); >> + card, QEMU_THREAD_JOINABLE, &err); >> + >> qemu_thread_create(&card->apdu_thread_id, "ccid/apdu", handle_apdu_thread, >>
- card, QEMU_THREAD_JOINABLE); >> + card, QEMU_THREAD_JOINABLE, &local_err); >> + error_propagate(&err, local_err); >> + >> + if (err) { >> + error_report_err(err); >> + return -1; >> + } > > > If you used the return value, you could write: > > if (qemu_thread_create(..., &err) < 0 || > qemu_thread_create(..., &err) < 0) { > error_report_err(err); > return -1; > } > > without needing the second object.
Well, I wrote it this way because of a recommendation in the error.h
header, but yes, if we were to change the return type of
qemu_thread_create, then this would make sense.
>> +++ b/include/qemu/thread.h >> @@ -55,7 +55,7 @@ void qemu_event_destroy(QemuEvent *ev); >> >> void qemu_thread_create(QemuThread *thread, const char *name, >> void *(*start_routine)(void *), >> - void *arg, int mode); >> + void *arg, int mode, Error **errp); > > Hmm, we still haven't made it official recommended practice, but it's a > good idea to use 'git config diff.orderFile /path/to/file' in order to > hoist .h changes to the front of a diff (it makes diffs easier to review > when you see the interface change prior to the clients of the > interface). I wish I had a better URL to point to on the topic, but > didn't want to spend time finding it in the mailing list archives at > this time.
Noted for future submissions.
>> +++ b/migration/ram.c >> @@ -357,6 +357,7 @@ void migrate_compress_threads_join(void) >> void migrate_compress_threads_create(void) >> { >> int i, thread_count; >> + Error *err = NULL, *local_err = NULL; >> >> if (!migrate_use_compression()) { >> return; >> @@ -378,7 +379,16 @@ void migrate_compress_threads_create(void) >> qemu_cond_init(&comp_param[i].cond); >> qemu_thread_create(compress_threads + i, "compress", >> do_data_compress, comp_param + i, >> - QEMU_THREAD_JOINABLE); >> + QEMU_THREAD_JOINABLE, &local_err); >> + >> + if (local_err) { >> + error_propagate(&err, local_err); >> + local_err = NULL; >> + } >> + } >> + >> + if (err) { >> + error_report_err(err); >> } > > Another place that looks weird with two error variables.
I was on the fence about this one. I wrote it this way thinking that
we would want to know the 'first' time the call to qemu_thread_create
failed, but proceed to try and create subsequent threads, which might
also fail. Seeing it now, it might be more reasonable to catch the
first error, report it then return?
>> +++ b/tests/iothread.c >> @@ -69,11 +69,18 @@ void iothread_join(IOThread *iothread) >> IOThread *iothread_new(void) >> { >> IOThread *iothread = g_new0(IOThread, 1); >> + Error *local_err = NULL; >> >> qemu_mutex_init(&iothread->init_done_lock); >> qemu_cond_init(&iothread->init_done_cond); >> qemu_thread_create(&iothread->thread, NULL, iothread_run, >> - iothread, QEMU_THREAD_JOINABLE); >> + iothread, QEMU_THREAD_JOINABLE, &local_err); > > In a test, you can just assert success, by using: > > qemu_thread_create(..., &error_abort); > >> + >> + if (local_err) { >> + error_report_err(local_err); >> + /*what makes sense here as a return value?*/ >> + return NULL; > > Doing that will get rid of this fishy comment. > >> +++ b/tests/rcutorture.c >> @@ -64,6 +64,7 @@ >> #include "qemu/atomic.h" >> #include "qemu/rcu.h" >> #include "qemu/thread.h" >> +#include "qapi/error.h" >> >> long long n_reads = 0LL; >>
long n_updates = 0L; >> @@ -85,12 +86,20 @@ static int n_threads; >> >> static void create_thread(void *(*func)(void *)) >> { >> + Error *local_err = NULL; >> + >> if (n_threads >= NR_THREADS) { >> fprintf(stderr, "Thread limit of %d exceeded!\n", NR_THREADS); >> exit(-1); >> } >> qemu_thread_create(&threads[n_threads], "test", func, &data[n_threads], >> - QEMU_THREAD_JOINABLE); >> + QEMU_THREAD_JOINABLE, &local_err); >> + >> + if (local_err) { >> + error_report_err(local_err); >> + exit(1); > > Again, in a test, if you're just going to exit anyway, then it's easier > to pass &error_abort to the original call, than it is to post-process > and report the error. >
OK, I will change the code in the tests.
Achilles
prev parent reply other threads:[~2017-03-22 19:01 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-21 21:00 [Qemu-devel] [PATCH v3] qemu/thread: Add support for error reporting in qemu_thread_create Achilles Benetopoulos
2017-03-21 21:22 ` no-reply
2017-03-22 12:20 ` Eric Blake
2017-03-22 19:01 ` Achilles Benetopoulos [this message]
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=dfda7306-0003-7e3c-f596-9f04586b6b8c@gmail.com \
--to=abenetopoulos@gmail.com \
--cc=armbru@redhat.com \
--cc=crosthwaite.peter@gmail.com \
--cc=eblake@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.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).