Coverage Report

Created: 2026-09-01 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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__ */