/src/haproxy/include/haproxy/ring.h
Line | Count | Source |
1 | | /* |
2 | | * include/haproxy/ring.h |
3 | | * Exported functions for ring buffers used for disposable data. |
4 | | * |
5 | | * Copyright (C) 2000-2019 Willy Tarreau - w@1wt.eu |
6 | | * |
7 | | * This library is free software; you can redistribute it and/or |
8 | | * modify it under the terms of the GNU Lesser General Public |
9 | | * License as published by the Free Software Foundation, version 2.1 |
10 | | * exclusively. |
11 | | * |
12 | | * This library is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | | * Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public |
18 | | * License along with this library; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | | */ |
21 | | |
22 | | #ifndef _HAPROXY_RING_H |
23 | | #define _HAPROXY_RING_H |
24 | | |
25 | | #include <stdlib.h> |
26 | | #include <import/ist.h> |
27 | | #include <haproxy/ring-t.h> |
28 | | #include <haproxy/vecpair.h> |
29 | | |
30 | | struct appctx; |
31 | | |
32 | | struct ring *ring_new(size_t size); |
33 | | struct ring *ring_make_from_area(void *area, size_t size, int reset); |
34 | | void ring_init(struct ring *ring, void *area, size_t size, int reset); |
35 | | struct ring *ring_resize(struct ring *ring, size_t size); |
36 | | void ring_free(struct ring *ring); |
37 | | ssize_t ring_write(struct ring *ring, size_t maxlen, const struct ist pfx[], size_t npfx, const struct ist msg[], size_t nmsg); |
38 | | int ring_attach(struct ring *ring); |
39 | | void ring_detach_appctx(struct ring *ring, struct appctx *appctx, size_t ofs); |
40 | | int ring_attach_cli(struct ring *ring, struct appctx *appctx, uint flags); |
41 | | int cli_io_handler_show_ring(struct appctx *appctx); |
42 | | void cli_io_release_show_ring(struct appctx *appctx); |
43 | | |
44 | | size_t ring_max_payload(const struct ring *ring); |
45 | | int ring_dispatch_messages(struct ring *ring, void *ctx, size_t *ofs_ptr, size_t *last_ofs_ptr, uint flags, |
46 | | ssize_t (*msg_handler)(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len, char delim), |
47 | | char delim, |
48 | | size_t *processed); |
49 | | |
50 | | /* returns the ring storage's usable area */ |
51 | | static inline void *ring_area(const struct ring *ring) |
52 | 0 | { |
53 | 0 | return ring->storage->area; |
54 | 0 | } Unexecuted instantiation: errors.c:ring_area Unexecuted instantiation: mworker.c:ring_area Unexecuted instantiation: ring.c:ring_area Unexecuted instantiation: sink.c:ring_area |
55 | | |
56 | | /* returns the allocated area for the ring. It covers the whole |
57 | | * area made of both the ring_storage and the usable area. |
58 | | */ |
59 | | static inline void *ring_allocated_area(const struct ring *ring) |
60 | 0 | { |
61 | 0 | return ring->storage; |
62 | 0 | } Unexecuted instantiation: errors.c:ring_allocated_area Unexecuted instantiation: mworker.c:ring_allocated_area Unexecuted instantiation: ring.c:ring_allocated_area Unexecuted instantiation: sink.c:ring_allocated_area |
63 | | |
64 | | /* returns the number of bytes in the ring */ |
65 | | static inline size_t ring_data(const struct ring *ring) |
66 | 0 | { |
67 | 0 | size_t tail = HA_ATOMIC_LOAD(&ring->storage->tail) & ~RING_TAIL_LOCK; |
68 | |
|
69 | 0 | return ((ring->storage->head <= tail) ? |
70 | 0 | 0 : ring->storage->size) + tail - ring->storage->head; |
71 | 0 | } Unexecuted instantiation: errors.c:ring_data Unexecuted instantiation: mworker.c:ring_data Unexecuted instantiation: ring.c:ring_data Unexecuted instantiation: sink.c:ring_data |
72 | | |
73 | | /* returns the usable size in bytes for the ring. It is smaller than |
74 | | * the allocate size by the size of the ring_storage header. |
75 | | */ |
76 | | static inline size_t ring_size(const struct ring *ring) |
77 | 0 | { |
78 | 0 | return ring->storage->size; |
79 | 0 | } Unexecuted instantiation: errors.c:ring_size Unexecuted instantiation: mworker.c:ring_size Unexecuted instantiation: ring.c:ring_size Unexecuted instantiation: sink.c:ring_size |
80 | | |
81 | | /* returns the allocated size in bytes for the ring. It covers the whole |
82 | | * area made of both the ring_storage and the usable area. |
83 | | */ |
84 | | static inline size_t ring_allocated_size(const struct ring *ring) |
85 | 0 | { |
86 | 0 | return ring->storage->size + ring->storage->rsvd; |
87 | 0 | } Unexecuted instantiation: errors.c:ring_allocated_size Unexecuted instantiation: mworker.c:ring_allocated_size Unexecuted instantiation: ring.c:ring_allocated_size Unexecuted instantiation: sink.c:ring_allocated_size |
88 | | |
89 | | /* returns the head offset of the ring */ |
90 | | static inline size_t ring_head(const struct ring *ring) |
91 | 0 | { |
92 | 0 | return ring->storage->head; |
93 | 0 | } Unexecuted instantiation: errors.c:ring_head Unexecuted instantiation: mworker.c:ring_head Unexecuted instantiation: ring.c:ring_head Unexecuted instantiation: sink.c:ring_head |
94 | | |
95 | | /* returns the ring's tail offset without the lock bit */ |
96 | | static inline size_t ring_tail(const struct ring *ring) |
97 | 0 | { |
98 | 0 | return HA_ATOMIC_LOAD(&ring->storage->tail) & ~RING_TAIL_LOCK; |
99 | 0 | } Unexecuted instantiation: errors.c:ring_tail Unexecuted instantiation: mworker.c:ring_tail Unexecuted instantiation: ring.c:ring_tail Unexecuted instantiation: sink.c:ring_tail |
100 | | |
101 | | /* duplicates ring <src> over ring <dst> for no more than <max> bytes or no |
102 | | * more than the amount of data present in <src>. It's assumed that the |
103 | | * destination ring is always large enough for <max>. The number of bytes |
104 | | * copied (the min of src's size and max) is returned. |
105 | | */ |
106 | | static inline size_t ring_dup(struct ring *dst, const struct ring *src, size_t max) |
107 | 0 | { |
108 | 0 | struct ist v1, v2; |
109 | |
|
110 | 0 | vp_ring_to_data(&v1, &v2, ring_area(src), ring_size(src), ring_head(src), ring_tail(src)); |
111 | |
|
112 | 0 | if (max > ring_data(src)) |
113 | 0 | max = ring_data(src); |
114 | |
|
115 | 0 | BUG_ON(max > ring_size(dst)); |
116 | |
|
117 | 0 | vp_peek_ofs(v1, v2, 0, ring_area(dst), max); |
118 | 0 | dst->storage->head = 0; |
119 | 0 | dst->storage->tail = max; |
120 | 0 | return max; |
121 | 0 | } Unexecuted instantiation: errors.c:ring_dup Unexecuted instantiation: mworker.c:ring_dup Unexecuted instantiation: ring.c:ring_dup Unexecuted instantiation: sink.c:ring_dup |
122 | | |
123 | | #endif /* _HAPROXY_RING_H */ |
124 | | |
125 | | /* |
126 | | * Local variables: |
127 | | * c-indent-level: 8 |
128 | | * c-basic-offset: 8 |
129 | | * End: |
130 | | */ |