How to delete elements when traversing the Linux kernel linked list

Source: Internet
Author: User

<! -- @ Page {margin: 2 cm} pre. CJK {font-family: "dejavu sans", monospace} p {margin-bottom: 0.21 cm} A: link {so-language: zxx} -->

The list_head function of the kernel is quite clever. Today, I will explain how to delete elements from the list_head linked list.

The review duration of the linked list. If you delete the current element, errors may occur. This is true for linked lists in various libraries in all languages. The same is true for list_head.

 

<! -- @ Page {margin: 2 cm} p {margin-bottom: 0.21} A: link {so-language: zxx} -->

For example, deleting the current element in Java traversal throws a java. util. concurrentmodificationexception.

See: how to delete multiple elements in a collection in Java http://blog.csdn.net/shendl/archive/2007/12/28/1999907.aspx
Article.

 

 

If you use list_for_each to remove the current element from the chain, the system will crash relentlessly. No prompts are displayed. Therefore, such bugs are very difficult to locate.

 

List_for_each source code:

/** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. */#define list_for_each(pos, head) /        for (pos = (head)->next; prefetch(pos->next), pos != (head); /                pos = pos->next)

 

After the list_del leeching element is removed, the next and Prev values are assigned as follows:

/* * These are non-NULL pointers that will result in page faults * under normal circumstances, used to verify that nobody uses * non-initialized list entries. */#define LIST_POISON1  ((void *) 0x00100100 + POISON_POINTER_DELTA)#define LIST_POISON2  ((void *) 0x00200200 + POISON_POINTER_DELTA

After list_del_init is dechained, both next and Prev are set as their own.

 

Therefore, after deleting the current element in list_for_each, The next element of the linked list cannot be found correctly.

 

To delete the current element when traversing the list_head linked list, you must use the list_for_each_safe function instead of the list_for_each function.

 

List_for_each_safe source code:

/** * list_for_each_safe - iterate over a list safe against removal of list entry * @pos: the &struct list_head to use as a loop cursor. * @n: another &struct list_head to use as temporary storage * @head: the head for your list. */#define list_for_each_safe(pos, n, head) /        for (pos = (head)->next, n = pos->next; pos != (head); /                pos = n, n = pos->next)

This function RatioList_for_eachThe function has one moreNParameters. This parameter is alsoList_headType.

It saves the next element, so that the current element can be safely deleted without any subsequent element being found.

At the end of the loop,PosPointNElement instead of pointingPosOfNextElement. BecausePosAfter leeching,PosElementNextIt may already be a null pointer, or list_python1
This meaningless value.

IfListIs empty, soPos = NIs still equalHeadThe traversal is over!

 ThereforeLisf_for_each_safeFunction TraversalList_headLinked list, you can safely delete the current element.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.