[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC 12/15] error: Make IGNORED_ERRORS not a NULL pointer
From: |
Eduardo Habkost |
Subject: |
[Qemu-devel] [RFC 12/15] error: Make IGNORED_ERRORS not a NULL pointer |
Date: |
Tue, 13 Jun 2017 13:53:10 -0300 |
Use a trick to make we have a non-NULL errp if IGNORED_ERRORS is used:
instead of passing NULL, pass an existing pointer that points to a
special &error_ignored_unset value. This will let the error API to flag
error state on *errp but won't require error_free() to be called later.
This will allow us to simplify the documented method to propagate errors
from:
Error *err = NULL;
foo(arg, &err);
if (err) {
handle the error...
error_propagate(errp, err);
}
to:
foo(arg, errp);
if (ERR_IS_SET(errp)) {
handle the error...
}
This will allow us to stop using local_err variables and
error_propagate() on hundreds of cases.
* TODO: API documentation needs to be updated.
* TODO: probably we should add assert(errp) lines to the ERR_IS_* macros,
as err_set*() will now break if errp is NULL.
Signed-off-by: Eduardo Habkost <address@hidden>
---
include/qapi/error.h | 20 +++++++++++++++++---
tests/test-qapi-util.c | 14 +++++++-------
util/error.c | 13 ++++++++++++-
3 files changed, 36 insertions(+), 11 deletions(-)
diff --git a/include/qapi/error.h b/include/qapi/error.h
index 1000853051..d1378396dd 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -117,10 +117,24 @@
#include "qapi-types.h"
-#define IGNORE_ERRORS (NULL)
-#define ERR_IS_SET(e) (!!*(e))
-#define ERR_IS_IGNORED(e) (!(e))
+/*
+ * Special error value to indicate errors will be ignored, and no
+ * error was set.
+ */
+extern Error ignored_error_unset;
+
+/*
+ * Special error destination to indicate errors will be ignored,
+ * but an error value was set.
+ */
+extern Error ignored_error_set;
+
+
+#define IGNORE_ERRORS (& (Error *) { &ignored_error_unset })
+
+#define ERR_IS_SET(e) (*(e) && *(e) != &ignored_error_unset)
+#define ERR_IS_IGNORED(e) (!(e) || *(e) == &ignored_error_unset || *(e) ==
&ignored_error_set)
/*
* Overall category of an error.
diff --git a/tests/test-qapi-util.c b/tests/test-qapi-util.c
index fe232ef9ed..0305b9201b 100644
--- a/tests/test-qapi-util.c
+++ b/tests/test-qapi-util.c
@@ -77,25 +77,25 @@ static void test_parse_qapi_name(void)
static void successfn(Error **errp)
{
- g_assert(ERR_IS_IGNORED(errp) || !ERR_IS_SET(errp));
+ g_assert(!ERR_IS_SET(errp));
}
static void fail1(Error **errp)
{
- g_assert(ERR_IS_IGNORED(errp) || !ERR_IS_SET(errp));
+ g_assert(!ERR_IS_SET(errp));
error_setg(errp, "error1");
- g_assert(ERR_IS_IGNORED(errp) || ERR_IS_SET(errp));
+ g_assert(ERR_IS_SET(errp));
}
static void fail2(Error **errp)
{
- g_assert(ERR_IS_IGNORED(errp) || !ERR_IS_SET(errp));
+ g_assert(!ERR_IS_SET(errp));
error_setg(errp, "error2");
- g_assert(ERR_IS_IGNORED(errp) || ERR_IS_SET(errp));
+ g_assert(ERR_IS_SET(errp));
}
static void multifn(Error **errp)
@@ -124,13 +124,13 @@ static void test_propagate(void (*fn)(Error **), Error
**errp)
bool failed;
Error *local_err = NULL;
- g_assert(ERR_IS_IGNORED(errp) || !ERR_IS_SET(errp));
+ g_assert(!ERR_IS_SET(errp));
fn(&local_err);
failed = !!local_err;
error_propagate(errp, local_err);
- g_assert(ERR_IS_IGNORED(errp) || (failed == !!ERR_IS_SET(errp)));
+ g_assert((failed == !!ERR_IS_SET(errp)));
}
static void test_error_api(void)
diff --git a/util/error.c b/util/error.c
index 4e804287eb..2e16ad371c 100644
--- a/util/error.c
+++ b/util/error.c
@@ -28,6 +28,8 @@ struct Error
Error *error_abort;
Error *error_fatal;
+Error ignored_error_unset;
+Error ignored_error_set;
static void error_handle_fatal(Error **errp, Error *err)
{
@@ -52,6 +54,7 @@ static void error_setv(Error **errp,
int saved_errno = errno;
if (ERR_IS_IGNORED(errp)) {
+ *errp = &ignored_error_set;
return;
}
assert(!ERR_IS_SET(errp));
@@ -104,6 +107,7 @@ void error_setg_errno_internal(Error **errp,
int saved_errno = errno;
if (ERR_IS_IGNORED(errp)) {
+ *errp = &ignored_error_set;
return;
}
@@ -127,6 +131,8 @@ void error_vprepend(Error **errp, const char *fmt, va_list
ap)
{
GString *newmsg;
+ assert(ERR_IS_SET(errp));
+
if (ERR_IS_IGNORED(errp)) {
return;
}
@@ -153,6 +159,8 @@ void error_append_hint(Error **errp, const char *fmt, ...)
int saved_errno = errno;
Error *err;
+ assert(ERR_IS_SET(errp));
+
if (ERR_IS_IGNORED(errp)) {
return;
}
@@ -179,6 +187,7 @@ void error_setg_win32_internal(Error **errp,
char *suffix = NULL;
if (ERR_IS_IGNORED(errp)) {
+ *errp = &ignored_error_set;
return;
}
@@ -266,7 +275,9 @@ void error_propagate(Error **dst_errp, Error *local_err)
return;
}
error_handle_fatal(dst_errp, local_err);
- if (!ERR_IS_IGNORED(dst_errp) && !ERR_IS_SET(dst_errp)) {
+ if (ERR_IS_IGNORED(dst_errp)) {
+ *dst_errp = &ignored_error_set;
+ } else if (!ERR_IS_SET(dst_errp)) {
*dst_errp = local_err;
} else {
error_free(local_err);
--
2.11.0.259.g40922b1
- [Qemu-devel] [RFC 02/15] error: New IGNORE_ERRORS macro, (continued)
- [Qemu-devel] [RFC 02/15] error: New IGNORE_ERRORS macro, Eduardo Habkost, 2017/06/13
- [Qemu-devel] [RFC 01/15] tests: Test cases for error API, Eduardo Habkost, 2017/06/13
- [Qemu-devel] [RFC 03/15] Add qapi/error.h includes on files that will need it, Eduardo Habkost, 2017/06/13
- [Qemu-devel] [RFC 05/15] qapi: Use IGNORE_ERRORS instead of NULL on generated code, Eduardo Habkost, 2017/06/13
- [Qemu-devel] [RFC 06/15] test-qapi-util: Use IGNORE_ERRORS instead of NULL, Eduardo Habkost, 2017/06/13
- [Qemu-devel] [RFC 08/15] error: New ERR_IS_* macros for checking Error** values, Eduardo Habkost, 2017/06/13
- [Qemu-devel] [RFC 07/15] Manual changes to use IGNORE_ERRORS instead of NULL, Eduardo Habkost, 2017/06/13
- [Qemu-devel] [RFC 10/15] test-qapi-util: Use ERR_IS_* macros, Eduardo Habkost, 2017/06/13
- [Qemu-devel] [RFC 11/15] Manual changes to use ERR_IS_* macros, Eduardo Habkost, 2017/06/13
- [Qemu-devel] [RFC 09/15] [coccinelle] Use ERR_IS_* macros, Eduardo Habkost, 2017/06/13
- [Qemu-devel] [RFC 12/15] error: Make IGNORED_ERRORS not a NULL pointer,
Eduardo Habkost <=
- [Qemu-devel] [RFC 13/15] rdma: Simplify var declaration to avoid confusing Coccinelle, Eduardo Habkost, 2017/06/13
- [Qemu-devel] [RFC 04/15] [coccinelle] Use IGNORE_ERRORS instead of NULL as errp argument, Eduardo Habkost, 2017/06/13
- [Qemu-devel] [RFC 14/15] [coccinelle] Eliminate unnecessary local_err/error_propagate() usage, Eduardo Habkost, 2017/06/13
- [Qemu-devel] [RFC 15/15] [test only] Use 'Error *err[static 1]' instead of 'Error **errp' to catch NULL errp arguments, Eduardo Habkost, 2017/06/13
- Message not available
- Re: [Qemu-devel] [RFC 15/15] [test only] Use 'Error *err[static 1]' instead of 'Error **errp' to catch NULL errp arguments, Eduardo Habkost, 2017/06/17
- Re: [Qemu-devel] [RFC 15/15] [test only] Use 'Error *err[static 1]' instead of 'Error **errp' to catch NULL errp arguments, Dr. David Alan Gilbert, 2017/06/19
- Re: [Qemu-devel] [RFC 15/15] [test only] Use 'Error *err[static 1]' instead of 'Error **errp' to catch NULL errp arguments, Peter Maydell, 2017/06/19
- Re: [Qemu-devel] [RFC 15/15] [test only] Use 'Error *err[static 1]' instead of 'Error **errp' to catch NULL errp arguments, Eduardo Habkost, 2017/06/19
- Re: [Qemu-devel] [RFC 15/15] [test only] Use 'Error *err[static 1]' instead of 'Error **errp' to catch NULL errp arguments, Eric Blake, 2017/06/27
- Re: [Qemu-devel] [RFC 15/15] [test only] Use 'Error *err[static 1]' instead of 'Error **errp' to catch NULL errp arguments, Eduardo Habkost, 2017/06/27