/* Licensed under LGPLv2+ - see LICENSE file for details */ #include "config.h" #include #include #include #include #include "private.h" void aga_init_graph_(struct aga_graph *g, aga_first_edge_fn first_edge, aga_next_edge_fn next_edge, aga_edge_info_fn edge_info) { g->sequence = 0; g->error = 0; g->first_edge = first_edge; g->next_edge = next_edge; g->edge_info = edge_info; } int aga_error(const struct aga_graph *g) { return g->error; } void aga_fail(struct aga_graph *g, int error) { g->error = error; } int aga_start(struct aga_graph *g) { if (g->sequence & 1) /* Odd means someone's already running */ return -1; assert(g->error == 0); /* FIXME: Want an atomic cmpxchg to make this thread safe */ ++g->sequence; return 0; } bool aga_check_state(const struct aga_graph *g) { if (!(g->sequence & 1)) return false; /* No algo in progress */ if (g->error) return false; /* error state */ return true; } void aga_finish(struct aga_graph *g) { assert(g->sequence & 1); g->error = 0; g->sequence++; } bool aga_update_node(const struct aga_graph *g, struct aga_node *node) { if (node->sequence == g->sequence) return false; node->sequence = g->sequence; return true; } const void *aga_first_edge(const struct aga_graph *g, const struct aga_node *n) { return g->first_edge(g, n); } const void *aga_next_edge(const struct aga_graph *g, const struct aga_node *n, const void *e) { if (!e) return NULL; else return g->next_edge(g, n, e); } int aga_edge_info(const struct aga_graph *g, const struct aga_node *n, const void *e, struct aga_edge_info *ei) { int rc; ei->to = NULL; rc = g->edge_info(g, n, e, ei); assert(rc <= 0); return rc; }