File Coverage

Shared.xs
Criterion Covered Total %
statement 76 84 90.4
branch 78 166 46.9
condition n/a
subroutine n/a
pod n/a
total 154 250 61.6


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5             #include "ppport.h"
6             #include "log.h"
7              
8             #define EXTRACT_LOG(sv) \
9             if (!sv_isobject(sv) || !sv_derived_from(sv, "Data::Log::Shared")) \
10             croak("Expected a Data::Log::Shared object"); \
11             LogHandle *h = INT2PTR(LogHandle*, SvIV(SvRV(sv))); \
12             if (!h) croak("Attempted to use a destroyed Data::Log::Shared object")
13              
14             #define MAKE_OBJ(class, handle) \
15             SV *obj = newSViv(PTR2IV(handle)); \
16             SV *ref = newRV_noinc(obj); \
17             sv_bless(ref, gv_stashpv(class, GV_ADD)); \
18             RETVAL = ref
19              
20             MODULE = Data::Log::Shared PACKAGE = Data::Log::Shared
21              
22             PROTOTYPES: DISABLE
23              
24             SV *
25             new(class, path, data_size)
26             const char *class
27             SV *path
28             UV data_size
29             PREINIT:
30             char errbuf[LOG_ERR_BUFLEN];
31             CODE:
32 5 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
33 5           LogHandle *h = log_create(p, data_size, errbuf);
34 5 50         if (!h) croak("Data::Log::Shared->new: %s", errbuf);
35 5           MAKE_OBJ(class, h);
36             OUTPUT:
37             RETVAL
38              
39             SV *
40             new_memfd(class, name, data_size)
41             const char *class
42             const char *name
43             UV data_size
44             PREINIT:
45             char errbuf[LOG_ERR_BUFLEN];
46             CODE:
47 1           LogHandle *h = log_create_memfd(name, data_size, errbuf);
48 1 50         if (!h) croak("Data::Log::Shared->new_memfd: %s", errbuf);
49 1           MAKE_OBJ(class, h);
50             OUTPUT:
51             RETVAL
52              
53             SV *
54             new_from_fd(class, fd)
55             const char *class
56             int fd
57             PREINIT:
58             char errbuf[LOG_ERR_BUFLEN];
59             CODE:
60 1           LogHandle *h = log_open_fd(fd, errbuf);
61 1 50         if (!h) croak("Data::Log::Shared->new_from_fd: %s", errbuf);
62 1           MAKE_OBJ(class, h);
63             OUTPUT:
64             RETVAL
65              
66             void
67             DESTROY(self)
68             SV *self
69             CODE:
70 7 50         if (!SvROK(self)) return;
71 7           LogHandle *h = INT2PTR(LogHandle*, SvIV(SvRV(self)));
72 7 50         if (!h) return;
73 7           sv_setiv(SvRV(self), 0);
74 7           log_destroy(h);
75              
76             SV *
77             append(self, data)
78             SV *self
79             SV *data
80             PREINIT:
81 58 50         EXTRACT_LOG(self);
    50          
    50          
82             CODE:
83             STRLEN len;
84 58           const char *buf = SvPV(data, len);
85 58 100         if (len == 0) croak("append: data must not be empty");
86 57 50         if (len > (STRLEN)(UINT32_MAX - LOG_ENTRY_HDR))
87 0           croak("append: data too large");
88 57           int64_t off = log_append(h, buf, (uint32_t)len);
89 57 100         RETVAL = (off >= 0) ? newSViv((IV)off) : &PL_sv_undef;
90             OUTPUT:
91             RETVAL
92              
93             void
94             read_entry(self, offset)
95             SV *self
96             UV offset
97             PREINIT:
98 225 50         EXTRACT_LOG(self);
    50          
    50          
99             PPCODE:
100             const uint8_t *out_data;
101             uint32_t out_len;
102             uint64_t next_off;
103 225 100         if (log_read(h, offset, &out_data, &out_len, &next_off)) {
104 217 50         EXTEND(SP, 2);
105 217           PUSHs(sv_2mortal(newSVpvn((const char *)out_data, out_len)));
106 217           PUSHs(sv_2mortal(newSVuv((UV)next_off)));
107             }
108              
109             UV
110             tail_offset(self)
111             SV *self
112             PREINIT:
113 3 50         EXTRACT_LOG(self);
    50          
    50          
114             CODE:
115 3           RETVAL = (UV)log_tail_offset(h);
116             OUTPUT:
117             RETVAL
118              
119             UV
120             entry_count(self)
121             SV *self
122             PREINIT:
123 10 50         EXTRACT_LOG(self);
    50          
    50          
124             CODE:
125 10           RETVAL = (UV)log_entry_count(h);
126             OUTPUT:
127             RETVAL
128              
129             UV
130             data_size(self)
131             SV *self
132             PREINIT:
133 1 50         EXTRACT_LOG(self);
    50          
    50          
134             CODE:
135 1           RETVAL = (UV)log_data_size(h);
136             OUTPUT:
137             RETVAL
138              
139             UV
140             available(self)
141             SV *self
142             PREINIT:
143 1 50         EXTRACT_LOG(self);
    50          
    50          
