File Coverage

Shared.xs
Criterion Covered Total %
statement 383 464 82.5
branch 358 900 39.7
condition n/a
subroutine n/a
pod n/a
total 741 1364 54.3


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              
6             #include "ppport.h"
7             #include "reqrep.h"
8              
9             #define EXTRACT_HANDLE(classname, sv) \
10             if (!sv_isobject(sv) || !sv_derived_from(sv, classname)) \
11             croak("Expected a %s object", classname); \
12             ReqRepHandle *h = INT2PTR(ReqRepHandle*, SvIV(SvRV(sv))); \
13             if (!h) croak("Attempted to use a destroyed %s object", classname)
14              
15             #define MAKE_OBJ(class, ptr) \
16             SV *obj = newSViv(PTR2IV(ptr)); \
17             SV *ref = newRV_noinc(obj); \
18             sv_bless(ref, gv_stashpv(class, GV_ADD))
19              
20             MODULE = Data::ReqRep::Shared PACKAGE = Data::ReqRep::Shared
21              
22             PROTOTYPES: DISABLE
23              
24             SV *
25             new(class, path, req_cap, resp_slots, resp_size, ...)
26             const char *class
27             SV *path
28             UV req_cap
29             UV resp_slots
30             UV resp_size
31             PREINIT:
32             char errbuf[REQREP_ERR_BUFLEN];
33             uint64_t arena_cap;
34             CODE:
35 47 100         arena_cap = (items > 5) ? (uint64_t)SvUV(ST(5)) : 0;
36 47 50         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
37 47           ReqRepHandle *h = reqrep_create(p, (uint32_t)req_cap, (uint32_t)resp_slots,
38             (uint32_t)resp_size, arena_cap, errbuf);
39 47 50         if (!h) croak("Data::ReqRep::Shared->new: %s", errbuf);
40 47           MAKE_OBJ(class, h);
41 47           RETVAL = ref;
42             OUTPUT:
43             RETVAL
44              
45             SV *
46             new_memfd(class, name, req_cap, resp_slots, resp_size, ...)
47             const char *class
48             const char *name
49             UV req_cap
50             UV resp_slots
51             UV resp_size
52             PREINIT:
53             char errbuf[REQREP_ERR_BUFLEN];
54             uint64_t arena_cap;
55             CODE:
56 3 50         arena_cap = (items > 5) ? (uint64_t)SvUV(ST(5)) : 0;
57 3           ReqRepHandle *h = reqrep_create_memfd(name, (uint32_t)req_cap, (uint32_t)resp_slots,
58             (uint32_t)resp_size, arena_cap, errbuf);
59 3 50         if (!h) croak("Data::ReqRep::Shared->new_memfd: %s", errbuf);
60 3           MAKE_OBJ(class, h);
61 3           RETVAL = ref;
62             OUTPUT:
63             RETVAL
64              
65             SV *
66             new_from_fd(class, fd)
67             const char *class
68             int fd
69             PREINIT:
70             char errbuf[REQREP_ERR_BUFLEN];
71             CODE:
72 1           ReqRepHandle *h = reqrep_open_fd(fd, REQREP_MODE_STR, errbuf);
73 1 50         if (!h) croak("Data::ReqRep::Shared->new_from_fd: %s", errbuf);
74 1           MAKE_OBJ(class, h);
75 1           RETVAL = ref;
76             OUTPUT:
77             RETVAL
78              
79             IV
80             memfd(self)
81             SV *self
82             PREINIT:
83 3 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
84             CODE:
85 3 50         RETVAL = h->backing_fd;
86             OUTPUT:
87             RETVAL
88              
89             void
90             DESTROY(self)
91             SV *self
92             PREINIT:
93 51 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
94             CODE:
95 51           sv_setiv(SvRV(self), 0);
96 51           reqrep_destroy(h);
97              
98             void
99             recv(self)
100             SV *self
101             PREINIT:
102 91 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
103             const char *str;
104             uint32_t len;
105             uint64_t id;
106             bool utf8;
107             PPCODE:
108 91           int r = reqrep_try_recv(h, &str, &len, &utf8, &id);
109 91 50         if (r == -1) croak("Data::ReqRep::Shared: out of memory");
110 91 100         if (r == 1) {
111 81           SV *sv = newSVpvn(str, len);
112 81 100         if (utf8) SvUTF8_on(sv);
113 81 50         mXPUSHs(sv);
114 81 50         mXPUSHu((UV)id);
115             }
116              
117             void
118             recv_wait(self, ...)
119             SV *self
120             PREINIT:
121 2152 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
122 2152           double timeout = -1;
123             const char *str;
124             uint32_t len;
125             uint64_t id;
126             bool utf8;
127             PPCODE:
128 2152 50         if (items > 1) timeout = SvNV(ST(1));
129 2152           int r = reqrep_recv_wait(h, &str, &len, &utf8, &id, timeout);
130 2152 50         if (r == -1) croak("Data::ReqRep::Shared: out of memory");
131 2152 100         if (r == 1) {
132 2148           SV *sv = newSVpvn(str, len);
133 2148 50         if (utf8) SvUTF8_on(sv);
134 2148 50         mXPUSHs(sv);
135 2148 50         mXPUSHu((UV)id);
136             }
137              
138             void
139             recv_multi(self, count)
140             SV *self
141             UV count
142             PREINIT:
143 6 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
144             const char *str;
145             uint32_t len;
146             uint64_t id;
147             bool utf8;
148             PPCODE:
149 6           int last_r = 0;
150 6           reqrep_mutex_lock(h->hdr);
151 16 100         for (UV i = 0; i < count; i++) {
152 14           last_r = reqrep_recv_locked(h, &str, &len, &utf8, &id);
153 14 100         if (last_r <= 0) break;
154 10           SV *sv = newSVpvn(str, len);
155 10 50         if (utf8) SvUTF8_on(sv);
156 10 50         mXPUSHs(sv);
157 10 50         mXPUSHu((UV)id);
158             }
159 6           reqrep_mutex_unlock(h->hdr);
160 6           reqrep_wake_producers(h->hdr);
161 6 50         if (last_r == -1) croak("Data::ReqRep::Shared: out of memory");
162              
163             void
164             recv_wait_multi(self, count, ...)
165             SV *self
166             UV count
167             PREINIT:
168 2 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
169 2           double timeout = -1;
170             const char *str;
171             uint32_t len;
172             uint64_t id;
173             bool utf8;
174             PPCODE:
175 2 50         if (items > 2) timeout = SvNV(ST(2));
176             /* Block until at least 1 */
177 2           int r = reqrep_recv_wait(h, &str, &len, &utf8, &id, timeout);
178 2 50         if (r == -1) croak("Data::ReqRep::Shared: out of memory");
179 2 100         if (r != 1) XSRETURN(0);
180             {
181 1           SV *sv = newSVpvn(str, len);
182 1 50         if (utf8) SvUTF8_on(sv);
183 1 50         mXPUSHs(sv);
184 1 50         mXPUSHu((UV)id);
185             }
186             /* Grab up to count-1 more non-blocking */
187 1           reqrep_mutex_lock(h->hdr);
188 4 50         for (UV i = 1; i < count; i++) {
189 4           int r2 = reqrep_recv_locked(h, &str, &len, &utf8, &id);
190 4 100         if (r2 <= 0) break;
191 3           SV *sv = newSVpvn(str, len);
192 3 50         if (utf8) SvUTF8_on(sv);
193 3 50         mXPUSHs(sv);
194 3 50         mXPUSHu((UV)id);
195             }
196 1           reqrep_mutex_unlock(h->hdr);
197 1           reqrep_wake_producers(h->hdr);
198              
199             void
200             drain(self, ...)
201             SV *self
202             PREINIT:
203 2 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
204             const char *str;
205             uint32_t len;
206             uint64_t id;
207             bool utf8;
208             uint32_t max_count;
209             PPCODE:
210 2 100         max_count = (items > 1) ? (uint32_t)SvUV(ST(1)) : UINT32_MAX;
211 2           reqrep_mutex_lock(h->hdr);
212 11 100         while (max_count-- > 0) {
213 10           int r = reqrep_recv_locked(h, &str, &len, &utf8, &id);
214 10 100         if (r <= 0) break;
215 9           SV *sv = newSVpvn(str, len);
216 9 50         if (utf8) SvUTF8_on(sv);
217 9 50         mXPUSHs(sv);
218 9 50         mXPUSHu((UV)id);
219             }
220 2           reqrep_mutex_unlock(h->hdr);
221 2           reqrep_wake_producers(h->hdr);
222              
223             bool
224             reply(self, id, value)
225             SV *self
226             UV id
227             SV *value
228             PREINIT:
229 2249 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
230             STRLEN len;
231             CODE:
232 2249           const char *str = SvPV(value, len);
233 2249           bool utf8 = SvUTF8(value) ? true : false;
234 2249           int r = reqrep_reply(h, (uint64_t)id, str, (uint32_t)len, utf8);
235 2249 50         if (r == -1) croak("Data::ReqRep::Shared: invalid slot index");
236 2249 100         if (r == -3) croak("Data::ReqRep::Shared: response too long (max %u bytes)", h->resp_data_max);
237 2248 100         RETVAL = (r == 1);
238             OUTPUT:
239             RETVAL
240              
241             UV
242             size(self)
243             SV *self
244             PREINIT:
245 23 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
246             CODE:
247 23           RETVAL = (UV)reqrep_size(h);
248             OUTPUT:
249             RETVAL
250              
251             UV
252             capacity(self)
253             SV *self
254             PREINIT:
255 4 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
256             CODE:
257 4 50         RETVAL = h->req_cap;
258             OUTPUT:
259             RETVAL
260              
261             UV
262             resp_slots(self)
263             SV *self
264             PREINIT:
265 4 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
266             CODE:
267 4 50         RETVAL = h->resp_slots;
268             OUTPUT:
269             RETVAL
270              
271             UV
272             resp_size(self)
273             SV *self
274             PREINIT:
275 4 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
276             CODE:
277 4 50         RETVAL = h->resp_data_max;
278             OUTPUT:
279             RETVAL
280              
281             bool
282             is_empty(self)
283             SV *self
284             PREINIT:
285 4 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
286             CODE:
287 4 50         RETVAL = (reqrep_size(h) == 0);
288             OUTPUT:
289             RETVAL
290              
291             void
292             clear(self)
293             SV *self
294             PREINIT:
295 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
296             CODE:
297 1           reqrep_clear(h);
298              
299             void
300             unlink(self_or_class, ...)
301             SV *self_or_class
302             CODE:
303             const char *path;
304 29 50         if (sv_isobject(self_or_class)) {
305 29           ReqRepHandle *h = INT2PTR(ReqRepHandle*, SvIV(SvRV(self_or_class)));
306 29 50         if (!h) croak("Attempted to use a destroyed object");
307 29           path = h->path;
308             } else {
309 0 0         if (items < 2) croak("Usage: Data::ReqRep::Shared->unlink($path)");
310 0           path = SvPV_nolen(ST(1));
311             }
312 29 50         if (!path) croak("cannot unlink anonymous or memfd channel");
313 29 50         if (unlink(path) != 0)
314 0           croak("unlink(%s): %s", path, strerror(errno));
315              
316             SV *
317             path(self)
318             SV *self
319             PREINIT:
320 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    0          
    0          
