mirror of
https://github.com/openvswitch/ovs
synced 2025-09-01 06:45:17 +00:00
rculist: use multi-variable helpers for loop macros.
Use multi-variable iteration helpers to rewrite rculist loops macros. There is an important behavior change compared with the previous implementation: When the loop ends normally (i.e: not via "break;"), the object pointer provided by the user is NULL. This is safer because it's not guaranteed that it would end up pointing a valid address. Acked-by: Eelco Chaudron <echaudro@redhat.com> Acked-by: Dumitru Ceara <dceara@redhat.com> Signed-off-by: Adrian Moreno <amorenoz@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
committed by
Ilya Maximets
parent
745c80f52c
commit
d293965d7b
@@ -366,34 +366,56 @@ rculist_is_singleton_protected(const struct rculist *list)
|
||||
}
|
||||
|
||||
#define RCULIST_FOR_EACH(ITER, MEMBER, RCULIST) \
|
||||
for (INIT_CONTAINER(ITER, rculist_next(RCULIST), MEMBER); \
|
||||
&(ITER)->MEMBER != (RCULIST); \
|
||||
ASSIGN_CONTAINER(ITER, rculist_next(&(ITER)->MEMBER), MEMBER))
|
||||
for (INIT_MULTIVAR(ITER, MEMBER, rculist_next(RCULIST), \
|
||||
const struct rculist); \
|
||||
CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \
|
||||
UPDATE_MULTIVAR(ITER, rculist_next(ITER_VAR(ITER))))
|
||||
|
||||
#define RCULIST_FOR_EACH_CONTINUE(ITER, MEMBER, RCULIST) \
|
||||
for (ASSIGN_CONTAINER(ITER, rculist_next(&(ITER)->MEMBER), MEMBER); \
|
||||
&(ITER)->MEMBER != (RCULIST); \
|
||||
ASSIGN_CONTAINER(ITER, rculist_next(&(ITER)->MEMBER), MEMBER))
|
||||
for (INIT_MULTIVAR(ITER, MEMBER, rculist_next(&(ITER)->MEMBER), \
|
||||
const struct rculist); \
|
||||
CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \
|
||||
UPDATE_MULTIVAR(ITER, rculist_next(ITER_VAR(ITER))))
|
||||
|
||||
#define RCULIST_FOR_EACH_REVERSE_PROTECTED(ITER, MEMBER, RCULIST) \
|
||||
for (INIT_CONTAINER(ITER, (RCULIST)->prev, MEMBER); \
|
||||
&(ITER)->MEMBER != (RCULIST); \
|
||||
ASSIGN_CONTAINER(ITER, (ITER)->MEMBER.prev, MEMBER))
|
||||
for (INIT_MULTIVAR(ITER, MEMBER, (RCULIST)->prev, struct rculist); \
|
||||
CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \
|
||||
UPDATE_MULTIVAR(ITER, ITER_VAR(VAR).prev))
|
||||
|
||||
#define RCULIST_FOR_EACH_REVERSE_PROTECTED_CONTINUE(ITER, MEMBER, RCULIST) \
|
||||
for (ASSIGN_CONTAINER(ITER, (ITER)->MEMBER.prev, MEMBER); \
|
||||
&(ITER)->MEMBER != (RCULIST); \
|
||||
ASSIGN_CONTAINER(ITER, (ITER)->MEMBER.prev, MEMBER))
|
||||
for (INIT_MULTIVAR(ITER, MEMBER, (ITER)->MEMBER.prev, struct rculist); \
|
||||
CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \
|
||||
UPDATE_MULTIVAR(ITER, ITER_VAR(VAR).prev))
|
||||
|
||||
#define RCULIST_FOR_EACH_PROTECTED(ITER, MEMBER, RCULIST) \
|
||||
for (INIT_CONTAINER(ITER, rculist_next_protected(RCULIST), MEMBER); \
|
||||
&(ITER)->MEMBER != (RCULIST); \
|
||||
ASSIGN_CONTAINER(ITER, rculist_next_protected(&(ITER)->MEMBER), \
|
||||
MEMBER))
|
||||
for (INIT_MULTIVAR(ITER, MEMBER, rculist_next_protected(RCULIST), \
|
||||
struct rculist); \
|
||||
CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \
|
||||
UPDATE_MULTIVAR(ITER, rculist_next_protected(ITER_VAR(ITER))) \
|
||||
|
||||
#define RCULIST_FOR_EACH_SAFE_SHORT_PROTECTED(ITER, MEMBER, RCULIST) \
|
||||
for (INIT_MULTIVAR_SAFE_SHORT(ITER, MEMBER, \
|
||||
rculist_next_protected(RCULIST), \
|
||||
struct rculist); \
|
||||
CONDITION_MULTIVAR_SAFE_SHORT(ITER, MEMBER, \
|
||||
ITER_VAR(ITER) != (RCULIST), \
|
||||
ITER_NEXT_VAR(ITER) = rculist_next_protected(ITER_VAR(VAR))); \
|
||||
UPDATE_MULTIVAR_SHORT(ITER))
|
||||
|
||||
#define RCULIST_FOR_EACH_SAFE_LONG_PROTECTED(ITER, NEXT, MEMBER, RCULIST) \
|
||||
for (INIT_MULTIVAR_SAFE_LONG(ITER, NEXT, MEMBER, \
|
||||
rculist_next_protected(RCULIST) \
|
||||
struct rculist); \
|
||||
CONDITION_MULTIVAR_SAFE_LONG(VAR, NEXT, MEMBER \
|
||||
ITER_VAR(ITER) != (RCULIST), \
|
||||
ITER_VAR(NEXT) = rculist_next_protected(ITER_VAR(VAR)), \
|
||||
ITER_VAR(NEXT) != (RCULIST)); \
|
||||
UPDATE_MULTIVAR_LONG(ITER))
|
||||
|
||||
#define RCULIST_FOR_EACH_SAFE_PROTECTED(...) \
|
||||
OVERLOAD_SAFE_MACRO(RCULIST_FOR_EACH_SAFE_LONG_PROTECTED, \
|
||||
RCULIST_FOR_EACH_SAFE_SHORT_PROTECTED, \
|
||||
4, __VA_ARGS__)
|
||||
|
||||
#define RCULIST_FOR_EACH_SAFE_PROTECTED(ITER, NEXT, MEMBER, RCULIST) \
|
||||
for (INIT_CONTAINER(ITER, rculist_next_protected(RCULIST), MEMBER); \
|
||||
(&(ITER)->MEMBER != (RCULIST) \
|
||||
? INIT_CONTAINER(NEXT, rculist_next_protected(&(ITER)->MEMBER), \
|
||||
MEMBER), 1 : 0); \
|
||||
(ITER) = (NEXT))
|
||||
|
||||
#endif /* rculist.h */
|
||||
|
Reference in New Issue
Block a user