/src/haproxy/include/haproxy/xref.h
Line | Count | Source |
1 | | /* |
2 | | * include/haproxy/xref.h |
3 | | * Atomic cross-references between two elements - functions |
4 | | * |
5 | | * Copyright (C) 2017 Thierry Fournier <thierry.fournier@ozon.io> |
6 | | * Copyright (C) 2020 Willy Tarreau - w@1wt.eu |
7 | | * |
8 | | * Permission is hereby granted, free of charge, to any person obtaining |
9 | | * a copy of this software and associated documentation files (the |
10 | | * "Software"), to deal in the Software without restriction, including |
11 | | * without limitation the rights to use, copy, modify, merge, publish, |
12 | | * distribute, sublicense, and/or sell copies of the Software, and to |
13 | | * permit persons to whom the Software is furnished to do so, subject to |
14 | | * the following conditions: |
15 | | * |
16 | | * The above copyright notice and this permission notice shall be |
17 | | * included in all copies or substantial portions of the Software. |
18 | | * |
19 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
20 | | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
21 | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
22 | | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
23 | | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
24 | | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
25 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
26 | | * OTHER DEALINGS IN THE SOFTWARE. |
27 | | */ |
28 | | #ifndef __HAPROXY_XREF_H__ |
29 | | #define __HAPROXY_XREF_H__ |
30 | | |
31 | | #include <haproxy/api.h> |
32 | | #include <haproxy/xref-t.h> |
33 | | |
34 | | /* xref is used to create relation between two elements. |
35 | | * Once an element is released, it breaks the relation. If the |
36 | | * relation is already broken, it frees the xref struct. |
37 | | * The pointer between two elements is sort of a refcount with |
38 | | * max value 1. The relation is only between two elements. |
39 | | * The pointer and the type of elements a and b are conventional. |
40 | | */ |
41 | | |
42 | | static inline void xref_create(struct xref *xref_a, struct xref *xref_b) |
43 | 0 | { |
44 | 0 | xref_a->peer = xref_b; |
45 | 0 | xref_b->peer = xref_a; |
46 | 0 | } Unexecuted instantiation: haproxy.c:xref_create Unexecuted instantiation: listener.c:xref_create Unexecuted instantiation: log.c:xref_create Unexecuted instantiation: mworker.c:xref_create Unexecuted instantiation: peers.c:xref_create Unexecuted instantiation: pool.c:xref_create Unexecuted instantiation: proto_sockpair.c:xref_create Unexecuted instantiation: proxy.c:xref_create Unexecuted instantiation: resolvers.c:xref_create Unexecuted instantiation: ring.c:xref_create Unexecuted instantiation: sample.c:xref_create Unexecuted instantiation: server.c:xref_create Unexecuted instantiation: session.c:xref_create Unexecuted instantiation: sink.c:xref_create Unexecuted instantiation: sock.c:xref_create Unexecuted instantiation: stats-proxy.c:xref_create Unexecuted instantiation: stats.c:xref_create Unexecuted instantiation: stick_table.c:xref_create Unexecuted instantiation: stream.c:xref_create Unexecuted instantiation: tcp_rules.c:xref_create Unexecuted instantiation: tcpcheck.c:xref_create Unexecuted instantiation: thread.c:xref_create Unexecuted instantiation: tools.c:xref_create Unexecuted instantiation: trace.c:xref_create Unexecuted instantiation: vars.c:xref_create Unexecuted instantiation: activity.c:xref_create Unexecuted instantiation: applet.c:xref_create Unexecuted instantiation: backend.c:xref_create Unexecuted instantiation: cfgparse-listen.c:xref_create Unexecuted instantiation: cfgparse.c:xref_create Unexecuted instantiation: channel.c:xref_create Unexecuted instantiation: check.c:xref_create Unexecuted instantiation: cli.c:xref_create Unexecuted instantiation: connection.c:xref_create Unexecuted instantiation: debug.c:xref_create Unexecuted instantiation: dns.c:xref_create Unexecuted instantiation: dns_ring.c:xref_create Unexecuted instantiation: errors.c:xref_create Unexecuted instantiation: extcheck.c:xref_create Unexecuted instantiation: fd.c:xref_create Unexecuted instantiation: filters.c:xref_create Unexecuted instantiation: flt_decomp.c:xref_create Unexecuted instantiation: flt_http_comp.c:xref_create Unexecuted instantiation: frontend.c:xref_create Unexecuted instantiation: haterm.c:xref_create Unexecuted instantiation: http_ana.c:xref_create Unexecuted instantiation: http_ext.c:xref_create Unexecuted instantiation: http_htx.c:xref_create Unexecuted instantiation: http_rules.c:xref_create Unexecuted instantiation: limits.c:xref_create Unexecuted instantiation: mux_spop.c:xref_create Unexecuted instantiation: pattern.c:xref_create Unexecuted instantiation: payload.c:xref_create Unexecuted instantiation: proto_rhttp.c:xref_create Unexecuted instantiation: queue.c:xref_create Unexecuted instantiation: stats-html.c:xref_create Unexecuted instantiation: stats-json.c:xref_create Unexecuted instantiation: stconn.c:xref_create Unexecuted instantiation: cache.c:xref_create Unexecuted instantiation: cfgparse-global.c:xref_create Unexecuted instantiation: compression.c:xref_create Unexecuted instantiation: fcgi-app.c:xref_create Unexecuted instantiation: flt_spoe.c:xref_create Unexecuted instantiation: http_fetch.c:xref_create Unexecuted instantiation: proto_tcp.c:xref_create |
47 | | |
48 | | static inline struct xref *xref_get_peer_and_lock(struct xref *xref) |
49 | 0 | { |
50 | 0 | struct xref *local; |
51 | 0 | struct xref *remote; |
52 | |
|
53 | 0 | while (1) { |
54 | | |
55 | | /* Get the local pointer to the peer. */ |
56 | 0 | local = _HA_ATOMIC_XCHG(&xref->peer, XREF_BUSY); |
57 | 0 | __ha_barrier_atomic_store(); |
58 | | |
59 | | /* If the local pointer is NULL, the peer no longer exists. */ |
60 | 0 | if (local == NULL) { |
61 | 0 | xref->peer = NULL; |
62 | 0 | return NULL; |
63 | 0 | } |
64 | | |
65 | | /* If the local pointeru is BUSY, the peer try to acquire the |
66 | | * lock. We retry the process. |
67 | | */ |
68 | 0 | if (local == XREF_BUSY) |
69 | 0 | continue; |
70 | | |
71 | | /* We are locked, the peer can't disappear, try to acquire |
72 | | * the pper's lock. Note that remote can't be NULL. |
73 | | */ |
74 | 0 | remote = _HA_ATOMIC_XCHG(&local->peer, XREF_BUSY); |
75 | | |
76 | | /* The remote lock is BUSY, We retry the process. */ |
77 | 0 | if (remote == XREF_BUSY) { |
78 | 0 | xref->peer = local; |
79 | 0 | __ha_barrier_store(); |
80 | 0 | continue; |
81 | 0 | } |
82 | | |
83 | | /* We have the lock, we return the value of the xref. */ |
84 | 0 | return local; |
85 | 0 | } |
86 | 0 | } Unexecuted instantiation: haproxy.c:xref_get_peer_and_lock Unexecuted instantiation: listener.c:xref_get_peer_and_lock Unexecuted instantiation: log.c:xref_get_peer_and_lock Unexecuted instantiation: mworker.c:xref_get_peer_and_lock Unexecuted instantiation: peers.c:xref_get_peer_and_lock Unexecuted instantiation: pool.c:xref_get_peer_and_lock Unexecuted instantiation: proto_sockpair.c:xref_get_peer_and_lock Unexecuted instantiation: proxy.c:xref_get_peer_and_lock Unexecuted instantiation: resolvers.c:xref_get_peer_and_lock Unexecuted instantiation: ring.c:xref_get_peer_and_lock Unexecuted instantiation: sample.c:xref_get_peer_and_lock Unexecuted instantiation: server.c:xref_get_peer_and_lock Unexecuted instantiation: session.c:xref_get_peer_and_lock Unexecuted instantiation: sink.c:xref_get_peer_and_lock Unexecuted instantiation: sock.c:xref_get_peer_and_lock Unexecuted instantiation: stats-proxy.c:xref_get_peer_and_lock Unexecuted instantiation: stats.c:xref_get_peer_and_lock Unexecuted instantiation: stick_table.c:xref_get_peer_and_lock Unexecuted instantiation: stream.c:xref_get_peer_and_lock Unexecuted instantiation: tcp_rules.c:xref_get_peer_and_lock Unexecuted instantiation: tcpcheck.c:xref_get_peer_and_lock Unexecuted instantiation: thread.c:xref_get_peer_and_lock Unexecuted instantiation: tools.c:xref_get_peer_and_lock Unexecuted instantiation: trace.c:xref_get_peer_and_lock Unexecuted instantiation: vars.c:xref_get_peer_and_lock Unexecuted instantiation: activity.c:xref_get_peer_and_lock Unexecuted instantiation: applet.c:xref_get_peer_and_lock Unexecuted instantiation: backend.c:xref_get_peer_and_lock Unexecuted instantiation: cfgparse-listen.c:xref_get_peer_and_lock Unexecuted instantiation: cfgparse.c:xref_get_peer_and_lock Unexecuted instantiation: channel.c:xref_get_peer_and_lock Unexecuted instantiation: check.c:xref_get_peer_and_lock Unexecuted instantiation: cli.c:xref_get_peer_and_lock Unexecuted instantiation: connection.c:xref_get_peer_and_lock Unexecuted instantiation: debug.c:xref_get_peer_and_lock Unexecuted instantiation: dns.c:xref_get_peer_and_lock Unexecuted instantiation: dns_ring.c:xref_get_peer_and_lock Unexecuted instantiation: errors.c:xref_get_peer_and_lock Unexecuted instantiation: extcheck.c:xref_get_peer_and_lock Unexecuted instantiation: fd.c:xref_get_peer_and_lock Unexecuted instantiation: filters.c:xref_get_peer_and_lock Unexecuted instantiation: flt_decomp.c:xref_get_peer_and_lock Unexecuted instantiation: flt_http_comp.c:xref_get_peer_and_lock Unexecuted instantiation: frontend.c:xref_get_peer_and_lock Unexecuted instantiation: haterm.c:xref_get_peer_and_lock Unexecuted instantiation: http_ana.c:xref_get_peer_and_lock Unexecuted instantiation: http_ext.c:xref_get_peer_and_lock Unexecuted instantiation: http_htx.c:xref_get_peer_and_lock Unexecuted instantiation: http_rules.c:xref_get_peer_and_lock Unexecuted instantiation: limits.c:xref_get_peer_and_lock Unexecuted instantiation: mux_spop.c:xref_get_peer_and_lock Unexecuted instantiation: pattern.c:xref_get_peer_and_lock Unexecuted instantiation: payload.c:xref_get_peer_and_lock Unexecuted instantiation: proto_rhttp.c:xref_get_peer_and_lock Unexecuted instantiation: queue.c:xref_get_peer_and_lock Unexecuted instantiation: stats-html.c:xref_get_peer_and_lock Unexecuted instantiation: stats-json.c:xref_get_peer_and_lock Unexecuted instantiation: stconn.c:xref_get_peer_and_lock Unexecuted instantiation: cache.c:xref_get_peer_and_lock Unexecuted instantiation: cfgparse-global.c:xref_get_peer_and_lock Unexecuted instantiation: compression.c:xref_get_peer_and_lock Unexecuted instantiation: fcgi-app.c:xref_get_peer_and_lock Unexecuted instantiation: flt_spoe.c:xref_get_peer_and_lock Unexecuted instantiation: http_fetch.c:xref_get_peer_and_lock Unexecuted instantiation: proto_tcp.c:xref_get_peer_and_lock |
87 | | |
88 | | static inline void xref_unlock(struct xref *xref, struct xref *peer) |
89 | 0 | { |
90 | | /* Release the peer. */ |
91 | 0 | peer->peer = xref; |
92 | |
|
93 | 0 | __ha_barrier_store(); |
94 | | |
95 | | /* Release myself. */ |
96 | 0 | xref->peer = peer; |
97 | 0 | } Unexecuted instantiation: haproxy.c:xref_unlock Unexecuted instantiation: listener.c:xref_unlock Unexecuted instantiation: log.c:xref_unlock Unexecuted instantiation: mworker.c:xref_unlock Unexecuted instantiation: peers.c:xref_unlock Unexecuted instantiation: pool.c:xref_unlock Unexecuted instantiation: proto_sockpair.c:xref_unlock Unexecuted instantiation: proxy.c:xref_unlock Unexecuted instantiation: resolvers.c:xref_unlock Unexecuted instantiation: ring.c:xref_unlock Unexecuted instantiation: sample.c:xref_unlock Unexecuted instantiation: server.c:xref_unlock Unexecuted instantiation: session.c:xref_unlock Unexecuted instantiation: sink.c:xref_unlock Unexecuted instantiation: sock.c:xref_unlock Unexecuted instantiation: stats-proxy.c:xref_unlock Unexecuted instantiation: stats.c:xref_unlock Unexecuted instantiation: stick_table.c:xref_unlock Unexecuted instantiation: stream.c:xref_unlock Unexecuted instantiation: tcp_rules.c:xref_unlock Unexecuted instantiation: tcpcheck.c:xref_unlock Unexecuted instantiation: thread.c:xref_unlock Unexecuted instantiation: tools.c:xref_unlock Unexecuted instantiation: trace.c:xref_unlock Unexecuted instantiation: vars.c:xref_unlock Unexecuted instantiation: activity.c:xref_unlock Unexecuted instantiation: applet.c:xref_unlock Unexecuted instantiation: backend.c:xref_unlock Unexecuted instantiation: cfgparse-listen.c:xref_unlock Unexecuted instantiation: cfgparse.c:xref_unlock Unexecuted instantiation: channel.c:xref_unlock Unexecuted instantiation: check.c:xref_unlock Unexecuted instantiation: cli.c:xref_unlock Unexecuted instantiation: connection.c:xref_unlock Unexecuted instantiation: debug.c:xref_unlock Unexecuted instantiation: dns.c:xref_unlock Unexecuted instantiation: dns_ring.c:xref_unlock Unexecuted instantiation: errors.c:xref_unlock Unexecuted instantiation: extcheck.c:xref_unlock Unexecuted instantiation: fd.c:xref_unlock Unexecuted instantiation: filters.c:xref_unlock Unexecuted instantiation: flt_decomp.c:xref_unlock Unexecuted instantiation: flt_http_comp.c:xref_unlock Unexecuted instantiation: frontend.c:xref_unlock Unexecuted instantiation: haterm.c:xref_unlock Unexecuted instantiation: http_ana.c:xref_unlock Unexecuted instantiation: http_ext.c:xref_unlock Unexecuted instantiation: http_htx.c:xref_unlock Unexecuted instantiation: http_rules.c:xref_unlock Unexecuted instantiation: limits.c:xref_unlock Unexecuted instantiation: mux_spop.c:xref_unlock Unexecuted instantiation: pattern.c:xref_unlock Unexecuted instantiation: payload.c:xref_unlock Unexecuted instantiation: proto_rhttp.c:xref_unlock Unexecuted instantiation: queue.c:xref_unlock Unexecuted instantiation: stats-html.c:xref_unlock Unexecuted instantiation: stats-json.c:xref_unlock Unexecuted instantiation: stconn.c:xref_unlock Unexecuted instantiation: cache.c:xref_unlock Unexecuted instantiation: cfgparse-global.c:xref_unlock Unexecuted instantiation: compression.c:xref_unlock Unexecuted instantiation: fcgi-app.c:xref_unlock Unexecuted instantiation: flt_spoe.c:xref_unlock Unexecuted instantiation: http_fetch.c:xref_unlock Unexecuted instantiation: proto_tcp.c:xref_unlock |
98 | | |
99 | | static inline void xref_disconnect(struct xref *xref, struct xref *peer) |
100 | 0 | { |
101 | 0 | peer->peer = NULL; |
102 | 0 | __ha_barrier_store(); |
103 | | xref->peer = NULL; |
104 | 0 | } Unexecuted instantiation: haproxy.c:xref_disconnect Unexecuted instantiation: listener.c:xref_disconnect Unexecuted instantiation: log.c:xref_disconnect Unexecuted instantiation: mworker.c:xref_disconnect Unexecuted instantiation: peers.c:xref_disconnect Unexecuted instantiation: pool.c:xref_disconnect Unexecuted instantiation: proto_sockpair.c:xref_disconnect Unexecuted instantiation: proxy.c:xref_disconnect Unexecuted instantiation: resolvers.c:xref_disconnect Unexecuted instantiation: ring.c:xref_disconnect Unexecuted instantiation: sample.c:xref_disconnect Unexecuted instantiation: server.c:xref_disconnect Unexecuted instantiation: session.c:xref_disconnect Unexecuted instantiation: sink.c:xref_disconnect Unexecuted instantiation: sock.c:xref_disconnect Unexecuted instantiation: stats-proxy.c:xref_disconnect Unexecuted instantiation: stats.c:xref_disconnect Unexecuted instantiation: stick_table.c:xref_disconnect Unexecuted instantiation: stream.c:xref_disconnect Unexecuted instantiation: tcp_rules.c:xref_disconnect Unexecuted instantiation: tcpcheck.c:xref_disconnect Unexecuted instantiation: thread.c:xref_disconnect Unexecuted instantiation: tools.c:xref_disconnect Unexecuted instantiation: trace.c:xref_disconnect Unexecuted instantiation: vars.c:xref_disconnect Unexecuted instantiation: activity.c:xref_disconnect Unexecuted instantiation: applet.c:xref_disconnect Unexecuted instantiation: backend.c:xref_disconnect Unexecuted instantiation: cfgparse-listen.c:xref_disconnect Unexecuted instantiation: cfgparse.c:xref_disconnect Unexecuted instantiation: channel.c:xref_disconnect Unexecuted instantiation: check.c:xref_disconnect Unexecuted instantiation: cli.c:xref_disconnect Unexecuted instantiation: connection.c:xref_disconnect Unexecuted instantiation: debug.c:xref_disconnect Unexecuted instantiation: dns.c:xref_disconnect Unexecuted instantiation: dns_ring.c:xref_disconnect Unexecuted instantiation: errors.c:xref_disconnect Unexecuted instantiation: extcheck.c:xref_disconnect Unexecuted instantiation: fd.c:xref_disconnect Unexecuted instantiation: filters.c:xref_disconnect Unexecuted instantiation: flt_decomp.c:xref_disconnect Unexecuted instantiation: flt_http_comp.c:xref_disconnect Unexecuted instantiation: frontend.c:xref_disconnect Unexecuted instantiation: haterm.c:xref_disconnect Unexecuted instantiation: http_ana.c:xref_disconnect Unexecuted instantiation: http_ext.c:xref_disconnect Unexecuted instantiation: http_htx.c:xref_disconnect Unexecuted instantiation: http_rules.c:xref_disconnect Unexecuted instantiation: limits.c:xref_disconnect Unexecuted instantiation: mux_spop.c:xref_disconnect Unexecuted instantiation: pattern.c:xref_disconnect Unexecuted instantiation: payload.c:xref_disconnect Unexecuted instantiation: proto_rhttp.c:xref_disconnect Unexecuted instantiation: queue.c:xref_disconnect Unexecuted instantiation: stats-html.c:xref_disconnect Unexecuted instantiation: stats-json.c:xref_disconnect Unexecuted instantiation: stconn.c:xref_disconnect Unexecuted instantiation: cache.c:xref_disconnect Unexecuted instantiation: cfgparse-global.c:xref_disconnect Unexecuted instantiation: compression.c:xref_disconnect Unexecuted instantiation: fcgi-app.c:xref_disconnect Unexecuted instantiation: flt_spoe.c:xref_disconnect Unexecuted instantiation: http_fetch.c:xref_disconnect Unexecuted instantiation: proto_tcp.c:xref_disconnect |
105 | | |
106 | | #endif /* __HAPROXY_XREF_H__ */ |