321             CODE:
322 0 0         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
323             OUTPUT:
324             RETVAL
325              
326             SV *
327             stats(self)
328             SV *self
329             PREINIT:
330 3 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
331             CODE:
332 3           HV *hv = newHV();
333 3           ReqRepHeader *hdr = h->hdr;
334 3           hv_store(hv, "size", 4, newSVuv((UV)reqrep_size(h)), 0);
335 3           hv_store(hv, "capacity", 8, newSVuv(h->req_cap), 0);
336 3           hv_store(hv, "resp_slots", 10, newSVuv(h->resp_slots), 0);
337 3           hv_store(hv, "resp_data_max", 13, newSVuv(h->resp_data_max), 0);
338 3           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
339 3           hv_store(hv, "arena_cap", 9, newSVuv(h->req_arena_cap), 0);
340 3           hv_store(hv, "arena_used", 10, newSVuv(hdr->arena_used), 0);
341 3           hv_store(hv, "requests", 8, newSVuv((UV)hdr->stat_requests), 0);
342 3           hv_store(hv, "replies", 7, newSVuv((UV)hdr->stat_replies), 0);
343 3           hv_store(hv, "send_full", 9, newSVuv((UV)hdr->stat_send_full), 0);
344 3           hv_store(hv, "recv_empty", 10, newSVuv(hdr->stat_recv_empty), 0);
345 3           hv_store(hv, "recoveries", 10, newSVuv(hdr->stat_recoveries), 0);
346 3           hv_store(hv, "recv_waiters", 12, newSVuv(hdr->recv_waiters), 0);
347 3           hv_store(hv, "send_waiters", 12, newSVuv(hdr->send_waiters), 0);
348 3           hv_store(hv, "slot_waiters", 12, newSVuv(hdr->slot_waiters), 0);
349 3           RETVAL = newRV_noinc((SV *)hv);
350             OUTPUT:
351             RETVAL
352              
353             void
354             sync(self)
355             SV *self
356             PREINIT:
357 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    0          
    0          
