• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# lws_dll Doubly-linked list
2
3## Introduction
4
5Lws supports two kinds of doubly-linked list, `lws_dll` and `lws_dll2`.
6
7Unless memory is at a big premium, or it has to work on lws < v3.2, it's
8best to simply use `lws_dll2`.
9
10![lws_dll overview](../doc-assets/lws_dll.svg)
11
12## How to use
13
14The basics are the same for lws_dll and lws_dll2.
15
16The list objects point only to themselves, and you use the `lws_container_of`
17macro to get a pointer to your struct that contains the list object.  Doing
18it this way
19
20 - the list object does not have to be the first thing in your struct
21
22 - your struct can contain multiple list objects and appear on lists belonging
23   to multiple owners simultaenously,
24
25### lws_dll Minimal example
26
27```
28struct mystruct {
29	....
30	lws_dll list;
31	...
32};
33
34lws_dll owner;
35```
36
37Adding a mystruct to the owner list (...add_tail() works the same way but adds
38to the other end of the list)
39
40```
41	struct mystruct *p;
42
43	...
44
45	lws_dll_add_head(&p->list, &owner);
46```
47
48Removing the list object from its owner
49
50```
51	lws_dll2_remove(&p->list, &owner);
52```
53
54If you have a `struct lws_dll *d` pointing to `list` in struct mystruct, you can
55convert it to a `struct mystruct *p` ike this
56
57```
58	struct mystruct *p = lws_container_of(d, struct lws_dll, list);
59```
60
61### lws_dll2 Minimal example
62
63
64```
65struct mystruct {
66	....
67	lws_dll2 list;
68	...
69};
70
71lws_dll2_owner owner;
72```
73
74Adding a mystruct to the owner list (...add_tail() works the same way but adds
75to the other end of the list)
76
77```
78	struct mystruct *p;
79
80	...
81
82	lws_dll2_add_head(&p->list, &owner);
83```
84
85Removing the list object from its owner (notice compared to lws_dll, it doesn't
86need to be told the owner)
87
88```
89	lws_dll2_remove(&p->list);
90```
91
92If you have a `struct lws_dll2 *d` pointing to `list` in struct mystruct, you
93can convert it to a `struct mystruct *p` ike this
94
95```
96	struct mystruct *p = lws_container_of(d, struct lws_dll2, list);
97```
98
99## Summary Comparing lws_dll and lws_dll2
100
101 - both offer a doubly-linked list object, and (since v3.2) track both the
102   head and tail in an "list owner" object
103
104 - both are initalized by memsetting to 0
105
106 - for `lws_dll`, it reuses an `lws_dll` as the "owner", for `lws_dll2`, there's a
107   specific `lws_dll2_owner` structure for that
108
109 - `lws_dll2_owner` also keeps count of the number of list elements
110
111 - `lws_dll2` knows which owner's list it is participating on.  So it can remove
112   itself and update the owner without the caller needing to know its owner.
113   In the case there are several potential owners list objects may be on, this
114   is very convenient.
115
116 - `lws_dll` is simpler and has a smaller footprint (two pointers per entry vs
117   three).  But you have to know the exact list owner to perform operations on
118   it.
119
120## apis
121
122|function|lws_dll|lws_dll2|
123|---|---|---|
124|add entry at head|`void lws_dll_add_head(struct lws_dll *d, struct lws_dll *phead)`|`void lws_dll2_add_head(struct lws_dll2 *d, struct lws_dll2_owner *owner)`|
125|add entry at tail|`void lws_dll_add_tail(struct lws_dll *d, struct lws_dll *phead);`|`void lws_dll2_add_tail(struct lws_dll2 *d, struct lws_dll2_owner *owner)`|
126|remove entry from its owning list|`void lws_dll_remove_track_tail(struct lws_dll *d, struct lws_dll *phead)`|`void lws_dll2_add_tail(struct lws_dll2 *d, struct lws_dll2_owner *owner)`|
127|get owner|(not supported)|`struct lws_dll2_owner * lws_dll2_owner(const struct lws_dll2 *d)`|
128|check if item is detached from any list|`lws_dll_is_detached(struct lws_dll *d, struct lws_dll *phead)|int lws_dll2_is_detached(const struct lws_dll2 *d)`|
129|iterate through items on list|`int lws_dll_foreach_safe(struct lws_dll *phead, void *user, int (*cb)(struct lws_dll *d, void *user))|int lws_dll2_foreach_safe(struct lws_dll2_owner *owner, void *user, int (*cb)(struct lws_dll2 *d, void *user))`|
130
131