Future-XS

 view release on metacpan or  search on metacpan

src/future.c  view on Meta::CPAN

    if(future_is_ready(f2)) {
      if(!future_is_cancelled(f2))
        future_on_ready(f2, fseq);
      else if(flags & CB_CANCEL)
        future_cancel(fseq);
    }
    else {
      struct FutureXS *f2self = get_future(f2);
      struct FutureXSCallback cb2 = {
        .flags = CB_DONE|CB_FAIL|CB_IS_FUTURE,
        .code  = sv_rvweaken(newSVsv(fseq)),
      };
      push_callback(f2self, &cb2);
    }

    assert(SvREFCNT(f2) == 1);
    SvREFCNT_dec(f2);
  }
  else {
    SV *code = CB_NONSEQ_CODE(cb);

src/future.c  view on Meta::CPAN


  SV *fseq = future_new_proto(f1);
  if(cb->flags & CB_SEQ_CANCEL)
    future_on_cancel(fseq, f1);

  cb->flags |= CB_DONE|CB_FAIL;
  if(cb->seq.thencode)
    cb->seq.thencode = wrap_cb(f1, "sequence", sv_2mortal(cb->seq.thencode));
  if(cb->seq.elsecode)
    cb->seq.elsecode = wrap_cb(f1, "sequence", sv_2mortal(cb->seq.elsecode));
  cb->seq.f = sv_rvweaken(newSVsv(fseq));

  push_callback(self, cb);

  return fseq;
}

// TODO: move to a hax/ file
#define CvNAME_FILE_LINE(cv)  S_CvNAME_FILE_LINE(aTHX_ cv)
static SV *S_CvNAME_FILE_LINE(pTHX_ CV *cv)
{

src/future.c  view on Meta::CPAN

  if(!self->on_cancel)
    self->on_cancel = newAV();

  SV *rv = newSVsv((SV *)code);
  av_push(self->on_cancel, rv);

  if(is_future) {
    struct FutureXSRevocation *rev;
    Newx(rev, 1, struct FutureXSRevocation);

    rev->precedent_f = sv_rvweaken(newSVsv(f));
    rev->toclear_sv_at = sv_rvweaken(newRV_inc(rv));

    struct FutureXS *codeself = get_future(code);
    if(!codeself->revoke_when_ready)
      codeself->revoke_when_ready = newAV();

    av_push(codeself->revoke_when_ready, (SV *)rev);
  }
}

void Future_on_ready(pTHX_ SV *f, SV *code)

src/future.c  view on Meta::CPAN


  if(!self->pending_subs) {
    self->result = newAV_svn_dup(subs, n);
    mark_ready(self, f, "wait_all");

    return f;
  }

  CV *sub_on_ready = newXS(NULL, sub_on_ready_waitall, __FILE__);
  cv_set_anysv_refcounted(sub_on_ready, newSVsv(f));
  sv_rvweaken(CvXSUBANY_sv(sub_on_ready));

  GV *gv = gv_fetchpvs("Future::XS::(wait_all callback)", GV_ADDMULTI, SVt_PVCV);
  CvGV_set(sub_on_ready, gv);
  CvANON_off(sub_on_ready);

  for(Size_t i = 0; i < n; i++) {
    if(!future_is_ready(subs[i]))
      future_on_ready(subs[i], sv_2mortal(newRV_inc((SV *)sub_on_ready)));
  }

src/future.c  view on Meta::CPAN


    mark_ready(self, f, "wait_any");

    return f;
  }

  self->pending_subs = 0;

  CV *sub_on_ready = newXS(NULL, sub_on_ready_waitany, __FILE__);
  cv_set_anysv_refcounted(sub_on_ready, newSVsv(f));
  sv_rvweaken(CvXSUBANY_sv(sub_on_ready));

  GV *gv = gv_fetchpvs("Future::XS::(wait_any callback)", GV_ADDMULTI, SVt_PVCV);
  CvGV_set(sub_on_ready, gv);
  CvANON_off(sub_on_ready);

  for(Size_t i = 0; i < n; i++) {
    if(future_is_cancelled(subs[i]))
      continue;

    future_on_ready(subs[i], sv_2mortal(newRV_inc((SV *)sub_on_ready)));

src/future.c  view on Meta::CPAN

    copy_result(self, immediate_fail);
    cancel_pending_subs(self);
    mark_ready(self, f, "needs_all");
    return f;
  }

  self->pending_subs = 0;

  CV *sub_on_ready = newXS(NULL, sub_on_ready_needsall, __FILE__);
  cv_set_anysv_refcounted(sub_on_ready, newSVsv(f));
  sv_rvweaken(CvXSUBANY_sv(sub_on_ready));

  GV *gv = gv_fetchpvs("Future::XS::(needs_all callback)", GV_ADDMULTI, SVt_PVCV);
  CvGV_set(sub_on_ready, gv);
  CvANON_off(sub_on_ready);

  for(Size_t i = 0; i < n; i++) {
    if(future_is_ready(subs[i]))
      continue;

    future_on_ready(subs[i], sv_2mortal(newRV_inc((SV *)sub_on_ready)));

src/future.c  view on Meta::CPAN

    copy_result(self, immediate_done);
    cancel_pending_subs(self);
    mark_ready(self, f, "needs_any");
    return f;
  }

  self->pending_subs = 0;

  CV *sub_on_ready = newXS(NULL, sub_on_ready_needsany, __FILE__);
  cv_set_anysv_refcounted(sub_on_ready, newSVsv(f));
  sv_rvweaken(CvXSUBANY_sv(sub_on_ready));

  GV *gv = gv_fetchpvs("Future::XS::(needs_any callback)", GV_ADDMULTI, SVt_PVCV);
  CvGV_set(sub_on_ready, gv);
  CvANON_off(sub_on_ready);

  for(Size_t i = 0; i < n; i++) {
    if(future_is_ready(subs[i]))
      continue;

    future_on_ready(subs[i], sv_2mortal(newRV_inc((SV *)sub_on_ready)));



( run in 0.267 second using v1.01-cache-2.11-cpan-0d8aa00de5b )