358             CODE:
359 0 0         if (reqrep_sync(h) != 0)
360 0           croak("msync: %s", strerror(errno));
361              
362             IV
363             eventfd(self)
364             SV *self
365             PREINIT:
366 5 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
367             CODE:
368 5           RETVAL = reqrep_eventfd_create(h);
369 5 50         if (RETVAL < 0) croak("eventfd: %s", strerror(errno));
370             OUTPUT:
371             RETVAL
372              
373             void
374             eventfd_set(self, fd)
375             SV *self
376             int fd
377             PREINIT:
378 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    0          
    0          
379             CODE:
380 0           reqrep_eventfd_set(h, fd);
381              
382             IV
383             fileno(self)
384             SV *self
385             PREINIT:
386 2 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
387             CODE:
388 2 50         RETVAL = h->notify_fd;
389             OUTPUT:
390             RETVAL
391              
392             void
393             eventfd_consume(self)
394             SV *self
395             PREINIT:
396 2 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
397             CODE:
398 2           reqrep_eventfd_consume(h);
399              
400             void
401             notify(self)
402             SV *self
403             PREINIT:
404 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    0          
    0          
405             CODE:
406 0           reqrep_notify(h);
407              
408             IV
409             reply_eventfd(self)
410             SV *self
411             PREINIT:
412 4 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
413             CODE:
414 4           RETVAL = reqrep_reply_eventfd_create(h);
415 4 50         if (RETVAL < 0) croak("eventfd: %s", strerror(errno));
416             OUTPUT:
417             RETVAL
418              
419             void
420             reply_eventfd_set(self, fd)
421             SV *self
422             int fd
423             PREINIT:
424 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    0          
    0          
425             CODE:
426 0           reqrep_reply_eventfd_set(h, fd);
427              
428             IV
429             reply_fileno(self)
430             SV *self
431             PREINIT:
432 2 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
433             CODE:
434 2 50         RETVAL = h->reply_fd;
435             OUTPUT:
436             RETVAL
437              
438             void
439             reply_eventfd_consume(self)
440             SV *self
441             PREINIT:
442 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    0          
    0          
443             CODE:
444 0           reqrep_reply_eventfd_consume(h);
445              
446             void
447             reply_notify(self)
448             SV *self
449             PREINIT:
450 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared", self);
    50          
    50          
451             CODE:
452 1           reqrep_reply_notify(h);
453              
454              
455             MODULE = Data::ReqRep::Shared PACKAGE = Data::ReqRep::Shared::Client
456              
457             SV *
458             new(class, path)
459             const char *class
460             SV *path
461             PREINIT:
462             char errbuf[REQREP_ERR_BUFLEN];
463             CODE:
464 42           const char *p = SvPV_nolen(path);
465 42           ReqRepHandle *h = reqrep_open(p, REQREP_MODE_STR, errbuf);
466 42 50         if (!h) croak("Data::ReqRep::Shared::Client->new: %s", errbuf);
467 42           MAKE_OBJ(class, h);
468 42           RETVAL = ref;
469             OUTPUT:
470             RETVAL
471              
472             SV *
473             new_from_fd(class, fd)
474             const char *class
475             int fd
476             PREINIT:
477             char errbuf[REQREP_ERR_BUFLEN];
478             CODE:
479 1           ReqRepHandle *h = reqrep_open_fd(fd, REQREP_MODE_STR, errbuf);
480 1 50         if (!h) croak("Data::ReqRep::Shared::Client->new_from_fd: %s", errbuf);
481 1           MAKE_OBJ(class, h);
482 1           RETVAL = ref;
483             OUTPUT:
484             RETVAL
485              
486             IV
487             memfd(self)
488             SV *self
489             PREINIT:
490 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    0          
    0          
