aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorMarkus Armbruster <armbru@redhat.com>2014-05-07 09:53:54 +0200
committerLuiz Capitulino <lcapitulino@redhat.com>2014-05-15 14:00:46 -0400
commit297a3646c2947ee64a6d42ca264039732c6218e0 (patch)
tree8ddd334c8e8b42d4972bca08fd57bb79a068cc33 /hw
parentcdaec3808e756fee3c4e17d0168ec6429eff0dbc (diff)
qapi: Replace uncommon use of the error API by the common one
We commonly use the error API like this: err = NULL; foo(..., &err); if (err) { goto out; } bar(..., &err); Every error source is checked separately. The second function is only called when the first one succeeds. Both functions are free to pass their argument to error_set(). Because error_set() asserts no error has been set, this effectively means they must not be called with an error set. The qapi-generated code uses the error API differently: // *errp was initialized to NULL somewhere up the call chain frob(..., errp); gnat(..., errp); Errors accumulate in *errp: first error wins, subsequent errors get dropped. To make this work, the second function does nothing when called with an error set. Requires non-null errp, or else the second function can't see the first one fail. This usage has also bled into visitor tests, and two device model object property getters rtc_get_date() and balloon_stats_get_all(). With the "accumulate" technique, you need fewer error checks in callers, and buy that with an error check in every callee. Can be nice. However, mixing the two techniques is confusing. You can't use the "accumulate" technique with functions designed for the "check separately" technique. You can use the "check separately" technique with functions designed for the "accumulate" technique, but then error_set() can't catch you setting an error more than once. Standardize on the "check separately" technique for now, because it's overwhelmingly prevalent. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/timer/mc146818rtc.c24
-rw-r--r--hw/virtio/virtio-balloon.c12
2 files changed, 30 insertions, 6 deletions
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 6c3e3b6d75..df54546562 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -804,13 +804,33 @@ static void rtc_get_date(Object *obj, Visitor *v, void *opaque,
goto out;
}
visit_type_int32(v, &current_tm.tm_year, "tm_year", &err);
+ if (err) {
+ goto out_end;
+ }
visit_type_int32(v, &current_tm.tm_mon, "tm_mon", &err);
+ if (err) {
+ goto out_end;
+ }
visit_type_int32(v, &current_tm.tm_mday, "tm_mday", &err);
+ if (err) {
+ goto out_end;
+ }
visit_type_int32(v, &current_tm.tm_hour, "tm_hour", &err);
+ if (err) {
+ goto out_end;
+ }
visit_type_int32(v, &current_tm.tm_min, "tm_min", &err);
+ if (err) {
+ goto out_end;
+ }
visit_type_int32(v, &current_tm.tm_sec, "tm_sec", &err);
- visit_end_struct(v, &err);
-
+ if (err) {
+ goto out_end;
+ }
+out_end:
+ error_propagate(errp, err);
+ err = NULL;
+ visit_end_struct(v, errp);
out:
error_propagate(errp, err);
}
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index ca99bd5f97..bf2b588b24 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -121,23 +121,27 @@ static void balloon_stats_get_all(Object *obj, struct Visitor *v,
if (err) {
goto out;
}
-
visit_type_int(v, &s->stats_last_update, "last-update", &err);
+ if (err) {
+ goto out_end;
+ }
visit_start_struct(v, NULL, NULL, "stats", 0, &err);
if (err) {
goto out_end;
}
-
- for (i = 0; i < VIRTIO_BALLOON_S_NR; i++) {
+ for (i = 0; !err && i < VIRTIO_BALLOON_S_NR; i++) {
visit_type_int64(v, (int64_t *) &s->stats[i], balloon_stat_names[i],
&err);
}
+ error_propagate(errp, err);
+ err = NULL;
visit_end_struct(v, &err);
out_end:
+ error_propagate(errp, err);
+ err = NULL;
visit_end_struct(v, &err);
-
out:
error_propagate(errp, err);
}