manage loops when freeing
[protos/libecoli.git] / lib / ecoli_node_weakref.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2016, Olivier MATZ <zer0@droids-corp.org>
3  */
4
5 #ifndef ECOLI_NODE_WEAKREF_
6 #define ECOLI_NODE_WEAKREF_
7
8 #include <ecoli_node.h>
9
10 /* A node that just behaves like its child and that does not free
11  * its child when freed. **The child has to be freed manually**.
12  *
13  * useful to create cyclic graphs of nodes:
14  *   creating a loop (with clones) result in something that is not
15  *   freeable, due to reference counters
16  *
17  * Example:
18  *  expr = or()
19  *  val = int(0, 10)
20  *  op = str("!")
21  *  seq = seq(op, clone(expr))
22  *  expr.add(seq)
23  *  expr.add(val)
24  *  free(expr) // just decrease ref
25  *
26  * FAIL: expr cannot be freed due to cyclic refs
27  * The references are like this:
28  *
29  *                   val
30  *                    ^
31  *                    |
32  *     $user ~ ~ ~ > expr ---> seq ---> op
33  *                        <---
34  *
35  * It is solved with:
36  *  expr = or()
37  *  val = int(0, 10)
38  *  op = str("!")
39  *  weak = weak(expr)
40  *  seq = seq(op, weak)
41  *  expr.add(op)
42  *  expr.add(val)
43  *
44  *
45  *                   val
46  *                    ^
47  *                    |
48  *     $user ~ ~ ~ > expr ---------------> seq ---> op
49  *                        <- - - weak <---
50  *
51  * The node expr can be freed.
52  */
53
54 /* on error, child is *not* freed */
55 struct ec_node *ec_node_weakref(const char *id, struct ec_node *child);
56
57 /* on error, child is *not* freed */
58 int ec_node_weakref_set(struct ec_node *node, struct ec_node *child);
59
60 #endif