491             CODE:
492 0 0         RETVAL = h->backing_fd;
493             OUTPUT:
494             RETVAL
495              
496             void
497             DESTROY(self)
498             SV *self
499             PREINIT:
500 43 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
501             CODE:
502 43           sv_setiv(SvRV(self), 0);
503 43           reqrep_destroy(h);
504              
505             SV *
506             send(self, value)
507             SV *self
508             SV *value
509             PREINIT:
510 96 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
511             STRLEN len;
512             uint64_t id;
513             CODE:
514 96           const char *str = SvPV(value, len);
515 96           bool utf8 = SvUTF8(value) ? true : false;
516 96           int r = reqrep_try_send(h, str, (uint32_t)len, utf8, &id);
517 96 50         if (r == -2) croak("Data::ReqRep::Shared::Client: request too long (max 2GB)");
518 96 100         RETVAL = (r == 1) ? newSVuv((UV)id) : &PL_sv_undef;
519             OUTPUT:
520             RETVAL
521              
522             SV *
523             send_wait(self, value, ...)
524             SV *self
525             SV *value
526             PREINIT:
527 216 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
528 216           double timeout = -1;
529             STRLEN len;
530             uint64_t id;
531             CODE:
532 216 50         if (items > 2) timeout = SvNV(ST(2));
533 216           const char *str = SvPV(value, len);
534 216           bool utf8 = SvUTF8(value) ? true : false;
535 216           int r = reqrep_send_wait(h, str, (uint32_t)len, utf8, &id, timeout);
536 216 50         if (r == -2) croak("Data::ReqRep::Shared::Client: request too long (max 2GB)");
537 216 100         RETVAL = (r == 1) ? newSVuv((UV)id) : &PL_sv_undef;
538             OUTPUT:
539             RETVAL
540              
541             SV *
542             send_notify(self, value)
543             SV *self
544             SV *value
545             PREINIT:
546 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
547             STRLEN len;
548             uint64_t id;
549             CODE:
550 1           const char *str = SvPV(value, len);
551 1           bool utf8 = SvUTF8(value) ? true : false;
552 1           int r = reqrep_try_send(h, str, (uint32_t)len, utf8, &id);
553 1 50         if (r == -2) croak("Data::ReqRep::Shared::Client: request too long (max 2GB)");
554 1 50         if (r == 1) {
555 1           reqrep_notify(h);
556 1           RETVAL = newSVuv((UV)id);
557             } else {
558 0           RETVAL = &PL_sv_undef;
559             }
560             OUTPUT:
561             RETVAL
562              
563             SV *
564             send_wait_notify(self, value, ...)
565             SV *self
566             SV *value
567             PREINIT:
568 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
569 1           double timeout = -1;
570             STRLEN len;
571             uint64_t id;
572             CODE:
573 1 50         if (items > 2) timeout = SvNV(ST(2));
574 1           const char *str = SvPV(value, len);
575 1           bool utf8 = SvUTF8(value) ? true : false;
576 1           int r = reqrep_send_wait(h, str, (uint32_t)len, utf8, &id, timeout);
577 1 50         if (r == -2) croak("Data::ReqRep::Shared::Client: request too long (max 2GB)");
578 1 50         if (r == 1) {
579 1           reqrep_notify(h);
580 1           RETVAL = newSVuv((UV)id);
581             } else {
582 0           RETVAL = &PL_sv_undef;
583             }
584             OUTPUT:
585             RETVAL
586              
587             SV *
588             get(self, id)
589             SV *self
590             UV id
591             PREINIT:
592 90 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
593             const char *str;
594             uint32_t len;
595             bool utf8;
596             CODE:
597 90           int r = reqrep_try_get(h, (uint64_t)id, &str, &len, &utf8);
598 90 50         if (r == -1) croak("Data::ReqRep::Shared::Client: invalid slot index");
599 90 50         if (r == -2) croak("Data::ReqRep::Shared::Client: out of memory");
600 90 100         if (r == 1) {
601 89           RETVAL = newSVpvn(str, len);
602 89 100         if (utf8) SvUTF8_on(RETVAL);
603             } else {
604 1           RETVAL = &PL_sv_undef;
605             }
606             OUTPUT:
607             RETVAL
608              
609             SV *
610             get_wait(self, id, ...)
611             SV *self
612             UV id
613             PREINIT:
614 6 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
615 6           double timeout = -1;
616             const char *str;
617             uint32_t len;
618             bool utf8;
619             CODE:
620 6 50         if (items > 2) timeout = SvNV(ST(2));
621 6           int r = reqrep_get_wait(h, (uint64_t)id, &str, &len, &utf8, timeout);
622 6 50         if (r == -1) croak("Data::ReqRep::Shared::Client: invalid slot index");
623 6 50         if (r == -2) croak("Data::ReqRep::Shared::Client: out of memory");
624 6 100         if (r == 1) {
625 3           RETVAL = newSVpvn(str, len);
626 3 50         if (utf8) SvUTF8_on(RETVAL);
627             } else {
628 3           RETVAL = &PL_sv_undef;
629             }
630             OUTPUT:
631             RETVAL
632              
633             SV *
634             req(self, value)
635             SV *self
636             SV *value
637             PREINIT:
638 747 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
639             STRLEN len;
640             const char *out_str;
641             uint32_t out_len;
642             bool out_utf8;
643             CODE:
644 747           const char *str = SvPV(value, len);
645 747           bool utf8 = SvUTF8(value) ? true : false;
646 747           int r = reqrep_request(h, str, (uint32_t)len, utf8, &out_str, &out_len, &out_utf8, -1);
647 747 50         if (r == -2) croak("Data::ReqRep::Shared::Client: request too long (max 2GB)");
648 747 50         if (r == 1) {
649 747           RETVAL = newSVpvn(out_str, out_len);
650 747 50         if (out_utf8) SvUTF8_on(RETVAL);
651             } else {
652 0           RETVAL = &PL_sv_undef;
653             }
654             OUTPUT:
655             RETVAL
656              
657             SV *
658             req_wait(self, value, timeout)
659             SV *self
660             SV *value
661             double timeout
662             PREINIT:
663 1801 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
664             STRLEN len;
665             const char *out_str;
666             uint32_t out_len;
667             bool out_utf8;
668             CODE:
669 1801           const char *str = SvPV(value, len);
670 1801           bool utf8 = SvUTF8(value) ? true : false;
671 1801           int r = reqrep_request(h, str, (uint32_t)len, utf8, &out_str, &out_len, &out_utf8, timeout);
672 1801 50         if (r == -2) croak("Data::ReqRep::Shared::Client: request too long (max 2GB)");
673 1801 100         if (r == 1) {
674 1800           RETVAL = newSVpvn(out_str, out_len);
675 1800 50         if (out_utf8) SvUTF8_on(RETVAL);
676             } else {
677 1           RETVAL = &PL_sv_undef;
678             }
679             OUTPUT:
680             RETVAL
681              
682             void
683             cancel(self, id)
684             SV *self
685             UV id
686             PREINIT:
687 213 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
688             CODE:
689 213           reqrep_cancel(h, (uint64_t)id);
690              
691             UV
692             pending(self)
693             SV *self
694             PREINIT:
695 7 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
696             CODE:
697 7 50         RETVAL = (UV)reqrep_pending(h);
698             OUTPUT:
699             RETVAL
700              
701             SV *
702             path(self)
703             SV *self
704             PREINIT:
705 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    0          
    0          
