Branch Coverage

src/future.c
Criterion Covered Total %
branch 5 746 0.6


line true false branch
121 0 0 if(!SvROK(sv) || !SvOBJECT(SvRV(sv)))
0 0 if(!SvROK(sv) || !SvOBJECT(SvRV(sv)))
124 0 0 if(sv_derived_from(sv, "Future") || sv_derived_from(sv, "Future::XS"))
0 0 if(sv_derived_from(sv, "Future") || sv_derived_from(sv, "Future::XS"))
137 0 0 struct FutureXS *self = INT2PTR(struct FutureXS *, SvIV(SvRV(sv)));
138 0 0 if(self || nullok)
0 0 if(self || nullok)
145 0 0 if(!cls)
157 0 0 if(capture_times)
164 0 0 if(future_debug)
165 0 0 self->constructed_at = newSVpvf("constructed at %s line %d", CopFILE(PL_curcop), CopLINE(PL_curcop));
205 0 0 EXTEND(SP, 1);
206 0 0 PUSHMARK(SP);
217 0 0 FREETMPS;
241 0 0 if(flags & CB_SEQ_ANY) {
248 0 0 SvREFCNT_dec(CB_NONSEQ_CODE(cb));
256 0 0 while(callbacksav && AvFILLp(callbacksav) > -1) {
0 0 while(callbacksav && AvFILLp(callbacksav) > -1) {
278 0 0 if(!f || !SvROK(f))
0 0 if(!f || !SvROK(f))
281 0 0 if(!self)
284 0 0 if(future_debug &&
0 0 if(future_debug &&
285 0 0 (!self->ready || (self->failure && !self->reported))) {
0 0 (!self->ready || (self->failure && !self->reported))) {
286 0 0 if(!self->ready)
287 0 0 warn("%" SVf " was %" SVf " and was lost near %s line %d before it was ready\n",
292 0 0 warn("%" SVf " was %" SVf " and was lost near %s line %d with an unreported failure of: %" SVf "\n",
311 0 0 while(revocationsav && AvFILLp(revocationsav) > -1) {
0 0 while(revocationsav && AvFILLp(revocationsav) > -1) {
341 0 0 return self->ready && !self->failure && !self->cancelled;
0 0 return self->ready && !self->failure && !self->cancelled;
0 0 return self->ready && !self->failure && !self->cancelled;
347 0 0 return self->ready && self->failure;
0 0 return self->ready && self->failure;
359 0 0 if(!self->on_cancel)
375 0 0 if(cb->flags & CB_SEQ_ANY) {
382 0 0 new->code = CB_NONSEQ_CODE(cb);
385 0 0 if(!self->callbacks)
400 0 0 EXTEND(SP, 3);
401 0 0 PUSHMARK(SP);
413 0 0 FREETMPS;
425 0 0 bool is_done = !self->cancelled && !is_fail;
0 0 bool is_done = !self->cancelled && !is_fail;
427 0 0 AV *result = (is_done) ? self->result :
428 0 0 (is_fail) ? self->failure :
431 0 0 SV *code = (is_done) ? cb->seq.thencode :
432 0 0 (is_fail) ? cb->seq.elsecode :
435 0 0 if(is_fail && result && av_count(result) > 1 && cb->seq.catches) {
0 0 if(is_fail && result && av_count(result) > 1 && cb->seq.catches) {
0 0 if(is_fail && result && av_count(result) > 1 && cb->seq.catches) {
0 0 if(is_fail && result && av_count(result) > 1 && cb->seq.catches) {
0 0 if(is_fail && result && av_count(result) > 1 && cb->seq.catches) {
437 0 0 if(SvOK(category)) {
0 0 if(SvOK(category)) {
0 0 if(SvOK(category)) {
439 0 0 if(he && HeVAL(he))
0 0 if(he && HeVAL(he))
444 0 0 if(!code || !SvOK(code))
0 0 if(!code || !SvOK(code))
0 0 if(!code || !SvOK(code))
0 0 if(!code || !SvOK(code))
452 0 0 PUSHMARK(SP);
453 0 0 if(flags & CB_SELF)
454 0 0 XPUSHs(selfsv);
455 0 0 if(flags & CB_RESULT)
456 0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
464 0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
0 0 if(SvROK(ERRSV) || SvTRUE(ERRSV)) {
469 0 0 if(!fseq)
472 0 0 future_failv(fseq, &ERRSV, 1);
474 0 0 FREETMPS;
484 0 0 FREETMPS;
487 0 0 if(!sv_is_future(f2)) {
506 0 0 bool is_done = !is_cancelled && !is_fail;
0 0 bool is_done = !is_cancelled && !is_fail;
508 0 0 AV *result = (is_done) ? self->result :
509 0 0 (is_fail) ? self->failure :
512 0 0 if(is_done && !(flags & CB_DONE))
0 0 if(is_done && !(flags & CB_DONE))
514 0 0 if(is_fail && !(flags & CB_FAIL))
0 0 if(is_fail && !(flags & CB_FAIL))
516 0 0 if(is_cancelled && !(flags & CB_CANCEL))
0 0 if(is_cancelled && !(flags & CB_CANCEL))
519 0 0 if(flags & CB_IS_FUTURE) {
525 0 0 PUSHMARK(SP);
526 0 0 XPUSHs(CB_NONSEQ_CODE(cb)); // really a Future RV
0 0 XPUSHs(CB_NONSEQ_CODE(cb)); // really a Future RV
527 0 0 if(result)
528 0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
531 0 0 if(is_done)
533 0 0 else if(is_fail)
538 0 0 FREETMPS;
541 0 0 else if(flags & CB_SEQ_ANY) {
544 0 0 if(!SvOK(fseq)) {
0 0 if(!SvOK(fseq)) {
0 0 if(!SvOK(fseq)) {
545 0 0 if(self->constructed_at)
555 0 0 if(f2 == fseq)
561 0 0 if(future_is_ready(f2)) {
562 0 0 if(!future_is_cancelled(f2))
564 0 0 else if(flags & CB_CANCEL)
579 0 0 SV *code = CB_NONSEQ_CODE(cb);
586 0 0 PUSHMARK(SP);
587 0 0 if(flags & CB_SELF)
588 0 0 XPUSHs(selfsv);
589 0 0 if((flags & CB_RESULT) && result)
0 0 if((flags & CB_RESULT) && result)
590 0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
0 0 XPUSHs_from_AV(result);
596 0 0 FREETMPS;
604 0 0 if(rev->toclear_sv_at && SvROK(rev->toclear_sv_at)) {
0 0 if(rev->toclear_sv_at && SvROK(rev->toclear_sv_at)) {
612 0 0 if(!SvOK(rev->precedent_f))
0 0 if(!SvOK(rev->precedent_f))
0 0 if(!SvOK(rev->precedent_f))
620 0 0 if(self->empty_revocation_slots >= 8 && on_cancel &&
0 0 if(self->empty_revocation_slots >= 8 && on_cancel &&
0 0 if(self->empty_revocation_slots >= 8 && on_cancel &&
621 0 0 self->empty_revocation_slots >= AvFILL(on_cancel)/2) {
626 0 0 **end = AvARRAY(on_cancel) + AvFILL(on_cancel);
628 0 0 while(rdsv <= end) {
629 0 0 if(SvOK(*rdsv))
0 0 if(SvOK(*rdsv))
0 0 if(SvOK(*rdsv))
649 0 0 if(capture_times)
656 0 0 if(self->precedent_f) {
662 0 0 if(self->revoke_when_ready) {
664 0 0 for(size_t i = 0; i < av_count(revocations); i++) {
0 0 for(size_t i = 0; i < av_count(revocations); i++) {
677 0 0 if(!self->callbacks)
683 0 0 size_t i, n = av_count(callbacks);
684 0 0 for(i = 0; i < n; i++) {
699 0 0 if(self->ready) {
708 0 0 if(cb->flags & CB_SEQ_CANCEL)
712 0 0 if(cb->seq.thencode)
714 0 0 if(cb->seq.elsecode)
727 0 0 if(!CvANON(cv)) {
733 0 0 while(cop && OP_CLASS(cop) != OA_COP)
0 0 while(cop && OP_CLASS(cop) != OA_COP)
0 0 while(cop && OP_CLASS(cop) != OA_COP)
0 0 while(cop && OP_CLASS(cop) != OA_COP)
736 0 0 if(!cop)
739 0 0 return newSVpvf("__ANON__(%s line %d)", CopFILE((COP *)cop), CopLINE((COP *)cop));
746 0 0 if(self->cancelled)
749 0 0 if(self->ready)
762 0 0 if(self->cancelled)
765 0 0 if(self->ready)
769 0 0 if(n == 1 &&
0 0 if(n == 1 &&
781 0 0 EXTEND(SP, 1);
782 0 0 PUSHMARK(SP);
793 0 0 FREETMPS;
801 0 0 EXTEND(SP, 1);
802 0 0 PUSHMARK(SP);
813 0 0 FREETMPS;
821 0 0 EXTEND(SP, 1);
822 0 0 PUSHMARK(SP);
832 0 0 for(SSize_t i = 0; i < count; i++)
837 0 0 FREETMPS;
853 0 0 if(self->cancelled)
856 0 0 if(self->ready)
869 0 0 if(self->ready)
875 0 0 if(!self->on_cancel)
881 0 0 if(is_future) {
889 0 0 if(!codeself->revoke_when_ready)
904 0 0 if(is_future)
912 0 0 if(self->ready)
928 0 0 if(is_future)
936 0 0 if(self->ready)
952 0 0 if(is_future)
960 0 0 if(self->ready)
976 0 0 PUSHMARK(SP);
977 0 0 mXPUSHs(newSVsv(f));
982 0 0 FREETMPS;
990 0 0 if(await && !self->ready)
0 0 if(await && !self->ready)
993 0 0 if(!self->ready)
996 0 0 if(self->failure) {
1000 0 0 if(av_count(self->failure) > 1) {
0 0 if(av_count(self->failure) > 1) {
1005 0 0 PUSHMARK(SP);
1006 0 0 EXTEND(SP, 1 + av_count(self->failure));
0 0 EXTEND(SP, 1 + av_count(self->failure));
0 0 EXTEND(SP, 1 + av_count(self->failure));
0 0 EXTEND(SP, 1 + av_count(self->failure));
0 0 EXTEND(SP, 1 + av_count(self->failure));
1008 0 0 for(SSize_t i = 0; i < av_count(self->failure); i++)
0 0 for(SSize_t i = 0; i < av_count(self->failure); i++)
1019 0 0 FREETMPS;
1023 0 0 if(SvROK(exception) || SvPV_nolen(exception)[SvCUR(exception)-1] == '\n')
0 0 if(SvROK(exception) || SvPV_nolen(exception)[SvCUR(exception)-1] == '\n')
0 0 if(SvROK(exception) || SvPV_nolen(exception)[SvCUR(exception)-1] == '\n')
1031 0 0 for(cxix = cxstack_ix; cxix; cxix--) {
1032 0 0 if(CxTYPE(&cxstack[cxix]) != CXt_SUB)
1036 0 0 if(!cv)
1039 0 0 const char *stashname = HvNAME(CvSTASH(cv));
0 0 const char *stashname = HvNAME(CvSTASH(cv));
0 0 const char *stashname = HvNAME(CvSTASH(cv));
0 0 const char *stashname = HvNAME(CvSTASH(cv));
0 0 const char *stashname = HvNAME(CvSTASH(cv));
0 0 const char *stashname = HvNAME(CvSTASH(cv));
1040 0 0 if(!stashname)
1044 0 0 if(strEQ(stashname, "Future::_base"))
1047 0 0 const COP *cop = cxix < cxstack_ix ? cxstack[cxix+1].blk_oldcop : PL_curcop;
1049 0 0 sv_catpvf(exception, " at %s line %d.\n", CopFILE(cop), CopLINE(cop));
1057 0 0 if(self->cancelled)
1061 0 0 if(!self->result)
1071 0 0 if(!self->ready)
1074 0 0 if(!self->failure)
1086 0 0 if(!self)
1089 0 0 if(self->ready)
1095 0 0 if(self->subs) {
1096 0 0 for(Size_t i = 0; i < av_count(self->subs); i++)
0 0 for(Size_t i = 0; i < av_count(self->subs); i++)
1103 0 0 for(int i = on_cancel ? AvFILL(on_cancel) : -1; i >= 0; i--) {
0 0 for(int i = on_cancel ? AvFILL(on_cancel) : -1; i >= 0; i--) {
0 0 for(int i = on_cancel ? AvFILL(on_cancel) : -1; i >= 0; i--) {
1105 0 0 if(!SvOK(code))
0 0 if(!SvOK(code))
0 0 if(!SvOK(code))
1108 0 0 if(sv_is_future(code)) {
1114 0 0 PUSHMARK(SP);
1120 0 0 FREETMPS;
1129 0 0 PUSHMARK(SP);
1136 0 0 FREETMPS;
1166 0 0 if(flags & FUTURE_THEN_WITH_F)
1191 0 0 if(flags & FUTURE_THEN_WITH_F)
1206 0 0 for(Size_t i = 0; i < n; i++) {
1207 0 0 if(!SvROK(subs[i]) || !SvOBJECT(SvRV(subs[i])))
0 0 if(!SvROK(subs[i]) || !SvOBJECT(SvRV(subs[i])))
1210 0 0 if(SvSTASH(SvRV(subs[i])) != future_stash) {
1216 0 0 SV *f = proto ? future_new_proto(proto) : future_new(cls);
1219 0 0 if(!self->subs)
1222 0 0 for(Size_t i = 0; i < n; i++)
1237 0 0 if(srcself->failure) {
1238 0 0 self->failure = newAV_svn_dup(AvARRAY(srcself->failure), av_count(srcself->failure));
1242 0 0 self->result = newAV_svn_dup(AvARRAY(srcself->result), av_count(srcself->result));
1249 0 0 if(!self->subs)
1252 0 0 for(Size_t i = 0; i < av_count(self->subs); i++) {
0 0 for(Size_t i = 0; i < av_count(self->subs); i++) {
1254 0 0 if(!future_is_ready(sub))
1264 0 0 if(!SvOK(f))
0 0 if(!SvOK(f))
0 0 if(!SvOK(f))
1275 0 0 if(self->pending_subs)
1279 0 0 self->result = newAV_svn_dup(AvARRAY(self->subs), av_count(self->subs));
1289 0 0 for(Size_t i = 0; i < n; i++) {
1291 0 0 if(!future_is_ready(subs[i]))
1295 0 0 if(!self->pending_subs) {
1310 0 0 for(Size_t i = 0; i < n; i++) {
1311 0 0 if(!future_is_ready(subs[i]))
1326 0 0 if(!SvOK(f))
0 0 if(!SvOK(f))
0 0 if(!SvOK(f))
1335 0 0 if(self->result || self->failure)
0 0 if(self->result || self->failure)
1342 0 0 if(self->pending_subs && this_cancelled)
0 0 if(self->pending_subs && this_cancelled)
1345 0 0 if(this_cancelled) {
1362 0 0 if(!n) {
1368 0 0 for(Size_t i = 0; i < n; i++) {
1370 0 0 if(future_is_ready(subs[i]) && !future_is_cancelled(subs[i])) {
0 0 if(future_is_ready(subs[i]) && !future_is_cancelled(subs[i])) {
1376 0 0 if(immediate_ready) {
1396 0 0 for(Size_t i = 0; i < n; i++) {
1397 0 0 if(future_is_cancelled(subs[i]))
1413 0 0 for(Size_t i = 0; i < av_count(self->subs); i++) {
0 0 for(Size_t i = 0; i < av_count(self->subs); i++) {
1417 0 0 av_push_svn(result, AvARRAY(subself->result), av_count(subself->result));
1427 0 0 if(!SvOK(f))
0 0 if(!SvOK(f))
0 0 if(!SvOK(f))
1436 0 0 if(self->result || self->failure)
0 0 if(self->result || self->failure)
1439 0 0 if(future_is_cancelled(thissub)) {
1444 0 0 else if(future_is_failed(thissub)) {
1451 0 0 if(self->pending_subs)
1463 0 0 if(!n) {
1469 0 0 for(Size_t i = 0; i < n; i++) {
1470 0 0 if(future_is_cancelled(subs[i])) {
1475 0 0 if(future_is_failed(subs[i])) {
1481 0 0 if(immediate_fail) {
1498 0 0 for(Size_t i = 0; i < n; i++) {
1499 0 0 if(future_is_ready(subs[i]))
1506 0 0 if(!self->pending_subs) {
1522 0 0 if(!SvOK(f))
0 0 if(!SvOK(f))
0 0 if(!SvOK(f))
1531 0 0 if(self->result || self->failure)
0 0 if(self->result || self->failure)
1538 0 0 if(self->pending_subs && this_cancelled)
0 0 if(self->pending_subs && this_cancelled)
1541 0 0 if(this_cancelled) {
1544 0 0 else if(future_is_failed(thissub)) {
1545 0 0 if(self->pending_subs)
1563 0 0 if(!n) {
1569 0 0 for(Size_t i = 0; i < n; i++) {
1570 0 0 if(future_is_done(subs[i])) {
1576 0 0 if(immediate_done) {
1593 0 0 for(Size_t i = 0; i < n; i++) {
1594 0 0 if(future_is_ready(subs[i]))
1601 0 0 if(!self->pending_subs) {
1618 0 0 for(Size_t i = 0; self->subs && i < av_count(self->subs); i++) {
0 0 for(Size_t i = 0; self->subs && i < av_count(self->subs); i++) {
0 0 for(Size_t i = 0; self->subs && i < av_count(self->subs); i++) {
1644 0 0 if(want) {
1645 0 0 XPUSHs(sv_mortalcopy(sub));
1670 0 0 if(self->label)
1687 0 0 if(!self->udata)
1697 0 0 if(!self->udata)
1701 0 0 return he ? HeVAL(he) : &PL_sv_undef;
1788 0 6 if(!val || !val[0])
0 0 if(!val || !val[0])
1790 0 0 if(val[0] == '0' && strlen(val) == 1)
0 0 if(val[0] == '0' && strlen(val) == 1)
1803 3 0 capture_times = future_debug || getenv_bool("PERL_FUTURE_TIMES");
0 3 capture_times = future_debug || getenv_bool("PERL_FUTURE_TIMES");
1804 0 3 sv_setsv(get_sv("Future::TIMES", GV_ADDMULTI), capture_times ? &PL_sv_yes : &PL_sv_no);
1816 0 3 newCONSTSUB(gv_stashpvn("Future::XS", 10, TRUE), "DEBUG", newSVbool(future_debug));