]> git.sur5r.net Git - ngadmin/blob - lib/src/list.c
bc48e1e781a591d5eaa4d68f0506616c1b703f77
[ngadmin] / lib / src / list.c
1
2 #include "list.h"
3
4
5
6
7 // -------------------------
8 List* createEmptyList (void) {
9  
10  List *l;
11  
12  
13  l=malloc(sizeof(List));
14  l->first=NULL;
15  l->last=NULL;
16  l->count=0;
17  pthread_cond_init(&l->cond, NULL);
18  pthread_mutex_init(&l->mutex, NULL);
19  
20  
21  return l;
22  
23 }
24
25
26
27 // ------------------------------------------------
28 void destroyList (List *l, void (*freefunc)(void*)) {
29  
30  ListNode *pr, *ln;
31  
32  
33  
34  if ( l==NULL ) {
35   return;
36  }
37  
38  
39  pthread_mutex_destroy(&l->mutex);
40  pthread_cond_destroy(&l->cond);
41  
42  for (ln=l->first; ln!=NULL; ) {
43   
44   pr=ln;
45   
46   if ( freefunc!=NULL ) {
47    freefunc(pr->data);
48   }
49   
50   ln=pr->next;
51   free(pr);
52   
53  }
54  
55  
56  free(l);
57  
58 }
59
60
61
62 // -------------------------------------
63 void pushFrontList (List *l, void* data) {
64  
65  ListNode *ln;
66  
67  
68  if ( l==NULL ) {
69   return;
70  }
71  
72  
73  pthread_mutex_lock(&l->mutex);
74  
75  ln=malloc(sizeof(ListNode));
76  ln->data=data;
77  ln->prev=NULL;
78  ln->next=l->first;
79  
80  if ( l->first==NULL ) {
81   l->last=ln;
82  } else {
83   l->first->prev=ln;
84  }
85  
86  l->first=ln;
87  l->count++;
88  
89  pthread_mutex_unlock(&l->mutex);
90  pthread_cond_broadcast(&l->cond);
91  
92 }
93
94
95
96 // ------------------------------------
97 void pushBackList (List *l, void* data) {
98  
99  ListNode *ln;
100  
101  
102  if ( l==NULL ) {
103   return;
104  }
105  
106  
107  pthread_mutex_lock(&l->mutex);
108  
109  ln=malloc(sizeof(ListNode));
110  ln->data=data;
111  ln->prev=l->last;
112  ln->next=NULL;
113  
114  if ( l->last==NULL ) {
115   l->first=ln;
116  } else {
117   l->last->next=ln;
118  }
119  
120  l->last=ln;
121  l->count++;
122  
123  pthread_mutex_unlock(&l->mutex);
124  pthread_cond_broadcast(&l->cond);
125  
126 }
127
128
129
130 // -------------------------
131 void* popFrontList (List *l) {
132  
133  ListNode *ln;
134  void* data;
135  
136  
137  if ( l==NULL ) {
138   return NULL;
139  }
140  
141  
142  pthread_mutex_lock(&l->mutex);
143  
144  if ( (ln=l->first)==NULL ) {
145   pthread_mutex_unlock(&l->mutex);
146   return NULL;
147  }
148  
149  data=ln->data;
150  l->first=ln->next;
151  
152  if ( ln->next==NULL ) {
153   l->last=NULL;
154  } else {
155   ln->next->prev=NULL;
156  }
157  
158  l->count--;
159  free(ln);
160  
161  pthread_mutex_unlock(&l->mutex);
162  pthread_cond_broadcast(&l->cond);
163  
164  
165  return data;
166  
167 }
168
169
170
171 // ------------------------
172 void* popBackList (List *l) {
173  
174  ListNode *ln;
175  void* data;
176  
177  
178  
179  if ( l==NULL ) {
180   return NULL;
181  }
182  
183  
184  pthread_mutex_lock(&l->mutex);
185  
186  if ( (ln=l->last)==NULL ) {
187   pthread_mutex_unlock(&l->mutex);
188   return NULL;
189  }
190  
191  data=ln->data;
192  l->last=ln->prev;
193  
194  if ( ln->prev==NULL ) {
195   l->first=NULL;
196  } else {
197   ln->prev->next=NULL;
198  }
199  
200  l->count--;
201  free(ln);
202  
203  pthread_mutex_unlock(&l->mutex);
204  pthread_cond_broadcast(&l->cond);
205  
206  
207  
208  return data;
209  
210 }
211
212
213
214 // ----------------------------------------------
215 void clearList (List *l, void (*freefunc)(void*)) {
216  
217  ListNode *ln, *pr;
218  
219  
220  if ( l==NULL ) {
221   return;
222  }
223  
224  
225  pthread_mutex_lock(&l->mutex);
226  
227  for (ln=l->first; ln!=NULL; ) {
228   
229   pr=ln;
230   
231   if ( freefunc!=NULL ) {
232    freefunc(pr->data);
233   }
234   
235   ln=pr->next;
236   free(pr);
237   
238  }
239  
240  l->first=NULL;
241  l->last=NULL;
242  l->count=0;
243  
244  pthread_mutex_unlock(&l->mutex);
245  pthread_cond_broadcast(&l->cond);
246  
247  
248 }
249
250
251
252 // ---------------------------------------------------------------
253 bool findAndDestroy (List *l, void* data, void (*freefunc)(void*)) {
254  
255  ListNode *ln;
256  
257  
258  
259  if ( l==NULL ) {
260   return false;
261  }
262  
263  
264  pthread_mutex_lock(&l->mutex);
265  
266  for (ln=l->first; ln!=NULL && ln->data!=data; ln=ln->next);
267  
268  if ( ln==NULL ) {
269   
270   pthread_mutex_unlock(&l->mutex);
271   
272  } else {
273   
274   if ( ln->prev==NULL ) {
275    l->first=ln->next;
276   } else {
277    ln->prev->next=ln->next;
278   }
279   
280   if ( ln->next==NULL ) {
281    l->last=ln->prev;
282   } else {
283    ln->next->prev=ln->prev;
284   }
285   
286   
287   if ( freefunc!=NULL ) {
288    freefunc(data);
289   }
290   
291   l->count--;
292   
293   pthread_mutex_unlock(&l->mutex);
294   pthread_cond_broadcast(&l->cond);
295   
296  }
297  
298  
299  
300  return true;
301  
302 }
303
304
305
306 // -------------------------------------------------
307 void browseList (List *l, void (*browsefunc)(void*)) {
308  
309  ListNode *ln;
310  
311  
312  
313  if ( l==NULL || browsefunc==NULL ) {
314   return;
315  }
316  
317  
318  pthread_mutex_lock(&l->mutex);
319  
320  for (ln=l->first; ln!=NULL; ln=ln->next) {
321   browsefunc(ln->data);
322  }
323  
324  pthread_mutex_unlock(&l->mutex);
325  
326  
327 }
328
329
330 // --------------------------------------
331 void* convertToArray (List *l, size_t sz) {
332  
333  ListNode *ln;
334  void *tab=NULL, *p;
335  
336  
337  
338  if ( l==NULL || sz==0 ) {
339   return NULL;
340  }
341  
342  
343  pthread_mutex_lock(&l->mutex);
344  
345  if ( l->count>0 ) {
346   
347   tab=malloc(l->count*sz);
348   p=tab;
349   
350   for (ln=l->first; ln!=NULL; ln=ln->next) {
351    memcpy(p, ln->data, sz);
352    p+=sz;
353   }
354   
355  }
356  
357  pthread_mutex_unlock(&l->mutex);
358  
359  
360  return tab;
361  
362 }
363
364
365
366