706             CODE:
707 0 0         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
708             OUTPUT:
709             RETVAL
710              
711             SV *
712             stats(self)
713             SV *self
714             PREINIT:
715 2 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
716             CODE:
717 2           HV *hv = newHV();
718 2           ReqRepHeader *hdr = h->hdr;
719 2           hv_store(hv, "size", 4, newSVuv((UV)reqrep_size(h)), 0);
720 2           hv_store(hv, "capacity", 8, newSVuv(h->req_cap), 0);
721 2           hv_store(hv, "resp_slots", 10, newSVuv(h->resp_slots), 0);
722 2           hv_store(hv, "resp_data_max", 13, newSVuv(h->resp_data_max), 0);
723 2           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
724 2           hv_store(hv, "arena_cap", 9, newSVuv(h->req_arena_cap), 0);
725 2           hv_store(hv, "arena_used", 10, newSVuv(hdr->arena_used), 0);
726 2           hv_store(hv, "requests", 8, newSVuv((UV)hdr->stat_requests), 0);
727 2           hv_store(hv, "replies", 7, newSVuv((UV)hdr->stat_replies), 0);
728 2           hv_store(hv, "send_full", 9, newSVuv((UV)hdr->stat_send_full), 0);
729 2           hv_store(hv, "recv_empty", 10, newSVuv(hdr->stat_recv_empty), 0);
730 2           hv_store(hv, "recoveries", 10, newSVuv(hdr->stat_recoveries), 0);
731 2           hv_store(hv, "recv_waiters", 12, newSVuv(hdr->recv_waiters), 0);
732 2           hv_store(hv, "send_waiters", 12, newSVuv(hdr->send_waiters), 0);
733 2           hv_store(hv, "slot_waiters", 12, newSVuv(hdr->slot_waiters), 0);
734 2           RETVAL = newRV_noinc((SV *)hv);
735             OUTPUT:
736             RETVAL
737              
738             UV
739             size(self)
740             SV *self
741             PREINIT:
742 4 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
743             CODE:
744 4           RETVAL = (UV)reqrep_size(h);
745             OUTPUT:
746             RETVAL
747              
748             UV
749             capacity(self)
750             SV *self
751             PREINIT:
752 4 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
753             CODE:
754 4 50         RETVAL = h->req_cap;
755             OUTPUT:
756             RETVAL
757              
758             bool
759             is_empty(self)
760             SV *self
761             PREINIT:
762 4 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
763             CODE:
764 4 50         RETVAL = (reqrep_size(h) == 0);
765             OUTPUT:
766             RETVAL
767              
768             UV
769             resp_slots(self)
770             SV *self
771             PREINIT:
772 4 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
773             CODE:
774 4 50         RETVAL = h->resp_slots;
775             OUTPUT:
776             RETVAL
777              
778             UV
779             resp_size(self)
780             SV *self
781             PREINIT:
782 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    0          
    0          
783             CODE:
784 0 0         RETVAL = h->resp_data_max;
785             OUTPUT:
786             RETVAL
787              
788             IV
789             eventfd(self)
790             SV *self
791             PREINIT:
792 2 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
793             CODE:
794 2           RETVAL = reqrep_reply_eventfd_create(h);
795 2 50         if (RETVAL < 0) croak("eventfd: %s", strerror(errno));
796             OUTPUT:
797             RETVAL
798              
799             void
800             eventfd_set(self, fd)
801             SV *self
802             int fd
803             PREINIT:
804 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
805             CODE:
806 1           reqrep_reply_eventfd_set(h, fd);
807              
808             IV
809             fileno(self)
810             SV *self
811             PREINIT:
812 2 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
813             CODE:
814 2 50         RETVAL = h->reply_fd;
815             OUTPUT:
816             RETVAL
817              
818             void
819             eventfd_consume(self)
820             SV *self
821             PREINIT:
822 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
823             CODE:
824 1           reqrep_reply_eventfd_consume(h);
825              
826             void
827             notify(self)
828             SV *self
829             PREINIT:
830 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
831             CODE:
832 1           reqrep_notify(h);
833              
834             void
835             req_eventfd_set(self, fd)
836             SV *self
837             int fd
838             PREINIT:
839 2 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    50          
    50          
840             CODE:
841 2           reqrep_eventfd_set(h, fd);
842              
843             IV
844             req_fileno(self)
845             SV *self
846             PREINIT:
847 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Client", self);
    0          
    0          
