diff options
Diffstat (limited to 'src/core/lib/iomgr/error.h')
-rw-r--r-- | src/core/lib/iomgr/error.h | 41 |
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; |