… | |
… | |
2631 | { |
2631 | { |
2632 | /* callback form */ |
2632 | /* callback form */ |
2633 | AV *av = (AV *)SvRV (arg [0]); |
2633 | AV *av = (AV *)SvRV (arg [0]); |
2634 | CV *cb_cv = coro_sv_2cv (aTHX_ arg [1]); |
2634 | CV *cb_cv = coro_sv_2cv (aTHX_ arg [1]); |
2635 | |
2635 | |
2636 | av_push (av, (SV *)SvREFCNT_inc_NN (cb_cv)); |
2636 | av_push (av, SvREFCNT_inc_NN (cb_cv)); |
2637 | |
2637 | |
2638 | if (SvIVX (AvARRAY (av)[0]) > 0) |
2638 | if (SvIVX (AvARRAY (av)[0]) > 0) |
2639 | coro_semaphore_adjust (aTHX_ av, 0); |
2639 | coro_semaphore_adjust (aTHX_ av, 0); |
2640 | |
2640 | |
2641 | frame->prepare = prepare_nop; |
2641 | frame->prepare = prepare_nop; |
… | |
… | |
2665 | AvARRAY (av)[0] = AvARRAY (av)[1]; |
2665 | AvARRAY (av)[0] = AvARRAY (av)[1]; |
2666 | AvARRAY (av)[1] = cb; |
2666 | AvARRAY (av)[1] = cb; |
2667 | |
2667 | |
2668 | cb = av_shift (av); |
2668 | cb = av_shift (av); |
2669 | |
2669 | |
|
|
2670 | if (SvTYPE (cb) == SVt_PVCV) |
|
|
2671 | { |
|
|
2672 | dSP; |
|
|
2673 | PUSHMARK (SP); |
|
|
2674 | XPUSHs (sv_2mortal (newRV_inc ((SV *)av))); |
|
|
2675 | PUTBACK; |
|
|
2676 | call_sv (cb, G_VOID | G_DISCARD | G_EVAL | G_KEEPERR); |
|
|
2677 | } |
|
|
2678 | else |
|
|
2679 | { |
2670 | api_ready (aTHX_ cb); |
2680 | api_ready (aTHX_ cb); |
2671 | sv_setiv (cb, 0); /* signal waiter */ |
2681 | sv_setiv (cb, 0); /* signal waiter */ |
|
|
2682 | } |
|
|
2683 | |
2672 | SvREFCNT_dec (cb); |
2684 | SvREFCNT_dec (cb); |
2673 | |
2685 | |
2674 | --count; |
2686 | --count; |
2675 | } |
2687 | } |
2676 | } |
2688 | } |
… | |
… | |
2685 | static void |
2697 | static void |
2686 | slf_init_signal_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items) |
2698 | slf_init_signal_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items) |
2687 | { |
2699 | { |
2688 | AV *av = (AV *)SvRV (arg [0]); |
2700 | AV *av = (AV *)SvRV (arg [0]); |
2689 | |
2701 | |
|
|
2702 | if (items >= 2) |
|
|
2703 | { |
|
|
2704 | CV *cb_cv = coro_sv_2cv (aTHX_ arg [1]); |
|
|
2705 | av_push (av, SvREFCNT_inc_NN (cb_cv)); |
|
|
2706 | |
2690 | if (SvIVX (AvARRAY (av)[0])) |
2707 | if (SvIVX (AvARRAY (av)[0])) |
|
|
2708 | coro_signal_wake (aTHX_ av, 1); /* ust be the only waiter */ |
|
|
2709 | |
|
|
2710 | frame->prepare = prepare_nop; |
|
|
2711 | frame->check = slf_check_nop; |
|
|
2712 | } |
|
|
2713 | else if (SvIVX (AvARRAY (av)[0])) |
2691 | { |
2714 | { |
2692 | SvIVX (AvARRAY (av)[0]) = 0; |
2715 | SvIVX (AvARRAY (av)[0]) = 0; |
2693 | frame->prepare = prepare_nop; |
2716 | frame->prepare = prepare_nop; |
2694 | frame->check = slf_check_nop; |
2717 | frame->check = slf_check_nop; |
2695 | } |
2718 | } |
2696 | else |
2719 | else |
2697 | { |
2720 | { |
2698 | SV *waiter = newRV_inc (SvRV (coro_current)); /* owned by signal av */ |
2721 | SV *waiter = newSVsv (coro_current); /* owned by signal av */ |
2699 | |
2722 | |
2700 | av_push (av, waiter); |
2723 | av_push (av, waiter); |
2701 | |
2724 | |
2702 | frame->data = (void *)sv_2mortal (SvREFCNT_inc_NN (waiter)); /* owned by process */ |
2725 | frame->data = (void *)sv_2mortal (SvREFCNT_inc_NN (waiter)); /* owned by process */ |
2703 | frame->prepare = prepare_schedule; |
2726 | frame->prepare = prepare_schedule; |