]> git.ozlabs.org Git - ccan/blob - ccan/aga/aga.c
tcon: Encode information on container members in "type" canaries
[ccan] / ccan / aga / aga.c
1 /* Licensed under LGPLv2+ - see LICENSE file for details */
2 #include "config.h"
3
4 #include <stdbool.h>
5 #include <stdlib.h>
6 #include <assert.h>
7
8 #include <ccan/aga/aga.h>
9
10 #include "private.h"
11
12 void aga_init_graph_(struct aga_graph *g,
13                      aga_first_edge_fn first_edge,
14                      aga_next_edge_fn next_edge,
15                      aga_edge_info_fn edge_info)
16 {
17         g->sequence = 0;
18         g->error = 0;
19
20         g->first_edge = first_edge;
21         g->next_edge = next_edge;
22         g->edge_info = edge_info;
23 }
24
25 int aga_error(const struct aga_graph *g)
26 {
27         return g->error;
28 }
29
30 void aga_fail(struct aga_graph *g, int error)
31 {
32         g->error = error;
33 }
34
35 int aga_start(struct aga_graph *g)
36 {
37         if (g->sequence & 1) /* Odd means someone's already running */
38                 return -1;
39         assert(g->error == 0);
40         /* FIXME: Want an atomic cmpxchg to make this thread safe */
41         ++g->sequence;
42         return 0;
43 }
44
45 bool aga_check_state(const struct aga_graph *g)
46 {
47         if (!(g->sequence & 1))
48                 return false; /* No algo in progress */
49         if (g->error)
50                 return false; /* error state */
51         return true;
52 }
53
54 void aga_finish(struct aga_graph *g)
55 {
56         assert(g->sequence & 1);
57         g->error = 0;
58         g->sequence++;
59 }
60
61 bool aga_update_node(const struct aga_graph *g, struct aga_node *node)
62 {
63         if (node->sequence == g->sequence)
64                 return false;
65
66         node->sequence = g->sequence;
67         return true;
68 }
69
70 const void *aga_first_edge(const struct aga_graph *g, const struct aga_node *n)
71 {
72         return g->first_edge(g, n);
73 }
74
75 const void *aga_next_edge(const struct aga_graph *g, const struct aga_node *n,
76                           const void *e)
77 {
78         if (!e)
79                 return NULL;
80         else
81                 return g->next_edge(g, n, e);
82 }
83
84 int aga_edge_info(const struct aga_graph *g, const struct aga_node *n,
85                   const void *e, struct aga_edge_info *ei)
86 {
87         int rc;
88
89         ei->to = NULL;
90         rc = g->edge_info(g, n, e, ei);
91         assert(rc <= 0);
92         return rc;
93 }