summaryrefslogtreecommitdiffstats
path: root/src/commonlib/bsd/include/commonlib/bsd/helpers.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/commonlib/bsd/include/commonlib/bsd/helpers.h')
-rw-r--r--src/commonlib/bsd/include/commonlib/bsd/helpers.h35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/commonlib/bsd/include/commonlib/bsd/helpers.h b/src/commonlib/bsd/include/commonlib/bsd/helpers.h
index 4e6ebeefdd48..376ebaef11cf 100644
--- a/src/commonlib/bsd/include/commonlib/bsd/helpers.h
+++ b/src/commonlib/bsd/include/commonlib/bsd/helpers.h
@@ -88,4 +88,39 @@
/* Calculate size of structure member. */
#define member_size(type, member) (sizeof(((type *)0)->member))
+#define _retry_impl(attempts, condition, expr, ...) \
+({ \
+ __typeof__(condition) _retry_ret = \
+ (__typeof__(condition))0; \
+ int _retry_attempts = (attempts); \
+ do { \
+ _retry_ret = (condition); \
+ if (_retry_ret) \
+ break; \
+ if (--_retry_attempts > 0) { \
+ expr; \
+ } else { \
+ break; \
+ } \
+ } while (1); \
+ _retry_ret; \
+})
+
+/*
+ * Helper macro to retry until a condition becomes true or the maximum number
+ * of attempts is reached. Two forms are supported:
+ *
+ * 1. retry(attempts, condition)
+ * 2. retry(attempts, condition, expr)
+ *
+ * @param attempts Maximum attempts.
+ * @param condition Condition to retry for.
+ * @param expr Procedure to run between each evaluation to "condition".
+ *
+ * @return Condition value if it evaluates to true within the maximum attempts;
+ * 0 otherwise.
+ */
+#define retry(attempts, condition, ...) \
+ _retry_impl(attempts, condition, __VA_ARGS__)
+
#endif /* COMMONLIB_BSD_HELPERS_H */