save
[protos/libecoli.git] / lib / ecoli_node_weakref.h
1 /*
2  * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of the University of California, Berkeley nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #ifndef ECOLI_NODE_WEAKREF_
29 #define ECOLI_NODE_WEAKREF_
30
31 #include <ecoli_node.h>
32
33 /* A node that just behaves like its child and that does not free
34  * its child when freed. **The child has to be freed manually**.
35  *
36  * useful to create cyclic graphs of nodes:
37  *   creating a loop (with clones) result in something that is not
38  *   freeable, due to reference counters
39  *
40  * Example:
41  *  val = int(0, 10)
42  *  op = str("!")
43  *  expr = or()
44  *  seq = seq(clone(op), clone(expr))
45  *  expr.add(clone(seq))
46  *  expr.add(clone(val))
47  *  free(val)
48  *  free(op)
49  *  free(seq)
50  *
51  * FAIL: expr cannot be freed due to cyclic refs
52  * The references are like this:
53  *
54  *                   val
55  *                    ^
56  *                    |
57  *        $user ---> expr ---> seq ---> op
58  *                        <---
59  *
60  * It is solved with:
61  *  val = int(0, 10)
62  *  op = str("!")
63  *  expr = or()
64  *  weak = weak(expr)
65  *  seq = seq(clone(op), clone(weak))
66  *  expr.add(clone(seq))
67  *  expr.add(clone(val))
68  *  free(val)
69  *  free(op)
70  *  free(weak)
71  *  free(seq)
72  *
73  *
74  *                   val
75  *                    ^
76  *                    |
77  *        $user ---> expr ---------------> seq ---> op
78  *                        <- - - weak <---
79  *
80  * The node expr can be freed.
81  */
82
83 /* on error, child is *not* freed */
84 struct ec_node *ec_node_weakref(const char *id, struct ec_node *child);
85
86 /* on error, child is *not* freed */
87 int ec_node_weakref_set(struct ec_node *node, struct ec_node *child);
88
89 #endif