Fetch
view release on metacpan or search on metacpan
include/fetch/ft_future.h view on Meta::CPAN
if (hm_call_list(aTHX_ NULL, NULL, user, args, n, out)) {
SV *err = sv_2mortal(newSVsv(ERRSV));
hmf_settle(aTHX_ next, HMF_FAILED, &err, 1);
SvREFCNT_dec((SV *)out);
} else {
hmf_chain_into(aTHX_ next, out);
}
} else {
AV *copy = newAV();
SSize_t i;
for (i = 0; i < n; i++) {
SV **e = av_fetch(vals, i, 0);
av_push(copy, e ? newSVsv(*e) : newSV(0));
}
hmf_settle_av(aTHX_ next, st, copy);
}
} else {
hmf_cancel(aTHX_ next);
}
XSRETURN_EMPTY;
}
/* transform continuation: b = done-mapper, c = fail-mapper */
XS_INTERNAL(hm_xs_transform_cb);
XS_INTERNAL(hm_xs_transform_cb) {
dXSARGS;
hm_clos *cl = hm_clos_of(aTHX_ cv);
SV *f, *next;
IV st;
if (!cl || items < 1) XSRETURN_EMPTY;
f = ST(0);
next = cl->a;
st = hmf_state(aTHX_ f);
if (st == HMF_DONE || st == HMF_FAILED) {
SV *mapper = (st == HMF_DONE) ? cl->b : cl->c;
AV *vals = hmf_values_av(aTHX_ f);
SSize_t n = vals ? av_len(vals) + 1 : 0;
AV *out = newAV();
if (mapper && SvOK(mapper)) {
SV **args = vals ? AvARRAY(vals) : NULL;
if (hm_call_list(aTHX_ NULL, NULL, mapper, args, n, out)) {
SV *err = sv_2mortal(newSVsv(ERRSV));
hmf_settle(aTHX_ next, HMF_FAILED, &err, 1);
SvREFCNT_dec((SV *)out);
XSRETURN_EMPTY;
}
} else {
SSize_t i;
for (i = 0; i < n; i++) {
SV **e = av_fetch(vals, i, 0);
av_push(out, e ? newSVsv(*e) : newSV(0));
}
}
hmf_settle_av(aTHX_ next, st, out);
} else {
hmf_cancel(aTHX_ next);
}
XSRETURN_EMPTY;
}
/* on_done / on_fail filter: b = user cb, i = required state */
XS_INTERNAL(hm_xs_ondone_cb);
XS_INTERNAL(hm_xs_ondone_cb) {
dXSARGS;
hm_clos *cl = hm_clos_of(aTHX_ cv);
SV *f;
if (!cl || items < 1) XSRETURN_EMPTY;
f = ST(0);
if (hmf_state(aTHX_ f) == cl->i) {
AV *vals = hmf_values_av(aTHX_ f);
SSize_t n = vals ? av_len(vals) + 1 : 0;
dSP;
SSize_t j;
ENTER; SAVETMPS; PUSHMARK(SP);
for (j = 0; j < n; j++) {
SV **e = av_fetch(vals, j, 0);
XPUSHs(e ? *e : &PL_sv_undef);
}
PUTBACK;
call_sv(cl->b, G_DISCARD);
FREETMPS; LEAVE;
}
XSRETURN_EMPTY;
}
/* ---- convergent combinators --------------------------------------------- *
* a = result future, b = remaining-count SV, c = subfutures AV ref,
* i = mode. */
#define HM_COMB_WAIT_ALL 0
#define HM_COMB_WAIT_ANY 1
#define HM_COMB_NEEDS_ALL 2
#define HM_COMB_NEEDS_ANY 3
XS_INTERNAL(hm_xs_comb_cb);
XS_INTERNAL(hm_xs_comb_cb) {
dXSARGS;
hm_clos *cl = hm_clos_of(aTHX_ cv);
SV *g, *res;
AV *list;
IV left;
if (!cl || items < 1) XSRETURN_EMPTY;
g = ST(0);
res = cl->a;
list = (AV *)SvRV(cl->c);
if (hmf_state(aTHX_ res) != HMF_PENDING) XSRETURN_EMPTY;
switch (cl->i) {
case HM_COMB_WAIT_ALL: {
left = SvIV(cl->b) - 1;
sv_setiv(cl->b, left);
if (left == 0) {
AV *out = newAV();
SSize_t i, n = av_len(list) + 1;
for (i = 0; i < n; i++) {
SV **e = av_fetch(list, i, 0);
av_push(out, e ? newSVsv(*e) : newSV(0));
}
hmf_settle_av(aTHX_ res, HMF_DONE, out);
}
break;
}
( run in 1.300 second using v1.01-cache-2.11-cpan-84e82930d8c )