- /* Find first entry with higher timeout value */
- while (*head && NL_WHEN(*head) <= NL_WHEN(entry))
- head = &(*head)->next;
- nlist_insert(head, entry);
+ notify_list *spot = *head, /* Insertion location */
+ /* ...Start at head */
+ *back = NULL; /* Back pointer */
+
+
+ /* Find first entry with higher timeout value or end of list */
+ while (spot && NL_WHEN(spot) <= NL_WHEN(entry)) {
+ /*
+ * Keep the back pointer in case we
+ * run off the end... (see below)
+ */
+ back = spot;
+ spot = spot->next;
+ }
+
+ if (spot == (*head)) {
+ /*
+ * case where we're prepending an empty or non-empty
+ * list or inserting in the middle somewhere. Pass
+ * the real head of the list, since we'll be changing
+ * during the insert...
+ */
+ nlist_insert(head, entry);
+ } else {
+ /* all other cases - don't move the real head pointer */
+ nlist_insert(&spot, entry);
+
+ /*
+ * If spot == entry, then spot was NULL when we called
+ * nlist_insert. This happened because we had run off
+ * the end of the list. Append entry to original list.
+ */
+ if (spot == entry) {
+ back->next = entry;
+ entry->prev = back;
+ }
+ }