diff options
author | Jo-Philipp Wich <jo@mein.io> | 2024-02-20 17:30:38 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2024-02-21 11:02:43 +0100 |
commit | ee4af9b55cb4591e63c596af592abc33a8a8f315 (patch) | |
tree | c38739676757c60b8caa0c1f0401022e8aa9b44c /include | |
parent | 3f9811d2f7b730f1f1d030872ae1def7e8349be6 (diff) |
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 <jo@mein.io>
Diffstat (limited to 'include')
-rw-r--r-- | include/ucode/types.h | 10 | ||||
-rw-r--r-- | include/ucode/util.h | 26 |
2 files changed, 36 insertions, 0 deletions
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) { |