848             CODE:
849 0 0         RETVAL = h->notify_fd;
850             OUTPUT:
851             RETVAL
852              
853              
854             MODULE = Data::ReqRep::Shared PACKAGE = Data::ReqRep::Shared::Int
855              
856             SV *
857             new(class, path, req_cap, resp_slots)
858             const char *class
859             SV *path
860             UV req_cap
861             UV resp_slots
862             PREINIT:
863             char errbuf[REQREP_ERR_BUFLEN];
864             CODE:
865 7 50         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
866 7           ReqRepHandle *h = reqrep_create_int(p, (uint32_t)req_cap, (uint32_t)resp_slots, errbuf);
867 7 50         if (!h) croak("Data::ReqRep::Shared::Int->new: %s", errbuf);
868 7           MAKE_OBJ(class, h);
869 7           RETVAL = ref;
870             OUTPUT:
871             RETVAL
872              
873             SV *
874             new_memfd(class, name, req_cap, resp_slots)
875             const char *class
876             const char *name
877             UV req_cap
878             UV resp_slots
879             PREINIT:
880             char errbuf[REQREP_ERR_BUFLEN];
881             CODE:
882 1           ReqRepHandle *h = reqrep_create_int_memfd(name, (uint32_t)req_cap, (uint32_t)resp_slots, errbuf);
883 1 50         if (!h) croak("Data::ReqRep::Shared::Int->new_memfd: %s", errbuf);
884 1           MAKE_OBJ(class, h);
885 1           RETVAL = ref;
886             OUTPUT:
887             RETVAL
888              
889             SV *
890             new_from_fd(class, fd)
891             const char *class
892             int fd
893             PREINIT:
894             char errbuf[REQREP_ERR_BUFLEN];
895             CODE:
896 1           ReqRepHandle *h = reqrep_open_fd(fd, REQREP_MODE_INT, errbuf);
897 1 50         if (!h) croak("Data::ReqRep::Shared::Int->new_from_fd: %s", errbuf);
898 1           MAKE_OBJ(class, h);
899 1           RETVAL = ref;
900             OUTPUT:
901             RETVAL
902              
903             IV
904             memfd(self)
905             SV *self
906             PREINIT:
907 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
908             CODE:
909 1 50         RETVAL = h->backing_fd;
910             OUTPUT:
911             RETVAL
912              
913             void
914             DESTROY(self)
915             SV *self
916             PREINIT:
917 9 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
918             CODE:
919 9           sv_setiv(SvRV(self), 0);
920 9           reqrep_destroy(h);
921              
922             void
923             recv(self)
924             SV *self
925             PREINIT:
926 31 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
927             int64_t value;
928             uint64_t id;
929             PPCODE:
930 31 100         if (reqrep_int_try_recv(h, &value, &id)) {
931 29 50         mXPUSHi((IV)value);
932 29 50         mXPUSHu((UV)id);
933             }
934              
935             void
936             recv_wait(self, ...)
937             SV *self
938             PREINIT:
939 7 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
940 7           double timeout = -1;
941             int64_t value;
942             uint64_t id;
943             PPCODE:
944 7 50         if (items > 1) timeout = SvNV(ST(1));
945 7 50         if (reqrep_int_recv_wait(h, &value, &id, timeout)) {
946 7 50         mXPUSHi((IV)value);
947 7 50         mXPUSHu((UV)id);
948             }
949              
950             bool
951             reply(self, id, value)
952             SV *self
953             UV id
954             IV value
955             PREINIT:
956 35 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
957             CODE:
958 35           int r = reqrep_int_reply(h, (uint64_t)id, (int64_t)value);
959 35 50         if (r == -1) croak("Data::ReqRep::Shared::Int: invalid slot index");
960 35 100         RETVAL = (r == 1);
961             OUTPUT:
962             RETVAL
963              
964             UV
965             size(self)
966             SV *self
967             PREINIT:
968 3 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
969             CODE:
970 3           RETVAL = (UV)reqrep_int_size(h);
971             OUTPUT:
972             RETVAL
973              
974             UV
975             capacity(self)
976             SV *self
977             PREINIT:
978 2 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
979             CODE:
980 2 50         RETVAL = h->req_cap;
981             OUTPUT:
982             RETVAL
983              
984             UV
985             resp_slots(self)
986             SV *self
987             PREINIT:
988 2 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
989             CODE:
990 2 50         RETVAL = h->resp_slots;
991             OUTPUT:
992             RETVAL
993              
994             SV *
995             path(self)
996             SV *self
997             PREINIT:
998 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    0          
    0          
999             CODE:
1000 0 0         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
1001             OUTPUT:
1002             RETVAL
1003              
1004             bool
1005             is_empty(self)
1006             SV *self
1007             PREINIT:
1008 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
1009             CODE:
1010 1 50         RETVAL = (reqrep_int_size(h) == 0);
1011             OUTPUT:
1012             RETVAL
1013              
1014             UV
1015             resp_size(self)
1016             SV *self
1017             PREINIT:
1018 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    0          
    0          
1019             CODE:
1020 0 0         RETVAL = h->resp_data_max;
1021             OUTPUT:
1022             RETVAL
1023              
1024             SV *
1025             stats(self)
1026             SV *self
1027             PREINIT:
1028 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
1029             CODE:
1030 1           HV *hv = newHV();
1031 1           ReqRepHeader *hdr = h->hdr;
1032 1           hv_store(hv, "size", 4, newSVuv((UV)reqrep_int_size(h)), 0);
1033 1           hv_store(hv, "capacity", 8, newSVuv(h->req_cap), 0);
1034 1           hv_store(hv, "resp_slots", 10, newSVuv(h->resp_slots), 0);
1035 1           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
1036 1           hv_store(hv, "requests", 8, newSVuv((UV)__atomic_load_n(&hdr->stat_requests, __ATOMIC_RELAXED)), 0);
1037 1           hv_store(hv, "replies", 7, newSVuv((UV)__atomic_load_n(&hdr->stat_replies, __ATOMIC_RELAXED)), 0);
1038 1           hv_store(hv, "send_full", 9, newSVuv((UV)__atomic_load_n(&hdr->stat_send_full, __ATOMIC_RELAXED)), 0);
1039 1           hv_store(hv, "recv_empty", 10, newSVuv(__atomic_load_n(&hdr->stat_recv_empty, __ATOMIC_RELAXED)), 0);
1040 1           hv_store(hv, "recoveries", 10, newSVuv(hdr->stat_recoveries), 0);
1041 1           hv_store(hv, "send_waiters", 12, newSVuv(hdr->send_waiters), 0);
1042 1           hv_store(hv, "recv_waiters", 12, newSVuv(hdr->recv_waiters), 0);
1043 1           hv_store(hv, "slot_waiters", 12, newSVuv(hdr->slot_waiters), 0);
1044 1           RETVAL = newRV_noinc((SV *)hv);
1045             OUTPUT:
1046             RETVAL
1047              
1048             void
1049             clear(self)
1050             SV *self
1051             PREINIT:
1052 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
1053             CODE:
1054 1           reqrep_int_clear(h);
1055              
1056             void
1057             sync(self)
1058             SV *self
1059             PREINIT:
1060 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    0          
    0          
1061             CODE:
1062 0 0         if (reqrep_sync(h) != 0) croak("msync: %s", strerror(errno));
1063              
1064             IV
1065             eventfd(self)
1066             SV *self
1067             PREINIT:
1068 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
1069             CODE:
1070 1           RETVAL = reqrep_eventfd_create(h);
1071 1 50         if (RETVAL < 0) croak("eventfd: %s", strerror(errno));
1072             OUTPUT:
1073             RETVAL
1074              
1075             void
1076             eventfd_set(self, fd)
1077             SV *self
1078             int fd
1079             PREINIT:
1080 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    0          
    0          
1081             CODE:
1082 0           reqrep_eventfd_set(h, fd);
1083              
1084             IV
1085             fileno(self)
1086             SV *self
1087             PREINIT:
1088 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
1089             CODE:
1090 1 50         RETVAL = h->notify_fd;
1091             OUTPUT:
1092             RETVAL
1093              
1094             void
1095             eventfd_consume(self)
1096             SV *self
1097             PREINIT:
1098 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    0          
    0          
