BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 7a0d3efda0953d2296a36652babef51441b5ef20 / object / list.c

// Related

Nucleus

Barry Doubly-linked object lists and copying 7a0d3ef (3 years, 3 months ago)
diff --git a/object/list.c b/object/list.c
index 3e9b96b..8581330 100644
--- a/object/list.c
+++ b/object/list.c
@@ -11,7 +11,7 @@
 
 /* Structure for a List Entry */
 struct ListEntry {
-	struct ListEntry *next;
+	struct ListEntry *prev, *next;
 	Object *obj;
 };
 /* Structure for an Object List */
@@ -58,6 +58,7 @@ add(ObjectList *list, void *addr)
 		list->start = entry;
 	else
 		list->end->next = entry;
+	entry->prev = list->end;
 	list->end = entry;
 	entry->obj = get(obj);
 	list->entries++;
@@ -75,30 +76,32 @@ remove(ObjectList *list, void *addr)
 		return;
 	acquire(&list->lock);
 
-	/* Start of list */
-	struct ListEntry *entry, *prev = NULL;
-	if (list->start->obj == obj) {
-		entry = list->start;
-		list->start = entry->next;
-		goto found;
+	/* Search for object */
+	struct ListEntry *entry;
+	for (entry = list->start;
+	     entry && entry->obj != obj;
+	     entry = entry->next);
+	if (!entry) {
+		release(&list->lock);
+		return;
 	}
 
-	/* Search for object */
-	for (prev = list->start; prev->next; prev = prev->next)
-		if (prev->next->obj == obj)
-			break;
-	if (!prev->next)
-		goto end;
-	entry = prev->next;
-	prev->next = entry->next;
-
-found:
-	if (list->end->obj == obj)
-		list->end = prev;
+	/* Unlink list */
+	if (list->start == entry)
+		list->start = entry->next;
+	if (list->end == entry)
+		list->end == entry->prev;
+
+	/* Unlink neighbours */
+	if (entry->prev)
+		entry->prev->next = entry->next;
+	if (entry->next)
+		entry->next->prev = entry->prev;
+
+	/* Release resources */
 	put(obj);
 	list->entries--;
 	kfree(entry);
-end:
 	release(&list->lock);
 }
 
@@ -137,7 +140,7 @@ count(ObjectList *list)
 
 /* Iterate a List with a callback */
 void
-iterate(ObjectList *list, callback_t callback, void *data)
+iterate(ObjectList *list, iterate_callback_t callback, void *data)
 {
 	acquire(&list->lock);
 	struct ListEntry *entry;
@@ -146,3 +149,16 @@ iterate(ObjectList *list, callback_t callback, void *data)
 			break;
 	release(&list->lock);
 }
+
+/* Copy list */
+ObjectList *
+copy_list(ObjectList *list)
+{
+	ObjectList *newlist = create_list(list->type);
+	acquire(&list->lock);
+	struct ListEntry *entry;
+	for (entry = list->start; entry; entry = entry->next)
+		add(newlist, entry->obj);
+	release(&list->lock);
+	return newlist;
+}