From ee4af9b55cb4591e63c596af592abc33a8a8f315 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Tue, 20 Feb 2024 17:30:38 +0100 Subject: vm: rework object iteration Ensure that deleting object keys during iteration is safe by keeping a global chain of per-object iterators which are advanced to the next key when the entry that is about to be iterated is deleted. Signed-off-by: Jo-Philipp Wich --- include/ucode/types.h | 10 ++++++++++ include/ucode/util.h | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'include') diff --git a/include/ucode/types.h b/include/ucode/types.h index 7fcc7f1..c0ccd38 100644 --- a/include/ucode/types.h +++ b/include/ucode/types.h @@ -207,6 +207,16 @@ typedef struct { uc_declare_vector(uc_resource_types_t, uc_resource_type_t *); +/* Object iteration */ + +extern uc_list_t uc_object_iterators; + +typedef struct { + uc_list_t list; + struct lh_entry *pos; +} uc_object_iterator_t; + + /* Program structure definitions */ uc_declare_vector(uc_sources_t, uc_source_t *); diff --git a/include/ucode/util.h b/include/ucode/util.h index 52303cc..a3692d5 100644 --- a/include/ucode/util.h +++ b/include/ucode/util.h @@ -79,6 +79,32 @@ } while(0) +/* linked lists */ + +typedef struct uc_list { + struct uc_list *prev; + struct uc_list *next; +} uc_list_t; + +static inline void uc_list_insert(uc_list_t *list, uc_list_t *item) +{ + list->next->prev = item; + item->next = list->next; + item->prev = list; + list->next = item; +} + +static inline void uc_list_remove(uc_list_t *item) +{ + item->next->prev = item->prev; + item->prev->next = item->next; + item->prev = item->next = item; +} + +#define uc_list_foreach(item, list) \ + for (uc_list_t *item = (list)->next; item != (list); item = item->next) + + /* "failsafe" utility functions */ static inline void *xcalloc(size_t size, size_t nmemb) { -- cgit v1.2.3