File Coverage

Shared.xs
Criterion Covered Total %
statement 72 80 90.0
branch 72 154 46.7
condition n/a
subroutine n/a
pod n/a
total 144 234 61.5


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 51 50         EXTRACT_LOG(self);
    50          
    50          
82             CODE:
83             STRLEN len;
84 51           const char *buf = SvPV(data, len);
85 51 100         if (len == 0) croak("append: data must not be empty");
86 50 50         if (len > (STRLEN)(UINT32_MAX - LOG_ENTRY_HDR))
87 0           croak("append: data too large");
88 50           int64_t off = log_append(h, buf, (uint32_t)len);
89 50 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 215 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 215 100         if (log_read(h, offset, &out_data, &out_len, &next_off)) {
104 211 50         EXTEND(SP, 2);
105 211           PUSHs(sv_2mortal(newSVpvn((const char *)out_data, out_len)));
106 211           PUSHs(sv_2mortal(newSVuv((UV)next_off)));
107             }
108              
109             UV
110             tail_offset(self)
111             SV *self
112             PREINIT:
113 2 50         EXTRACT_LOG(self);
    50          
    50          
114             CODE:
115 2           RETVAL = (UV)log_tail_offset(h);
116             OUTPUT:
117             RETVAL
118              
119             UV
120             entry_count(self)
121             SV *self
122             PREINIT:
123 8 50         EXTRACT_LOG(self);
    50          
    50          
124             CODE:
125 8           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 5 50         EXTRACT_LOG(self);
    50          
    50          
167             CODE:
168 5           log_reset(h);
169              
170             SV *
171             path(self)
172             SV *self
173             PREINIT:
174 1 50         EXTRACT_LOG(self);
    50          
    50          
175             CODE:
176 1 50         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
177             OUTPUT:
178             RETVAL
179              
180             IV
181             memfd(self)
182             SV *self
183             PREINIT:
184 1 50         EXTRACT_LOG(self);
    50          
    50          
185             CODE:
186 1 50         RETVAL = h->backing_fd;
187             OUTPUT:
188             RETVAL
189              
190             IV
191             eventfd(self)
192             SV *self
193             PREINIT:
194 1 50         EXTRACT_LOG(self);
    50          
    50          
195             CODE:
196 1 50         RETVAL = log_create_eventfd(h);
197             OUTPUT:
198             RETVAL
199              
200             void
201             eventfd_set(self, fd)
202             SV *self
203             int fd
204             PREINIT:
205 0 0         EXTRACT_LOG(self);
    0          
    0          
206             CODE:
207 0 0         if (h->notify_fd >= 0 && h->notify_fd != fd) close(h->notify_fd);
    0          
208 0           h->notify_fd = fd;
209              
210             IV
211             fileno(self)
212             SV *self
213             PREINIT:
214 0 0         EXTRACT_LOG(self);
    0          
    0          
215             CODE:
216 0 0         RETVAL = h->notify_fd;
217             OUTPUT:
218             RETVAL
219              
220             bool
221             notify(self)
222             SV *self
223             PREINIT:
224 1 50         EXTRACT_LOG(self);
    50          
    50          
225             CODE:
226 1 50         RETVAL = log_notify(h);
227             OUTPUT:
228             RETVAL
229              
230             SV *
231             eventfd_consume(self)
232             SV *self
233             PREINIT:
234 1 50         EXTRACT_LOG(self);
    50          
    50          
235             CODE:
236 1           int64_t v = log_eventfd_consume(h);
237 1 50         RETVAL = (v >= 0) ? newSViv((IV)v) : &PL_sv_undef;
238             OUTPUT:
239             RETVAL
240              
241             void
242             sync(self)
243             SV *self
244             PREINIT:
245 1 50         EXTRACT_LOG(self);
    50          
    50          
246             CODE:
247 1           log_msync(h);
248              
249             void
250             unlink(self_or_class, ...)
251             SV *self_or_class
252             CODE:
253             const char *p;
254 1 50         if (sv_isobject(self_or_class)) {
255 1           LogHandle *h = INT2PTR(LogHandle*, SvIV(SvRV(self_or_class)));
256 1 50         if (!h) croak("destroyed object");
257 1           p = h->path;
258             } else {
259 0 0         if (items < 2) croak("Usage: ...->unlink($path)");
260 0           p = SvPV_nolen(ST(1));
261             }
262 1 50         if (!p) croak("cannot unlink anonymous or memfd object");
263 1 50         if (unlink(p) != 0) croak("unlink(%s): %s", p, strerror(errno));
264              
265             SV *
266             stats(self)
267             SV *self
268             PREINIT:
269 1 50         EXTRACT_LOG(self);
    50          
    50          
270             CODE:
271 1           HV *hv = newHV();
272 1           LogHeader *hdr = h->hdr;
273 1           hv_store(hv, "data_size", 9, newSVuv((UV)hdr->data_size), 0);
274 1           hv_store(hv, "tail", 4, newSVuv((UV)log_tail_offset(h)), 0);
275 1           hv_store(hv, "count", 5, newSVuv((UV)log_entry_count(h)), 0);
276 1           hv_store(hv, "available", 9, newSVuv((UV)log_available(h)), 0);
277 1           hv_store(hv, "waiters", 7, newSVuv(hdr->waiters), 0);
278 1           hv_store(hv, "appends", 7, newSVuv((UV)hdr->stat_appends), 0);
279 1           hv_store(hv, "waits", 5, newSVuv((UV)hdr->stat_waits), 0);
280 1           hv_store(hv, "timeouts", 8, newSVuv((UV)hdr->stat_timeouts), 0);
281 1           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
282 1           RETVAL = newRV_noinc((SV *)hv);
283             OUTPUT:
284             RETVAL