1099             CODE:
1100 0           reqrep_eventfd_consume(h);
1101              
1102             void
1103             notify(self)
1104             SV *self
1105             PREINIT:
1106 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    0          
    0          
1107             CODE:
1108 0           reqrep_notify(h);
1109              
1110             IV
1111             reply_eventfd(self)
1112             SV *self
1113             PREINIT:
1114 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    50          
    50          
1115             CODE:
1116 1           RETVAL = reqrep_reply_eventfd_create(h);
1117 1 50         if (RETVAL < 0) croak("eventfd: %s", strerror(errno));
1118             OUTPUT:
1119             RETVAL
1120              
1121             void
1122             reply_eventfd_set(self, fd)
1123             SV *self
1124             int fd
1125             PREINIT:
1126 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    0          
    0          
1127             CODE:
1128 0           reqrep_reply_eventfd_set(h, fd);
1129              
1130             IV
1131             reply_fileno(self)
1132             SV *self
1133             PREINIT:
1134 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    0          
    0          
1135             CODE:
1136 0 0         RETVAL = h->reply_fd;
1137             OUTPUT:
1138             RETVAL
1139              
1140             void
1141             reply_eventfd_consume(self)
1142             SV *self
1143             PREINIT:
1144 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    0          
    0          
1145             CODE:
1146 0           reqrep_reply_eventfd_consume(h);
1147              
1148             void
1149             reply_notify(self)
1150             SV *self
1151             PREINIT:
1152 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int", self);
    0          
    0          
1153             CODE:
1154 0           reqrep_reply_notify(h);
1155              
1156             void
1157             unlink(self_or_class, ...)
1158             SV *self_or_class
1159             CODE:
1160             const char *path;
1161 5 50         if (sv_isobject(self_or_class)) {
1162 5           ReqRepHandle *h = INT2PTR(ReqRepHandle*, SvIV(SvRV(self_or_class)));
1163 5 50         if (!h) croak("Attempted to use a destroyed object");
1164 5           path = h->path;
1165             } else {
1166 0 0         if (items < 2) croak("Usage: ...->unlink($path)");
1167 0           path = SvPV_nolen(ST(1));
1168             }
1169 5 50         if (!path) croak("cannot unlink anonymous or memfd channel");
1170 5 50         if (unlink(path) != 0) croak("unlink(%s): %s", path, strerror(errno));
1171              
1172              
1173             MODULE = Data::ReqRep::Shared PACKAGE = Data::ReqRep::Shared::Int::Client
1174              
1175             SV *
1176             new(class, path)
1177             const char *class
1178             SV *path
1179             PREINIT:
1180             char errbuf[REQREP_ERR_BUFLEN];
1181             CODE:
1182 7           const char *p = SvPV_nolen(path);
1183 7           ReqRepHandle *h = reqrep_open(p, REQREP_MODE_INT, errbuf);
1184 7 50         if (!h) croak("Data::ReqRep::Shared::Int::Client->new: %s", errbuf);
1185 7           MAKE_OBJ(class, h);
1186 7           RETVAL = ref;
1187             OUTPUT:
1188             RETVAL
1189              
1190             SV *
1191             new_from_fd(class, fd)
1192             const char *class
1193             int fd
1194             PREINIT:
1195             char errbuf[REQREP_ERR_BUFLEN];
1196             CODE:
1197 1           ReqRepHandle *h = reqrep_open_fd(fd, REQREP_MODE_INT, errbuf);
1198 1 50         if (!h) croak("Data::ReqRep::Shared::Int::Client->new_from_fd: %s", errbuf);
1199 1           MAKE_OBJ(class, h);
1200 1           RETVAL = ref;
1201             OUTPUT:
1202             RETVAL
1203              
1204             IV
1205             memfd(self)
1206             SV *self
1207             PREINIT:
1208 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    0          
    0          
1209             CODE:
1210 0 0         RETVAL = h->backing_fd;
1211             OUTPUT:
1212             RETVAL
1213              
1214             void
1215             DESTROY(self)
1216             SV *self
1217             PREINIT:
1218 8 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    50          
    50          
1219             CODE:
1220 8           sv_setiv(SvRV(self), 0);
1221 8           reqrep_destroy(h);
1222              
1223             SV *
1224             send(self, value)
1225             SV *self
1226             IV value
1227             PREINIT:
1228 32 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    50          
    50          
1229             uint64_t id;
1230             CODE:
1231 32           int r = reqrep_int_try_send(h, (int64_t)value, &id);
1232 32 100         RETVAL = (r == 1) ? newSVuv((UV)id) : &PL_sv_undef;
1233             OUTPUT:
1234             RETVAL
1235              
1236             SV *
1237             send_wait(self, value, ...)
1238             SV *self
1239             IV value
1240             PREINIT:
1241 2 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    50          
    50          
1242 2           double timeout = -1;
1243             uint64_t id;
1244             CODE:
1245 2 50         if (items > 2) timeout = SvNV(ST(2));
1246 2           int r = reqrep_int_send_wait(h, (int64_t)value, &id, timeout);
1247 2 50         RETVAL = (r == 1) ? newSVuv((UV)id) : &PL_sv_undef;
1248             OUTPUT:
1249             RETVAL
1250              
1251             SV *
1252             get(self, id)
1253             SV *self
1254             UV id
1255             PREINIT:
1256 25 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    50          
    50          
1257             int64_t value;
1258             CODE:
1259 25           int r = reqrep_int_try_get(h, (uint64_t)id, &value);
1260 25 50         if (r == -1) croak("invalid slot index");
1261 25 50         RETVAL = (r == 1) ? newSViv((IV)value) : &PL_sv_undef;
1262             OUTPUT:
1263             RETVAL
1264              
1265             SV *
1266             get_wait(self, id, ...)
1267             SV *self
1268             UV id
1269             PREINIT:
1270 2 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    50          
    50          
