summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2024-02-20 17:30:38 +0100
committerJo-Philipp Wich <jo@mein.io>2024-02-21 11:02:43 +0100
commitee4af9b55cb4591e63c596af592abc33a8a8f315 (patch)
treec38739676757c60b8caa0c1f0401022e8aa9b44c /include
parent3f9811d2f7b730f1f1d030872ae1def7e8349be6 (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.h10
-rw-r--r--include/ucode/util.h26
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) {