Future-XS
view release on metacpan or search on metacpan
lib/Future/XS.xs view on Meta::CPAN
fail = 0
die = 1
CODE:
SV *exception = ST(1);
if(ix == 1 && /* ->die */
!SvROK(exception) && SvPV_nolen(exception)[SvCUR(exception)-1] != '\n') {
ST(1) = exception = newSVsv(exception);
sv_catpvf(exception, " at %s line %d\n", CopFILE(PL_curcop), CopLINE(PL_curcop));
}
// TODO: mess about with Future::Exception
if(sv_is_future(self))
RETVAL = SvREFCNT_inc(ST(0));
else
RETVAL = future_new(SvPV_nolen(ST(0)));
future_failv(RETVAL, &ST(1), items - 1);
OUTPUT:
RETVAL
SV *
on_cancel(SV *self, SV *code)
CODE:
CHECK_INSTANCE(self);
RETVAL = newSVsv(self);
future_on_cancel(self, code);
OUTPUT:
RETVAL
SV *
on_ready(SV *self, SV *code)
CODE:
CHECK_INSTANCE(self);
/* Need to copy the return value first in case on_ready destroys it
* RT145168 */
RETVAL = newSVsv(self);
future_on_ready(self, code);
OUTPUT:
RETVAL
SV *
await(SV *self)
CODE:
CHECK_INSTANCE(self);
if(future_is_ready(self)) {
RETVAL = newSVsv(ST(0));
XSRETURN(1);
}
croak_from_caller("%" SVf " is not yet complete and does not provide an ->await method",
SVfARG(self));
OUTPUT:
RETVAL
void
result(SV *self)
ALIAS:
result = FALSE
get = TRUE
PPCODE:
CHECK_INSTANCE(self);
/* This PUTBACK + SPAGAIN pair is required in case future_get_result_av()
* causes the arguments stack to be reällocated. It works fine on perls
* 5.24+ but causes older perls to crash. For now we just depend on 5.24
* https://rt.cpan.org/Ticket/Display.html?id=145597
*/
PUTBACK;
AV *result = future_get_result_av(self, ix);
SPAGAIN;
if(GIMME_V == G_LIST) {
XPUSHs_from_AV(result);
XSRETURN(av_count(result));
}
else {
if(av_count(result))
XPUSHs(AvARRAY(result)[0]);
else
XPUSHs(&PL_sv_undef);
XSRETURN(1);
}
SV *
on_done(SV *self, SV *code)
CODE:
CHECK_INSTANCE(self);
RETVAL = newSVsv(self);
future_on_done(self, code);
OUTPUT:
RETVAL
void
failure(SV *self)
PPCODE:
CHECK_INSTANCE(self);
PUTBACK;
AV *failure = future_get_failure_av(self);
SPAGAIN;
if(!failure)
XSRETURN(0);
if(GIMME_V == G_LIST) {
XPUSHs_from_AV(failure);
XSRETURN(av_count(failure));
}
else {
if(av_count(failure))
XPUSHs(AvARRAY(failure)[0]);
else
XPUSHs(&PL_sv_undef);
XSRETURN(1);
}
SV *
on_fail(SV *self, SV *code)
CODE:
CHECK_INSTANCE(self);
RETVAL = newSVsv(self);
future_on_fail(self, code);
OUTPUT:
RETVAL
SV *
cancel(SV *self)
CODE:
CHECK_INSTANCE(self);
RETVAL = SvREFCNT_inc(self);
future_cancel(self);
OUTPUT:
RETVAL
SV *
without_cancel(SV *self)
CODE:
RETVAL = future_without_cancel(self);
OUTPUT:
RETVAL
SV *
then(SV *self, ...)
ALIAS:
then = 0
then_with_f = FUTURE_THEN_WITH_F
CODE:
CHECK_INSTANCE(self);
if(GIMME_V == G_VOID) {
// Need to ensure we print the ->transform message right
const PERL_CONTEXT *cx = caller_cx(0, NULL);
if(CxTYPE(cx) == CXt_SUB &&
strEQ(GvNAME(CvGV(cx->blk_sub.cv)), "transform")) {
warn_void_context("transform");
}
else {
warn_void_context(ix ? "then_with_f" : "then");
lib/Future/XS.xs view on Meta::CPAN
SV *elsecode = &PL_sv_undef;
if(items % 2) {
elsecode = newSVsv(ST(items));
items--;
}
HV *catches = newHV();
for(int i = 0; i < items/2; i++)
hv_store_ent(catches, ST(1 + i*2), newSVsv(ST(1 + i*2 + 1)), 0);
RETVAL = future_thencatch(self, ix, NULL, catches, elsecode);
OUTPUT:
RETVAL
SV *
followed_by(SV *self, SV *code)
CODE:
CHECK_INSTANCE(self);
warn_void_context("followed_by");
RETVAL = future_followed_by(self, newSVsv(code));
OUTPUT:
RETVAL
SV *
wait_all(SV *cls, ...)
CODE:
RETVAL = future_new_waitallv(SvPV_nolen(cls), &ST(1), items - 1);
OUTPUT:
RETVAL
SV *
wait_any(SV *cls, ...)
CODE:
RETVAL = future_new_waitanyv(SvPV_nolen(cls), &ST(1), items - 1);
OUTPUT:
RETVAL
SV *
needs_all(SV *cls, ...)
CODE:
RETVAL = future_new_needsallv(SvPV_nolen(cls), &ST(1), items - 1);
OUTPUT:
RETVAL
SV *
needs_any(SV *cls, ...)
CODE:
RETVAL = future_new_needsanyv(SvPV_nolen(cls), &ST(1), items - 1);
OUTPUT:
RETVAL
void
pending_futures(SV *self)
ALIAS:
pending_futures = FUTURE_SUBS_PENDING
ready_futures = FUTURE_SUBS_READY
done_futures = FUTURE_SUBS_DONE
failed_futures = FUTURE_SUBS_FAILED
cancelled_futures = FUTURE_SUBS_CANCELLED
PPCODE:
CHECK_INSTANCE(self);
PUTBACK;
Size_t count = future_mPUSH_subs(self, ix);
SPAGAIN;
XSRETURN(count);
SV *
btime(SV *self)
ALIAS:
btime = 0
rtime = 1
CODE:
{
struct timeval t;
switch(ix) {
case 0: t = future_get_btime(self); break;
case 1: t = future_get_rtime(self); break;
}
RETVAL = &PL_sv_undef;
if(t.tv_sec) {
AV *retav = newAV();
av_push(retav, newSViv(t.tv_sec));
av_push(retav, newSViv(t.tv_usec));
RETVAL = newRV_noinc((SV *)retav);
}
}
OUTPUT:
RETVAL
SV *
set_label(SV *self, SV *label)
CODE:
future_set_label(self, label);
RETVAL = SvREFCNT_inc(self);
OUTPUT:
RETVAL
SV *
label(SV *self)
CODE:
SV *label = future_get_label(self);
RETVAL = label ? newSVsv(label) : &PL_sv_undef;
OUTPUT:
RETVAL
SV *
set_udata(SV *self, SV *name, SV *value)
CODE:
future_set_udata(self, name, value);
RETVAL = SvREFCNT_inc(self);
OUTPUT:
RETVAL
SV *
udata(SV *self, SV *name)
CODE:
RETVAL = newSVsv(future_get_udata(self, name));
( run in 0.479 second using v1.01-cache-2.11-cpan-5511b514fd6 )