Merge lp:~cbehrens/agent-smith/slist-improvements into lp:agent-smith
- slist-improvements
- Merge into trunk
Proposed by
Chris Behrens
Status: | Merged |
---|---|
Merged at revision: | 74 |
Proposed branch: | lp:~cbehrens/agent-smith/slist-improvements |
Merge into: | lp:agent-smith |
Diff against target: |
741 lines (+405/-82) 7 files modified
src/slist.c (+134/-23) src/slist.h (+75/-8) src/spool.c (+23/-9) src/xen.c (+34/-7) tests/check_slist.c (+109/-17) tests/check_spool.c (+1/-0) tests/mock_xenstore.c (+29/-18) |
To merge this branch: | bzr merge lp:~cbehrens/agent-smith/slist-improvements |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Agent Smith devs | Pending | ||
Review via email: mp+33613@code.launchpad.net |
Commit message
Description of the change
Reworked SList to be a doubly linked list to not require searching to the end to add a new element.
Added a number of functions so that struct members are not accessed directly
Doxygen'd
To post a comment you must log in.
- 74. By Chris Behrens
-
add #ifndef/
define/ endif to slist.h
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/slist.c' |
2 | --- src/slist.c 2010-08-24 05:43:50 +0000 |
3 | +++ src/slist.c 2010-08-25 08:06:08 +0000 |
4 | @@ -14,31 +14,142 @@ |
5 | * limitations under the License. |
6 | */ |
7 | #include <malloc.h> |
8 | +#include <assert.h> |
9 | #include "slist.h" |
10 | |
11 | -SList *slist_append(SList *list, void *data) { |
12 | - SList *elem = malloc(sizeof(SList)); |
13 | - |
14 | +struct _SListElem { |
15 | + void *sle_data; |
16 | + SListElem *sle_prev; |
17 | + SListElem *sle_next; |
18 | +}; |
19 | + |
20 | +struct _SList { |
21 | + slist_destroy_cb sl_destroy_cb; |
22 | + SListElem sl_elem; |
23 | +}; |
24 | + |
25 | +/** |
26 | + * Create a new list for storing arbitrary data |
27 | + * |
28 | + * @param destroy_cb Callback to call when deiniting (Can be NULL) |
29 | + * @retval A new list that is init'd as empty |
30 | + */ |
31 | +SList *slist_init(slist_destroy_cb destroy_cb) |
32 | +{ |
33 | + SList *list = malloc(sizeof(SList)); |
34 | + |
35 | + if (list == NULL) |
36 | + return NULL; |
37 | + |
38 | + list->sl_destroy_cb = destroy_cb; |
39 | + list->sl_elem.sle_data = NULL; |
40 | + list->sl_elem.sle_prev = &(list->sl_elem); |
41 | + list->sl_elem.sle_next = &(list->sl_elem); |
42 | + |
43 | + return list; |
44 | +} |
45 | + |
46 | +/** |
47 | + * Destroy a previously created list |
48 | + * |
49 | + * @param slist The list to destroy |
50 | + */ |
51 | +void slist_deinit(SList *slist) |
52 | +{ |
53 | + if (slist != NULL) |
54 | + { |
55 | + SListElem *elem; |
56 | + SListElem *next; |
57 | + |
58 | + for(elem = slist_first(slist); |
59 | + elem != NULL; |
60 | + elem = next) |
61 | + { |
62 | + next = slist_next(slist, elem); |
63 | + if ((elem->sle_data != NULL) && slist->sl_destroy_cb != NULL) |
64 | + slist->sl_destroy_cb(elem->sle_data); |
65 | + free(elem); |
66 | + } |
67 | + |
68 | + free(slist); |
69 | + } |
70 | +} |
71 | + |
72 | +/** |
73 | + * Append a new element to a previously created slist |
74 | + * |
75 | + * @param list The list to append to |
76 | + * @param data Arbitrary data pointer |
77 | + * @retval The newly created element |
78 | + */ |
79 | +SListElem *slist_append(SList *list, void *data) { |
80 | + SListElem *elem; |
81 | + |
82 | + assert(list != NULL); |
83 | + |
84 | + elem = malloc(sizeof(SListElem)); |
85 | if (elem == NULL) |
86 | return NULL; |
87 | |
88 | - elem->data = data; |
89 | - elem->next = NULL; |
90 | - |
91 | - if (!list) { |
92 | - return elem; |
93 | - } else { |
94 | - SList *last; |
95 | - last = slist_last(list); |
96 | - last->next = elem; |
97 | - return list; |
98 | - } |
99 | -} |
100 | - |
101 | -SList *slist_last(SList *list) { |
102 | - if (list) { |
103 | - while (list->next) |
104 | - list = list->next; |
105 | - } |
106 | - return list; |
107 | -} |
108 | + elem->sle_data = data; |
109 | + |
110 | + elem->sle_prev = list->sl_elem.sle_prev; |
111 | + elem->sle_next = &(list->sl_elem); |
112 | + list->sl_elem.sle_prev->sle_next = elem; |
113 | + list->sl_elem.sle_prev = elem; |
114 | + |
115 | + return elem; |
116 | +} |
117 | + |
118 | +/** |
119 | + * Return the first element of a previously created list |
120 | + * |
121 | + * @param list The list |
122 | + * @retval The first element or NULL if none |
123 | + */ |
124 | +SListElem *slist_first(SList *list) { |
125 | + return slist_next(list, &(list->sl_elem)); |
126 | +} |
127 | + |
128 | +/** |
129 | + * Return the last element of a previously created list |
130 | + * |
131 | + * @param list The list |
132 | + * @retval The last element or NULL if none |
133 | + */ |
134 | +SListElem *slist_last(SList *list) { |
135 | + return slist_prev(list, &(list->sl_elem)); |
136 | +} |
137 | + |
138 | +/** |
139 | + * Return the next element in the list after the passed element |
140 | + * |
141 | + * @param list The list |
142 | + * @param elem The current element |
143 | + * @retval The element after the current element or NULL if none left |
144 | + */ |
145 | +SListElem *slist_next(SList *list, SListElem *elem) { |
146 | + return elem->sle_next == &(list->sl_elem) ? NULL : elem->sle_next; |
147 | +} |
148 | + |
149 | +/** |
150 | + * Return the previous element in the list after the passed element |
151 | + * |
152 | + * @param list The list |
153 | + * @param elem The current element |
154 | + * @retval The element before the current element or NULL if none |
155 | + */ |
156 | +SListElem *slist_prev(SList *list, SListElem *elem) { |
157 | + return elem->sle_prev == &(list->sl_elem) ? NULL : elem->sle_prev; |
158 | +} |
159 | + |
160 | +/** |
161 | + * Return the arbitrary data pointer for an element |
162 | + * |
163 | + * @param elem The element you want the data for |
164 | + * @retval The arbitrary data pointer |
165 | + */ |
166 | +void *slist_data(SListElem *elem) { |
167 | + return elem->sle_data; |
168 | +} |
169 | + |
170 | |
171 | === modified file 'src/slist.h' |
172 | --- src/slist.h 2010-07-07 09:26:52 +0000 |
173 | +++ src/slist.h 2010-08-25 08:06:08 +0000 |
174 | @@ -13,12 +13,79 @@ |
175 | * See the License for the specific language governing permissions and |
176 | * limitations under the License. |
177 | */ |
178 | +#ifndef __SRC_SLIST_H__ |
179 | +#define __SRC_SLIST_H__ |
180 | + |
181 | typedef struct _SList SList; |
182 | - |
183 | -struct _SList { |
184 | - void *data; |
185 | - SList *next; |
186 | -}; |
187 | - |
188 | -SList *slist_append(SList *list, void *data); |
189 | -SList *slist_last(SList *list); |
190 | +typedef struct _SListElem SListElem; |
191 | + |
192 | +typedef void (*slist_destroy_cb)(void *data); |
193 | + |
194 | +/** |
195 | + * Create a new list for storing arbitrary data |
196 | + * |
197 | + * @param destroy_cb Callback to call when deiniting (Can be NULL) |
198 | + * @retval A new list that is init'd as empty |
199 | + */ |
200 | +SList *slist_init(slist_destroy_cb destroy_cb); |
201 | + |
202 | +/** |
203 | + * Destroy a previously created list |
204 | + * |
205 | + * @param slist The list to destroy |
206 | + */ |
207 | +void slist_deinit(SList *slist); |
208 | + |
209 | +/** |
210 | + * Append a new element to a previously created slist |
211 | + * |
212 | + * @param list The list to append to |
213 | + * @param data Arbitrary data pointer |
214 | + * @retval The newly created element |
215 | + */ |
216 | +SListElem *slist_append(SList *list, void *data); |
217 | + |
218 | +/** |
219 | + * Return the first element of a previously created list |
220 | + * |
221 | + * @param list The list |
222 | + * @retval The first element or NULL if none |
223 | + */ |
224 | +SListElem *slist_first(SList *list); |
225 | + |
226 | +/** |
227 | + * Return the last element of a previously created list |
228 | + * |
229 | + * @param list The list |
230 | + * @retval The last element or NULL if none |
231 | + */ |
232 | +SListElem *slist_last(SList *list); |
233 | + |
234 | +/** |
235 | + * Return the next element in the list after the passed element |
236 | + * |
237 | + * @param list The list |
238 | + * @param elem The current element |
239 | + * @retval The element after the current element or NULL if none left |
240 | + */ |
241 | +SListElem *slist_next(SList *list, SListElem *elem); |
242 | + |
243 | +/** |
244 | + * Return the previous element in the list after the passed element |
245 | + * |
246 | + * @param list The list |
247 | + * @param elem The current element |
248 | + * @retval The element before the current element or NULL if none |
249 | + */ |
250 | +SListElem *slist_prev(SList *list, SListElem *elem); |
251 | + |
252 | +/** |
253 | + * Return the arbitrary data pointer for an element |
254 | + * |
255 | + * @param elem The element you want the data for |
256 | + * @retval The arbitrary data pointer |
257 | + */ |
258 | +void *slist_data(SListElem *elem); |
259 | + |
260 | + |
261 | +#endif /* __SRC_SLIST_H__ */ |
262 | |
263 | === modified file 'src/spool.c' |
264 | --- src/spool.c 2010-08-24 17:35:14 +0000 |
265 | +++ src/spool.c 2010-08-25 08:06:08 +0000 |
266 | @@ -35,6 +35,13 @@ |
267 | #define INCOMING_DIR "incoming" |
268 | #define OUTGOING_DIR "outgoing" |
269 | |
270 | +/* |
271 | + * Global variables |
272 | + */ |
273 | + |
274 | +int inotify_fd = -1; |
275 | +SList *callbacks = NULL; |
276 | + |
277 | int spool_ensure_dir(const char *dir); |
278 | |
279 | char *spool_basedir(void); |
280 | @@ -44,11 +51,19 @@ |
281 | |
282 | char *tmp; |
283 | |
284 | + callbacks = slist_init(NULL); |
285 | + if (callbacks == NULL) |
286 | + { |
287 | + return -1; |
288 | + } |
289 | + |
290 | if (spool_ensure_dir(tmp = spool_incoming_dir()) == 0) |
291 | free(tmp); |
292 | else { |
293 | syslog(LOG_DAEMON | LOG_CRIT, "Failed to create incoming spool dir: %s", tmp); |
294 | free(tmp); |
295 | + slist_deinit(callbacks); |
296 | + callbacks = NULL; |
297 | return -1; |
298 | } |
299 | |
300 | @@ -57,6 +72,8 @@ |
301 | else { |
302 | syslog(LOG_DAEMON | LOG_CRIT, "Failed to create outgoing spool dir: %s", tmp); |
303 | free(tmp); |
304 | + slist_deinit(callbacks); |
305 | + callbacks = NULL; |
306 | return -1; |
307 | } |
308 | |
309 | @@ -235,10 +252,6 @@ |
310 | return 0; |
311 | } |
312 | |
313 | -int inotify_fd = -1; |
314 | - |
315 | -SList *callbacks = NULL; |
316 | - |
317 | int spool_watch(spool_callback cb) { |
318 | char *incoming_dir; |
319 | |
320 | @@ -268,8 +281,7 @@ |
321 | |
322 | free(incoming_dir); |
323 | |
324 | - callbacks = slist_append(callbacks, cb); |
325 | - if (callbacks == NULL) |
326 | + if (slist_append(callbacks, cb) == NULL) |
327 | { |
328 | return -1; |
329 | } |
330 | @@ -300,7 +312,7 @@ |
331 | |
332 | if (ev->len) { |
333 | char *path, *incoming_dir; |
334 | - SList *ptr; |
335 | + SListElem *elem; |
336 | |
337 | if (ev->len > len) { |
338 | /* No room left in buffer, so exit out of this packet */ |
339 | @@ -311,8 +323,10 @@ |
340 | path = util_join_paths(incoming_dir, ev->name); |
341 | free(incoming_dir); |
342 | |
343 | - for (ptr = callbacks; ptr; ptr=ptr->next) { |
344 | - spool_callback cb = (spool_callback) ptr->data; |
345 | + for(elem = slist_first(callbacks); |
346 | + elem != NULL; |
347 | + elem = slist_next(callbacks, elem)) { |
348 | + spool_callback cb = (spool_callback)slist_data(elem); |
349 | cb(path); |
350 | } |
351 | |
352 | |
353 | === modified file 'src/xen.c' |
354 | --- src/xen.c 2010-08-20 15:27:36 +0000 |
355 | +++ src/xen.c 2010-08-25 08:06:08 +0000 |
356 | @@ -18,6 +18,7 @@ |
357 | #include <stdlib.h> |
358 | #include <string.h> |
359 | #include <unistd.h> |
360 | +#include <assert.h> |
361 | #include <xs.h> |
362 | #include "log.h" |
363 | #include "slist.h" |
364 | @@ -36,9 +37,24 @@ |
365 | /* |
366 | * Global variables |
367 | */ |
368 | -SList *handlers; |
369 | +SList *handlers = NULL; |
370 | struct xs_handle *xh; |
371 | |
372 | +/* |
373 | + * Static function prototypes |
374 | + */ |
375 | +static void _xen_destroy_callback(void *data); |
376 | + |
377 | +/* |
378 | + * Static functions |
379 | + */ |
380 | +static void _xen_destroy_callback(void *data) { |
381 | + token_callback_tuple *cb = (token_callback_tuple *)data; |
382 | + |
383 | + free(cb->token); |
384 | + free(cb); |
385 | +} |
386 | + |
387 | void xen_fire_callback(const char *path, const char *token, void *buf, |
388 | unsigned int buflen); |
389 | |
390 | @@ -48,9 +64,16 @@ |
391 | * @returns 0 on success, -1 otherwise |
392 | */ |
393 | int xen_init(void) { |
394 | - if (!xh) |
395 | - if (!(xh = xs_domain_open())) |
396 | + if (!xh) { |
397 | + handlers = slist_init(_xen_destroy_callback); |
398 | + if (handlers == NULL) |
399 | + return -1; |
400 | + |
401 | + if (!(xh = xs_domain_open())) { |
402 | AGENT_LOG("Failed to connect to Xen Store: %s", strerror(errno)); |
403 | + slist_deinit(handlers); |
404 | + } |
405 | + } |
406 | return xh ? 0 : -1; |
407 | } |
408 | |
409 | @@ -68,6 +91,8 @@ |
410 | const char *data) { |
411 | token_callback_tuple *cb; |
412 | |
413 | + assert(xh != NULL); /* make sure xen_init() was called */ |
414 | + |
415 | if (!(cb = malloc(sizeof(token_callback_tuple)))) { |
416 | AGENT_LOG("malloc: %s", strerror(errno)); |
417 | return -1; |
418 | @@ -88,7 +113,7 @@ |
419 | |
420 | cb->callback = callback; |
421 | |
422 | - if (!(handlers = slist_append(handlers, cb))) { |
423 | + if (slist_append(handlers, cb) == NULL) { |
424 | AGENT_LOG0("Failed to append callback to handler list."); |
425 | free(cb->token); |
426 | free(cb); |
427 | @@ -171,10 +196,12 @@ |
428 | |
429 | void xen_fire_callback(const char *path, const char *token, void *buf, |
430 | unsigned int buflen) { |
431 | - SList *ptr; |
432 | + SListElem *elem; |
433 | |
434 | - for (ptr = handlers; ptr; ptr=ptr->next) { |
435 | - token_callback_tuple *t = (token_callback_tuple *) ptr->data; |
436 | + for (elem = slist_first(handlers); |
437 | + elem != NULL; |
438 | + elem = slist_next(handlers, elem)) { |
439 | + token_callback_tuple *t = (token_callback_tuple *)slist_data(elem); |
440 | if (strcmp(token, t->token) == 0) { |
441 | t->callback(path, buf, buflen, t->token); |
442 | break; |
443 | |
444 | === modified file 'tests/check_slist.c' |
445 | --- tests/check_slist.c 2010-07-07 09:26:52 +0000 |
446 | +++ tests/check_slist.c 2010-08-25 08:06:08 +0000 |
447 | @@ -15,28 +15,119 @@ |
448 | */ |
449 | #include <stdlib.h> |
450 | #include <check.h> |
451 | +#include <assert.h> |
452 | #include "../src/slist.h" |
453 | |
454 | START_TEST(test_slist_append) |
455 | { |
456 | - SList *list = NULL; |
457 | char *testdata[] = { "foo", "bar", "baz" }; |
458 | - |
459 | - list = slist_append(list, (void *) testdata[0]); |
460 | - fail_unless(list->data == testdata[0], "element's data attribute not correctly set"); |
461 | - fail_unless(list->next == NULL, "element's next attribute not set to NULL"); |
462 | - list = slist_append(list, (void *) testdata[1]); |
463 | - fail_unless(list->data == testdata[0], "element's data attribute not correctly set"); |
464 | - fail_unless(list->next != NULL, "element's next attribute set to NULL"); |
465 | - fail_unless(list->next->data == testdata[1], "element's data attribute not correctly set"); |
466 | - fail_unless(list->next->next == NULL, "element's next attribute not set to NULL"); |
467 | - list = slist_append(list, (void *) testdata[2]); |
468 | - fail_unless(list->data == testdata[0], "element's data attribute not correctly set"); |
469 | - fail_unless(list->next != NULL, "element's next attribute set to NULL"); |
470 | - fail_unless(list->next->data == testdata[1], "element's data attribute not correctly set"); |
471 | - fail_unless(list->next->next != NULL, "element's next attribute set to NULL"); |
472 | - fail_unless(list->next->next->data == testdata[2], "element's data attribute not correctly set"); |
473 | - fail_unless(list->next->next->next == NULL, "element's next attribute not set to NULL"); |
474 | + SList *list = NULL; |
475 | + SListElem *elem; |
476 | + SListElem *elem1; |
477 | + SListElem *elem2; |
478 | + SListElem *elem2_2; |
479 | + SListElem *elem3; |
480 | + |
481 | + fail_unless((list = slist_init(NULL)) != NULL, "initing failed"); |
482 | + |
483 | + fail_unless(slist_append(list, (void *) testdata[0]) != NULL, "appending failed"); |
484 | + |
485 | + fail_unless((elem = slist_first(list)) != NULL, "couldn't get first elem"); |
486 | + |
487 | + fail_unless(slist_last(list) == elem, "last element is not same as first element"); |
488 | + |
489 | + fail_unless(slist_data(elem) == testdata[0], "element's data attribute not correctly set"); |
490 | + fail_unless(slist_next(list, elem) == NULL, "next element is not NULL"); |
491 | + fail_unless(slist_prev(list, elem) == NULL, "prev element is not NULL"); |
492 | + |
493 | + fail_unless((elem2 = slist_append(list, (void *)testdata[1])) != NULL); |
494 | + |
495 | + fail_unless((elem1 = slist_first(list)) != NULL, "couldn't get first elem"); |
496 | + |
497 | + fail_unless((elem1 == elem), "first element doesn't match original first element"); |
498 | + |
499 | + fail_unless(slist_data(elem) == testdata[0], "first element's data attribute not correctly set"); |
500 | + |
501 | + fail_unless(slist_next(list, elem) == elem2, "1st element's next ptr is not 2nd element"); |
502 | + fail_unless(slist_prev(list, elem) == NULL, "1st element's prev ptr is not NULL"); |
503 | + fail_unless(slist_prev(list, elem2) == elem, "2nd element's prev ptr is not 1st element"); |
504 | + fail_unless(slist_next(list, elem2) == NULL, "2nd element's next ptr is not NULL"); |
505 | + fail_unless(slist_last(list) == elem2, "last element is not same as 2nd element"); |
506 | + |
507 | + fail_unless(slist_data(elem2) == testdata[1], "2nd element's data attribute not correctly set"); |
508 | + |
509 | + fail_unless((elem3 = slist_append(list, (void *)testdata[2])) != NULL); |
510 | + |
511 | + fail_unless((elem1 = slist_first(list)) != NULL, "couldn't get first elem"); |
512 | + |
513 | + fail_unless((elem1 == elem), "first element doesn't match original first element"); |
514 | + |
515 | + fail_unless((elem2_2 = slist_next(list, elem1)) != NULL, "couldn't get 2nd elem"); |
516 | + |
517 | + fail_unless((elem2_2 == elem2), "2nd element doesn't match original 2nd element"); |
518 | + |
519 | + fail_unless(slist_data(elem) == testdata[0], "first element's data attribute not correctly set"); |
520 | + |
521 | + fail_unless(slist_next(list, elem) == elem2, "1st element's next ptr is not 2nd element"); |
522 | + fail_unless(slist_prev(list, elem) == NULL, "1st element's prev ptr is not NULL"); |
523 | + fail_unless(slist_prev(list, elem2) == elem, "2nd element's prev ptr is not 1st element"); |
524 | + fail_unless(slist_next(list, elem2) == elem3, "2nd element's next ptr is not third element"); |
525 | + fail_unless(slist_prev(list, elem3) == elem2, "3rd element's prev ptr is not 2nd element"); |
526 | + fail_unless(slist_next(list, elem3) == NULL, "3rd element's next ptr is not NULL"); |
527 | + fail_unless(slist_last(list) == elem3, "last element is not same as 3rd element"); |
528 | + |
529 | + fail_unless(slist_data(elem3) == testdata[2], "3rd element's data attribute not correctly set"); |
530 | + |
531 | + slist_deinit(list); |
532 | +} |
533 | +END_TEST |
534 | + |
535 | +int destroy_cb_iter; |
536 | +char *destroy_cb_testdata[] = { "foo", "bar", "baz" }; |
537 | + |
538 | +void _slist_destroy_cb(void *arg) |
539 | +{ |
540 | + switch(++destroy_cb_iter) |
541 | + { |
542 | + case 1: |
543 | + assert(arg == destroy_cb_testdata[0]); |
544 | + break; |
545 | + case 2: |
546 | + assert(arg == destroy_cb_testdata[1]); |
547 | + break; |
548 | + case 3: |
549 | + assert(arg == destroy_cb_testdata[2]); |
550 | + break; |
551 | + case 4: |
552 | + break; |
553 | + } |
554 | +} |
555 | + |
556 | +START_TEST(test_slist_destroy_cb) |
557 | +{ |
558 | + SList *list = NULL; |
559 | + |
560 | + destroy_cb_iter = 0; |
561 | + |
562 | + fail_unless((list = slist_init(NULL)) != NULL, "initing failed"); |
563 | + |
564 | + fail_unless(slist_append(list, (void *) destroy_cb_testdata[0]) != NULL, "appending failed"); |
565 | + fail_unless(slist_append(list, (void *) destroy_cb_testdata[1]) != NULL, "appending failed"); |
566 | + fail_unless(slist_append(list, (void *) destroy_cb_testdata[2]) != NULL, "appending failed"); |
567 | + |
568 | + slist_deinit(list); |
569 | + |
570 | + fail_unless(destroy_cb_iter == 0); |
571 | + |
572 | + fail_unless((list = slist_init(_slist_destroy_cb)) != NULL, "initing failed"); |
573 | + |
574 | + fail_unless(slist_append(list, (void *) destroy_cb_testdata[0]) != NULL, "appending failed"); |
575 | + fail_unless(slist_append(list, (void *) destroy_cb_testdata[1]) != NULL, "appending failed"); |
576 | + fail_unless(slist_append(list, (void *) destroy_cb_testdata[2]) != NULL, "appending failed"); |
577 | + |
578 | + slist_deinit(list); |
579 | + |
580 | + fail_unless(destroy_cb_iter == 3); |
581 | } |
582 | END_TEST |
583 | |
584 | @@ -46,6 +137,7 @@ |
585 | |
586 | TCase *tc_slist = tcase_create("slist"); |
587 | tcase_add_test(tc_slist, test_slist_append); |
588 | + tcase_add_test(tc_slist, test_slist_destroy_cb); |
589 | suite_add_tcase(s, tc_slist); |
590 | |
591 | return s; |
592 | |
593 | === modified file 'tests/check_spool.c' |
594 | --- tests/check_spool.c 2010-08-24 15:54:14 +0000 |
595 | +++ tests/check_spool.c 2010-08-25 08:06:08 +0000 |
596 | @@ -112,6 +112,7 @@ |
597 | FILE *fp; |
598 | |
599 | setenv("AGENT_MSG_SPOOL", testdir, 1); |
600 | + fail_unless(spool_init() == 0, "Failed to init spool"); |
601 | fail_unless(spool_watch(spool_cb) == 0, "Failed to add watch."); |
602 | spool_process_pending_events(); |
603 | fail_unless(spool_cb_called == 0, "Spool callback got called even though nothing had happened yet."); |
604 | |
605 | === modified file 'tests/mock_xenstore.c' |
606 | --- tests/mock_xenstore.c 2010-08-19 08:09:01 +0000 |
607 | +++ tests/mock_xenstore.c 2010-08-25 08:06:08 +0000 |
608 | @@ -24,6 +24,9 @@ |
609 | #include <sys/socket.h> |
610 | |
611 | struct xs_handle { |
612 | + SList *xs_object_list; |
613 | + SList *watches; |
614 | + SList *pending_notifications; |
615 | char *verification; |
616 | char transactions; |
617 | int clientfd; |
618 | @@ -46,10 +49,6 @@ |
619 | const char *token; |
620 | }; |
621 | |
622 | -SList *xs_object_list = NULL; |
623 | -SList *watches = NULL; |
624 | -SList *pending_notifications = NULL; |
625 | - |
626 | static int validate_xs_handle(struct xs_handle *h) { |
627 | if (h && !strcmp(h->verification, "foo")) |
628 | return 1; |
629 | @@ -75,6 +74,11 @@ |
630 | return NULL; |
631 | |
632 | struct xs_handle *retval = malloc(sizeof(struct xs_handle)); |
633 | + |
634 | + retval->watches = slist_init(NULL); |
635 | + retval->xs_object_list = slist_init(NULL); |
636 | + retval->pending_notifications = slist_init(NULL); |
637 | + |
638 | retval->verification = strdup("foo"); |
639 | retval->transactions = 0; |
640 | |
641 | @@ -112,21 +116,23 @@ |
642 | } |
643 | |
644 | bool xs_write(struct xs_handle *h, xs_transaction_t t, const char *path, const void *buf, unsigned int len) { |
645 | - SList *ptr; |
646 | + SListElem *ptr; |
647 | struct xs_object *obj; |
648 | |
649 | if (!validate_xs_transaction(h, t)) |
650 | return 0; |
651 | |
652 | - for (ptr = watches; ptr; ptr=ptr->next) { |
653 | - struct xs_path_watch *watch = (struct xs_path_watch *) ptr->data; |
654 | + for (ptr = slist_first(h->watches); |
655 | + ptr != NULL; |
656 | + ptr = slist_next(h->watches, ptr)) { |
657 | + struct xs_path_watch *watch = (struct xs_path_watch *)slist_data(ptr); |
658 | if (strstr(path, watch->path) == path) { |
659 | /* Either they must be identical or the triggering path be in a subdir of the watched path */ |
660 | if (strlen(path) == strlen(watch->path) || path[strlen(watch->path)] == '/') { |
661 | struct notification *n = (struct notification *) malloc(sizeof(struct notification)); |
662 | n->path = path; |
663 | n->token = watch->token; |
664 | - pending_notifications = slist_append(pending_notifications, n); |
665 | + slist_append(h->pending_notifications, n); |
666 | /* We notify the client that there's some action */ |
667 | if (write(h->libraryfd, "X", 1) < 1) |
668 | abort(); |
669 | @@ -134,8 +140,10 @@ |
670 | } |
671 | } |
672 | |
673 | - for (ptr = xs_object_list; ptr; ptr=ptr->next) { |
674 | - obj = (struct xs_object *) ptr->data; |
675 | + for (ptr = slist_first(h->xs_object_list); |
676 | + ptr != NULL; |
677 | + ptr = slist_next(h->xs_object_list, ptr)) { |
678 | + obj = (struct xs_object *)slist_data(ptr); |
679 | if (strcmp(obj->path, path) == 0) { |
680 | obj->buflen = len; |
681 | obj->buf = buf; |
682 | @@ -146,19 +154,21 @@ |
683 | obj->path = strdup(path); |
684 | obj->buf = buf; |
685 | obj->buflen = len; |
686 | - xs_object_list = slist_append(xs_object_list, obj); |
687 | + slist_append(h->xs_object_list, obj); |
688 | |
689 | return 1; |
690 | } |
691 | |
692 | void *xs_read(struct xs_handle *h, xs_transaction_t t, const char *path, unsigned int *len) { |
693 | - SList *ptr; |
694 | + SListElem *ptr; |
695 | |
696 | if (!validate_xs_transaction(h, t)) |
697 | return 0; |
698 | |
699 | - for (ptr = xs_object_list; ptr; ptr=ptr->next) { |
700 | - struct xs_object *obj = (struct xs_object *) ptr->data; |
701 | + for (ptr = slist_first(h->xs_object_list); |
702 | + ptr != NULL; |
703 | + ptr = slist_next(h->xs_object_list, ptr)) { |
704 | + struct xs_object *obj = (struct xs_object *)slist_data(ptr); |
705 | if (strcmp(obj->path, path) == 0) { |
706 | void *buf; |
707 | |
708 | @@ -180,7 +190,7 @@ |
709 | watch = (struct xs_path_watch *) malloc(sizeof(struct xs_path_watch)); |
710 | watch->path = path; |
711 | watch->token = token; |
712 | - watches = slist_append(watches, watch); |
713 | + slist_append(h->watches, watch); |
714 | |
715 | return 1; |
716 | } |
717 | @@ -189,11 +199,12 @@ |
718 | |
719 | char **xs_read_watch(struct xs_handle *h, unsigned int *num) { |
720 | char **retval; |
721 | + SListElem *elem; |
722 | |
723 | if (!validate_xs_handle(h)) |
724 | return NULL; |
725 | |
726 | - if (!pending_notifications) { |
727 | + if ((elem = slist_first(h->pending_notifications)) == NULL) { |
728 | if (nonblocking) { |
729 | errno = EWOULDBLOCK; |
730 | return NULL; |
731 | @@ -208,8 +219,8 @@ |
732 | } |
733 | |
734 | retval = (char **) malloc(sizeof(char *)*2); |
735 | - *retval = strdup(((struct notification *) pending_notifications->data)->path); |
736 | - *(retval + 1) = strdup(((struct notification *) pending_notifications->data)->token); |
737 | + *retval = strdup(((struct notification *) slist_data(elem))->path); |
738 | + *(retval + 1) = strdup(((struct notification *) slist_data(elem))->token); |
739 | *num = 2; |
740 | |
741 | return retval; |