144             CODE:
145 1           RETVAL = (UV)log_available(h);
146             OUTPUT:
147             RETVAL
148              
149             bool
150             wait_for(self, expected_count, ...)
151             SV *self
152             UV expected_count
153             PREINIT:
154 2 50         EXTRACT_LOG(self);
    50          
    50          
155 2           double timeout = -1;
156             CODE:
157 2 50         if (items > 2) timeout = SvNV(ST(2));
158 2 100         RETVAL = log_wait(h, expected_count, timeout);
159             OUTPUT:
160             RETVAL
161              
162             void
163             reset(self)
164             SV *self
165             PREINIT:
166 7 50         EXTRACT_LOG(self);
    50          
    50          
167             CODE:
168 7           log_reset(h);
169              
170             void
171             truncate(self, offset)
172             SV *self
173             UV offset
174             PREINIT:
175 3 50         EXTRACT_LOG(self);
    50          
    50          
176             CODE:
177 3           log_truncate(h, (uint64_t)offset);
178              
179             UV
180             truncation(self)
181             SV *self
182             PREINIT:
183 10 50         EXTRACT_LOG(self);
    50          
    50          
184             CODE:
185 10           RETVAL = (UV)log_truncation(h);
186             OUTPUT:
187             RETVAL
188              
189             SV *
190             path(self)
191             SV *self
192             PREINIT:
193 1 50         EXTRACT_LOG(self);
    50          
    50          
194             CODE:
195 1 50         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
196             OUTPUT:
197             RETVAL
198              
199             IV
200             memfd(self)
201             SV *self
202             PREINIT:
203 1 50         EXTRACT_LOG(self);
    50          
    50          
204             CODE:
205 1 50         RETVAL = h->backing_fd;
206             OUTPUT:
207             RETVAL
208              
209             IV
210             eventfd(self)
211             SV *self
212             PREINIT:
213 1 50         EXTRACT_LOG(self);
    50          
    50          
214             CODE:
215 1 50         RETVAL = log_create_eventfd(h);
216             OUTPUT:
217             RETVAL
218              
219             void
220             eventfd_set(self, fd)
221             SV *self
222             int fd
223             PREINIT:
224 0 0         EXTRACT_LOG(self);
    0          
    0          
225             CODE:
226 0 0         if (h->notify_fd >= 0 && h->notify_fd != fd) close(h->notify_fd);
    0          
227 0           h->notify_fd = fd;
228              
229             IV
230             fileno(self)
231             SV *self
232             PREINIT:
233 0 0         EXTRACT_LOG(self);
    0          
    0          
234             CODE:
235 0 0         RETVAL = h->notify_fd;
236             OUTPUT:
237             RETVAL
238              
239             bool
240             notify(self)
241             SV *self
242             PREINIT:
243 1 50         EXTRACT_LOG(self);
    50          
    50          
244             CODE:
245 1 50         RETVAL = log_notify(h);
246             OUTPUT:
247             RETVAL
248              
249             SV *
250             eventfd_consume(self)
251             SV *self
252             PREINIT:
253 1 50         EXTRACT_LOG(self);
    50          
    50          
254             CODE:
255 1           int64_t v = log_eventfd_consume(h);
256 1 50         RETVAL = (v >= 0) ? newSViv((IV)v) : &PL_sv_undef;
257             OUTPUT:
258             RETVAL
259              
260             void
261             sync(self)
262             SV *self
263             PREINIT:
264 1 50         EXTRACT_LOG(self);
    50          
    50          
265             CODE:
266 1           log_msync(h);
267              
268             void
269             unlink(self_or_class, ...)
270             SV *self_or_class
271             CODE:
272             const char *p;
273 1 50         if (sv_isobject(self_or_class)) {
274 1           LogHandle *h = INT2PTR(LogHandle*, SvIV(SvRV(self_or_class)));
275 1 50         if (!h) croak("destroyed object");
276 1           p = h->path;
277             } else {
278 0 0         if (items < 2) croak("Usage: ...->unlink($path)");
279 0           p = SvPV_nolen(ST(1));
280             }
281 1 50         if (!p) croak("cannot unlink anonymous or memfd object");
282 1 50         if (unlink(p) != 0) croak("unlink(%s): %s", p, strerror(errno));
283              
284             SV *
285             stats(self)
286             SV *self
287             PREINIT:
288 1 50         EXTRACT_LOG(self);
    50          
    50          
289             CODE:
290 1           HV *hv = newHV();
291 1           LogHeader *hdr = h->hdr;
292 1           hv_store(hv, "data_size", 9, newSVuv((UV)hdr->data_size), 0);
293 1           hv_store(hv, "tail", 4, newSVuv((UV)log_tail_offset(h)), 0);
294 1           hv_store(hv, "count", 5, newSVuv((UV)log_entry_count(h)), 0);
295 1           hv_store(hv, "available", 9, newSVuv((UV)log_available(h)), 0);
296 1           hv_store(hv, "waiters", 7, newSVuv(hdr->waiters), 0);
297 1           hv_store(hv, "appends", 7, newSVuv((UV)hdr->stat_appends), 0);
298 1           hv_store(hv, "waits", 5, newSVuv((UV)hdr->stat_waits), 0);
299 1           hv_store(hv, "timeouts", 8, newSVuv((UV)hdr->stat_timeouts), 0);
300 1           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
301 1           RETVAL = newRV_noinc((SV *)hv);
302             OUTPUT:
303             RETVAL