1271 2           double timeout = -1;
1272             int64_t value;
1273             CODE:
1274 2 50         if (items > 2) timeout = SvNV(ST(2));
1275 2           int r = reqrep_int_get_wait(h, (uint64_t)id, &value, timeout);
1276 2 50         if (r == -1) croak("invalid slot index");
1277 2 50         RETVAL = (r == 1) ? newSViv((IV)value) : &PL_sv_undef;
1278             OUTPUT:
1279             RETVAL
1280              
1281             SV *
1282             req(self, value)
1283             SV *self
1284             IV value
1285             PREINIT:
1286 5 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    50          
    50          
1287             int64_t out;
1288             CODE:
1289 5           int r = reqrep_int_request(h, (int64_t)value, &out, -1);
1290 5 50         RETVAL = (r == 1) ? newSViv((IV)out) : &PL_sv_undef;
1291             OUTPUT:
1292             RETVAL
1293              
1294             SV *
1295             req_wait(self, value, timeout)
1296             SV *self
1297             IV value
1298             double timeout
1299             PREINIT:
1300 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    50          
    50          
1301             int64_t out;
1302             CODE:
1303 1           int r = reqrep_int_request(h, (int64_t)value, &out, timeout);
1304 1 50         RETVAL = (r == 1) ? newSViv((IV)out) : &PL_sv_undef;
1305             OUTPUT:
1306             RETVAL
1307              
1308             void
1309             cancel(self, id)
1310             SV *self
1311             UV id
1312             PREINIT:
1313 3 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    50          
    50          
1314             CODE:
1315 3           reqrep_cancel(h, (uint64_t)id);
1316              
1317             UV
1318             pending(self)
1319             SV *self
1320             PREINIT:
1321 3 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    50          
    50          
1322             CODE:
1323 3 50         RETVAL = (UV)reqrep_pending(h);
1324             OUTPUT:
1325             RETVAL
1326              
1327             UV
1328             size(self)
1329             SV *self
1330             PREINIT:
1331 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    0          
    0          
1332             CODE:
1333 0           RETVAL = (UV)reqrep_int_size(h);
1334             OUTPUT:
1335             RETVAL
1336              
1337             UV
1338             capacity(self)
1339             SV *self
1340             PREINIT:
1341 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    50          
    50          
1342             CODE:
1343 1 50         RETVAL = h->req_cap;
1344             OUTPUT:
1345             RETVAL
1346              
1347             bool
1348             is_empty(self)
1349             SV *self
1350             PREINIT:
1351 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    50          
    50          
1352             CODE:
1353 1 50         RETVAL = (reqrep_int_size(h) == 0);
1354             OUTPUT:
1355             RETVAL
1356              
1357             UV
1358             resp_slots(self)
1359             SV *self
1360             PREINIT:
1361 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    0          
    0          
1362             CODE:
1363 0 0         RETVAL = h->resp_slots;
1364             OUTPUT:
1365             RETVAL
1366              
1367             UV
1368             resp_size(self)
1369             SV *self
1370             PREINIT:
1371 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    0          
    0          
1372             CODE:
1373 0 0         RETVAL = h->resp_data_max;
1374             OUTPUT:
1375             RETVAL
1376              
1377             SV *
1378             stats(self)
1379             SV *self
1380             PREINIT:
1381 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    0          
    0          
1382             CODE:
1383 0           HV *hv = newHV();
1384 0           ReqRepHeader *hdr = h->hdr;
1385 0           hv_store(hv, "size", 4, newSVuv((UV)reqrep_int_size(h)), 0);
1386 0           hv_store(hv, "capacity", 8, newSVuv(h->req_cap), 0);
1387 0           hv_store(hv, "resp_slots", 10, newSVuv(h->resp_slots), 0);
1388 0           hv_store(hv, "requests", 8, newSVuv((UV)__atomic_load_n(&hdr->stat_requests, __ATOMIC_RELAXED)), 0);
1389 0           hv_store(hv, "replies", 7, newSVuv((UV)__atomic_load_n(&hdr->stat_replies, __ATOMIC_RELAXED)), 0);
1390 0           hv_store(hv, "recoveries", 10, newSVuv(hdr->stat_recoveries), 0);
1391 0           RETVAL = newRV_noinc((SV *)hv);
1392             OUTPUT:
1393             RETVAL
1394              
1395             SV *
1396             path(self)
1397             SV *self
1398             PREINIT:
1399 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    0          
    0          
1400             CODE:
1401 0 0         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
1402             OUTPUT:
1403             RETVAL
1404              
1405             IV
1406             eventfd(self)
1407             SV *self
1408             PREINIT:
1409 1 50         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    50          
    50          
1410             CODE:
1411 1           RETVAL = reqrep_reply_eventfd_create(h);
1412 1 50         if (RETVAL < 0) croak("eventfd: %s", strerror(errno));
1413             OUTPUT:
1414             RETVAL
1415              
1416             void
1417             eventfd_set(self, fd)
1418             SV *self
1419             int fd
1420             PREINIT:
1421 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    0          
    0          
1422             CODE:
1423 0           reqrep_reply_eventfd_set(h, fd);
1424              
1425             IV
1426             fileno(self)
1427             SV *self
1428             PREINIT:
1429 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    0          
    0          
1430             CODE:
1431 0 0         RETVAL = h->reply_fd;
1432             OUTPUT:
1433             RETVAL
1434              
1435             void
1436             eventfd_consume(self)
1437             SV *self
1438             PREINIT:
1439 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    0          
    0          
1440             CODE:
1441 0           reqrep_reply_eventfd_consume(h);
1442              
1443             void
1444             notify(self)
1445             SV *self
1446             PREINIT:
1447 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    0          
    0          
1448             CODE:
1449 0           reqrep_notify(h);
1450              
1451             void
1452             req_eventfd_set(self, fd)
1453             SV *self
1454             int fd
1455             PREINIT:
1456 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    0          
    0          
1457             CODE:
1458 0           reqrep_eventfd_set(h, fd);
1459              
1460             IV
1461             req_fileno(self)
1462             SV *self
1463             PREINIT:
1464 0 0         EXTRACT_HANDLE("Data::ReqRep::Shared::Int::Client", self);
    0          
    0          
1465             CODE:
1466 0 0         RETVAL = h->notify_fd;
1467             OUTPUT:
1468             RETVAL