xref: /aosp_15_r20/external/libwebsockets/READMEs/README.lws_dll.md (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker# lws_dll Doubly-linked list
2*1c60b9acSAndroid Build Coastguard Worker
3*1c60b9acSAndroid Build Coastguard Worker## Introduction
4*1c60b9acSAndroid Build Coastguard Worker
5*1c60b9acSAndroid Build Coastguard WorkerLws supports two kinds of doubly-linked list, `lws_dll` and `lws_dll2`.
6*1c60b9acSAndroid Build Coastguard Worker
7*1c60b9acSAndroid Build Coastguard WorkerUnless memory is at a big premium, or it has to work on lws < v3.2, it's
8*1c60b9acSAndroid Build Coastguard Workerbest to simply use `lws_dll2`.
9*1c60b9acSAndroid Build Coastguard Worker
10*1c60b9acSAndroid Build Coastguard Worker![lws_dll overview](../doc-assets/lws_dll.svg)
11*1c60b9acSAndroid Build Coastguard Worker
12*1c60b9acSAndroid Build Coastguard Worker## How to use
13*1c60b9acSAndroid Build Coastguard Worker
14*1c60b9acSAndroid Build Coastguard WorkerThe basics are the same for lws_dll and lws_dll2.
15*1c60b9acSAndroid Build Coastguard Worker
16*1c60b9acSAndroid Build Coastguard WorkerThe list objects point only to themselves, and you use the `lws_container_of`
17*1c60b9acSAndroid Build Coastguard Workermacro to get a pointer to your struct that contains the list object.  Doing
18*1c60b9acSAndroid Build Coastguard Workerit this way
19*1c60b9acSAndroid Build Coastguard Worker
20*1c60b9acSAndroid Build Coastguard Worker - the list object does not have to be the first thing in your struct
21*1c60b9acSAndroid Build Coastguard Worker
22*1c60b9acSAndroid Build Coastguard Worker - your struct can contain multiple list objects and appear on lists belonging
23*1c60b9acSAndroid Build Coastguard Worker   to multiple owners simultaenously,
24*1c60b9acSAndroid Build Coastguard Worker
25*1c60b9acSAndroid Build Coastguard Worker### lws_dll Minimal example
26*1c60b9acSAndroid Build Coastguard Worker
27*1c60b9acSAndroid Build Coastguard Worker```
28*1c60b9acSAndroid Build Coastguard Workerstruct mystruct {
29*1c60b9acSAndroid Build Coastguard Worker	....
30*1c60b9acSAndroid Build Coastguard Worker	lws_dll list;
31*1c60b9acSAndroid Build Coastguard Worker	...
32*1c60b9acSAndroid Build Coastguard Worker};
33*1c60b9acSAndroid Build Coastguard Worker
34*1c60b9acSAndroid Build Coastguard Workerlws_dll owner;
35*1c60b9acSAndroid Build Coastguard Worker```
36*1c60b9acSAndroid Build Coastguard Worker
37*1c60b9acSAndroid Build Coastguard WorkerAdding a mystruct to the owner list (...add_tail() works the same way but adds
38*1c60b9acSAndroid Build Coastguard Workerto the other end of the list)
39*1c60b9acSAndroid Build Coastguard Worker
40*1c60b9acSAndroid Build Coastguard Worker```
41*1c60b9acSAndroid Build Coastguard Worker	struct mystruct *p;
42*1c60b9acSAndroid Build Coastguard Worker
43*1c60b9acSAndroid Build Coastguard Worker	...
44*1c60b9acSAndroid Build Coastguard Worker
45*1c60b9acSAndroid Build Coastguard Worker	lws_dll_add_head(&p->list, &owner);
46*1c60b9acSAndroid Build Coastguard Worker```
47*1c60b9acSAndroid Build Coastguard Worker
48*1c60b9acSAndroid Build Coastguard WorkerRemoving the list object from its owner
49*1c60b9acSAndroid Build Coastguard Worker
50*1c60b9acSAndroid Build Coastguard Worker```
51*1c60b9acSAndroid Build Coastguard Worker	lws_dll2_remove(&p->list, &owner);
52*1c60b9acSAndroid Build Coastguard Worker```
53*1c60b9acSAndroid Build Coastguard Worker
54*1c60b9acSAndroid Build Coastguard WorkerIf you have a `struct lws_dll *d` pointing to `list` in struct mystruct, you can
55*1c60b9acSAndroid Build Coastguard Workerconvert it to a `struct mystruct *p` ike this
56*1c60b9acSAndroid Build Coastguard Worker
57*1c60b9acSAndroid Build Coastguard Worker```
58*1c60b9acSAndroid Build Coastguard Worker	struct mystruct *p = lws_container_of(d, struct lws_dll, list);
59*1c60b9acSAndroid Build Coastguard Worker```
60*1c60b9acSAndroid Build Coastguard Worker
61*1c60b9acSAndroid Build Coastguard Worker### lws_dll2 Minimal example
62*1c60b9acSAndroid Build Coastguard Worker
63*1c60b9acSAndroid Build Coastguard Worker
64*1c60b9acSAndroid Build Coastguard Worker```
65*1c60b9acSAndroid Build Coastguard Workerstruct mystruct {
66*1c60b9acSAndroid Build Coastguard Worker	....
67*1c60b9acSAndroid Build Coastguard Worker	lws_dll2 list;
68*1c60b9acSAndroid Build Coastguard Worker	...
69*1c60b9acSAndroid Build Coastguard Worker};
70*1c60b9acSAndroid Build Coastguard Worker
71*1c60b9acSAndroid Build Coastguard Workerlws_dll2_owner owner;
72*1c60b9acSAndroid Build Coastguard Worker```
73*1c60b9acSAndroid Build Coastguard Worker
74*1c60b9acSAndroid Build Coastguard WorkerAdding a mystruct to the owner list (...add_tail() works the same way but adds
75*1c60b9acSAndroid Build Coastguard Workerto the other end of the list)
76*1c60b9acSAndroid Build Coastguard Worker
77*1c60b9acSAndroid Build Coastguard Worker```
78*1c60b9acSAndroid Build Coastguard Worker	struct mystruct *p;
79*1c60b9acSAndroid Build Coastguard Worker
80*1c60b9acSAndroid Build Coastguard Worker	...
81*1c60b9acSAndroid Build Coastguard Worker
82*1c60b9acSAndroid Build Coastguard Worker	lws_dll2_add_head(&p->list, &owner);
83*1c60b9acSAndroid Build Coastguard Worker```
84*1c60b9acSAndroid Build Coastguard Worker
85*1c60b9acSAndroid Build Coastguard WorkerRemoving the list object from its owner (notice compared to lws_dll, it doesn't
86*1c60b9acSAndroid Build Coastguard Workerneed to be told the owner)
87*1c60b9acSAndroid Build Coastguard Worker
88*1c60b9acSAndroid Build Coastguard Worker```
89*1c60b9acSAndroid Build Coastguard Worker	lws_dll2_remove(&p->list);
90*1c60b9acSAndroid Build Coastguard Worker```
91*1c60b9acSAndroid Build Coastguard Worker
92*1c60b9acSAndroid Build Coastguard WorkerIf you have a `struct lws_dll2 *d` pointing to `list` in struct mystruct, you
93*1c60b9acSAndroid Build Coastguard Workercan convert it to a `struct mystruct *p` ike this
94*1c60b9acSAndroid Build Coastguard Worker
95*1c60b9acSAndroid Build Coastguard Worker```
96*1c60b9acSAndroid Build Coastguard Worker	struct mystruct *p = lws_container_of(d, struct lws_dll2, list);
97*1c60b9acSAndroid Build Coastguard Worker```
98*1c60b9acSAndroid Build Coastguard Worker
99*1c60b9acSAndroid Build Coastguard Worker## Summary Comparing lws_dll and lws_dll2
100*1c60b9acSAndroid Build Coastguard Worker
101*1c60b9acSAndroid Build Coastguard Worker - both offer a doubly-linked list object, and (since v3.2) track both the
102*1c60b9acSAndroid Build Coastguard Worker   head and tail in an "list owner" object
103*1c60b9acSAndroid Build Coastguard Worker
104*1c60b9acSAndroid Build Coastguard Worker - both are initalized by memsetting to 0
105*1c60b9acSAndroid Build Coastguard Worker
106*1c60b9acSAndroid Build Coastguard Worker - for `lws_dll`, it reuses an `lws_dll` as the "owner", for `lws_dll2`, there's a
107*1c60b9acSAndroid Build Coastguard Worker   specific `lws_dll2_owner` structure for that
108*1c60b9acSAndroid Build Coastguard Worker
109*1c60b9acSAndroid Build Coastguard Worker - `lws_dll2_owner` also keeps count of the number of list elements
110*1c60b9acSAndroid Build Coastguard Worker
111*1c60b9acSAndroid Build Coastguard Worker - `lws_dll2` knows which owner's list it is participating on.  So it can remove
112*1c60b9acSAndroid Build Coastguard Worker   itself and update the owner without the caller needing to know its owner.
113*1c60b9acSAndroid Build Coastguard Worker   In the case there are several potential owners list objects may be on, this
114*1c60b9acSAndroid Build Coastguard Worker   is very convenient.
115*1c60b9acSAndroid Build Coastguard Worker
116*1c60b9acSAndroid Build Coastguard Worker - `lws_dll` is simpler and has a smaller footprint (two pointers per entry vs
117*1c60b9acSAndroid Build Coastguard Worker   three).  But you have to know the exact list owner to perform operations on
118*1c60b9acSAndroid Build Coastguard Worker   it.
119*1c60b9acSAndroid Build Coastguard Worker
120*1c60b9acSAndroid Build Coastguard Worker## apis
121*1c60b9acSAndroid Build Coastguard Worker
122*1c60b9acSAndroid Build Coastguard Worker|function|lws_dll|lws_dll2|
123*1c60b9acSAndroid Build Coastguard Worker|---|---|---|
124*1c60b9acSAndroid Build Coastguard Worker|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*1c60b9acSAndroid Build Coastguard Worker|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*1c60b9acSAndroid Build Coastguard Worker|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*1c60b9acSAndroid Build Coastguard Worker|get owner|(not supported)|`struct lws_dll2_owner * lws_dll2_owner(const struct lws_dll2 *d)`|
128*1c60b9acSAndroid Build Coastguard Worker|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*1c60b9acSAndroid Build Coastguard Worker|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*1c60b9acSAndroid Build Coastguard Worker
131