aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/iomgr/error.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lib/iomgr/error.h')
-rw-r--r--src/core/lib/iomgr/error.h41
1 files changed, 37 insertions, 4 deletions
diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h
index 27c4d22fd1..cb740d5b01 100644
--- a/src/core/lib/iomgr/error.h
+++ b/src/core/lib/iomgr/error.h
@@ -120,8 +120,15 @@ typedef enum {
/// polling engines) can safely use the lower bit for themselves.
#define GRPC_ERROR_NONE ((grpc_error*)NULL)
+#define GRPC_ERROR_RESERVED_1 ((grpc_error*)1)
#define GRPC_ERROR_OOM ((grpc_error*)2)
+#define GRPC_ERROR_RESERVED_2 ((grpc_error*)3)
#define GRPC_ERROR_CANCELLED ((grpc_error*)4)
+#define GRPC_ERROR_SPECIAL_MAX GRPC_ERROR_CANCELLED
+
+inline bool grpc_error_is_special(struct grpc_error* err) {
+ return err <= GRPC_ERROR_SPECIAL_MAX;
+}
// debug only toggles that allow for a sanity to check that ensures we will
// never create any errors in the per-RPC hotpath.
@@ -158,19 +165,37 @@ grpc_error* grpc_error_create(const char* file, int line, grpc_slice desc,
errs, count)
#ifndef NDEBUG
-grpc_error* grpc_error_ref(grpc_error* err, const char* file, int line);
-void grpc_error_unref(grpc_error* err, const char* file, int line);
+grpc_error* grpc_error_do_ref(grpc_error* err, const char* file, int line);
+void grpc_error_do_unref(grpc_error* err, const char* file, int line);
+inline grpc_error* grpc_error_ref(grpc_error* err, const char* file, int line) {
+ if (grpc_error_is_special(err)) return err;
+ return grpc_error_do_ref(err, file, line);
+}
+inline void grpc_error_unref(grpc_error* err, const char* file, int line) {
+ if (grpc_error_is_special(err)) return;
+ grpc_error_do_unref(err, file, line);
+}
#define GRPC_ERROR_REF(err) grpc_error_ref(err, __FILE__, __LINE__)
#define GRPC_ERROR_UNREF(err) grpc_error_unref(err, __FILE__, __LINE__)
#else
-grpc_error* grpc_error_ref(grpc_error* err);
-void grpc_error_unref(grpc_error* err);
+grpc_error* grpc_error_do_ref(grpc_error* err);
+void grpc_error_do_unref(grpc_error* err);
+inline grpc_error* grpc_error_ref(grpc_error* err) {
+ if (grpc_error_is_special(err)) return err;
+ return grpc_error_do_ref(err);
+}
+inline void grpc_error_unref(grpc_error* err) {
+ if (grpc_error_is_special(err)) return;
+ grpc_error_do_unref(err);
+}
#define GRPC_ERROR_REF(err) grpc_error_ref(err)
#define GRPC_ERROR_UNREF(err) grpc_error_unref(err)
#endif
grpc_error* grpc_error_set_int(grpc_error* src, grpc_error_ints which,
intptr_t value) GRPC_MUST_USE_RESULT;
+/// It is an error to pass nullptr as `p`. Caller should allocate a dummy
+/// intptr_t for `p`, even if the value of `p` is not used.
bool grpc_error_get_int(grpc_error* error, grpc_error_ints which, intptr_t* p);
/// This call takes ownership of the slice; the error is responsible for
/// eventually unref-ing it.
@@ -185,8 +210,16 @@ bool grpc_error_get_str(grpc_error* error, grpc_error_strs which,
/// error occurring. Allows root causing high level errors from lower level
/// errors that contributed to them. The src error takes ownership of the
/// child error.
+///
+/// Edge Conditions -
+/// 1) If either of \a src or \a child is GRPC_ERROR_NONE, returns a reference
+/// to the other argument. 2) If both \a src and \a child are GRPC_ERROR_NONE,
+/// returns GRPC_ERROR_NONE. 3) If \a src and \a child point to the same error,
+/// returns a single reference. (Note that, 2 references should have been
+/// received to the error in this case.)
grpc_error* grpc_error_add_child(grpc_error* src,
grpc_error* child) GRPC_MUST_USE_RESULT;
+
grpc_error* grpc_os_error(const char* file, int line, int err,
const char* call_name) GRPC_MUST_USE_RESULT;