Merge lp:~cbehrens/agent-smith/slist-improvements into lp:agent-smith

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
Reviewer Review Type Date Requested Status
Agent Smith devs Pending
Review via email: mp+33613@code.launchpad.net

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;

Subscribers

People subscribed via source and target branches