… | |
… | |
1839 | } |
1839 | } |
1840 | while (slf_frame.check (aTHX_ &slf_frame)); |
1840 | while (slf_frame.check (aTHX_ &slf_frame)); |
1841 | |
1841 | |
1842 | slf_frame.prepare = 0; /* invalidate the frame, we are done processing it */ |
1842 | slf_frame.prepare = 0; /* invalidate the frame, we are done processing it */ |
1843 | |
1843 | |
|
|
1844 | /* exception handling */ |
|
|
1845 | if (expect_false (coro_throw)) |
|
|
1846 | { |
|
|
1847 | SV *exception = sv_2mortal (coro_throw); |
|
|
1848 | |
|
|
1849 | coro_throw = 0; |
|
|
1850 | sv_setsv (ERRSV, exception); |
|
|
1851 | croak (0); |
|
|
1852 | } |
|
|
1853 | |
1844 | /* return value handling - mostly like entersub */ |
1854 | /* return value handling - mostly like entersub */ |
1845 | /* make sure we put something on the stack in scalar context */ |
1855 | /* make sure we put something on the stack in scalar context */ |
1846 | if (GIMME_V == G_SCALAR) |
1856 | if (GIMME_V == G_SCALAR) |
1847 | { |
1857 | { |
1848 | dSP; |
1858 | dSP; |
… | |
… | |
1854 | bot [1] = *sp; |
1864 | bot [1] = *sp; |
1855 | |
1865 | |
1856 | SP = bot + 1; |
1866 | SP = bot + 1; |
1857 | |
1867 | |
1858 | PUTBACK; |
1868 | PUTBACK; |
1859 | } |
|
|
1860 | |
|
|
1861 | /* exception handling */ |
|
|
1862 | if (expect_false (coro_throw)) |
|
|
1863 | { |
|
|
1864 | SV *exception = sv_2mortal (coro_throw); |
|
|
1865 | |
|
|
1866 | coro_throw = 0; |
|
|
1867 | sv_setsv (ERRSV, exception); |
|
|
1868 | croak (0); |
|
|
1869 | } |
1869 | } |
1870 | |
1870 | |
1871 | return NORMAL; |
1871 | return NORMAL; |
1872 | } |
1872 | } |
1873 | |
1873 | |
… | |
… | |
2040 | slf_check_semaphore_down (pTHX_ struct CoroSLF *frame) |
2040 | slf_check_semaphore_down (pTHX_ struct CoroSLF *frame) |
2041 | { |
2041 | { |
2042 | AV *av = (AV *)frame->data; |
2042 | AV *av = (AV *)frame->data; |
2043 | SV *count_sv = AvARRAY (av)[0]; |
2043 | SV *count_sv = AvARRAY (av)[0]; |
2044 | |
2044 | |
|
|
2045 | /* if we are about to throw, don't actually acquire the lock, just throw */ |
|
|
2046 | if (coro_throw) |
|
|
2047 | return 0; |
2045 | if (SvIVX (count_sv) > 0) |
2048 | else if (SvIVX (count_sv) > 0) |
2046 | { |
2049 | { |
2047 | SvSTATE_current->on_destroy = 0; |
2050 | SvSTATE_current->on_destroy = 0; |
2048 | SvIVX (count_sv) = SvIVX (count_sv) - 1; |
2051 | SvIVX (count_sv) = SvIVX (count_sv) - 1; |
2049 | return 0; |
2052 | return 0; |
2050 | } |
2053 | } |
… | |
… | |
2071 | |
2074 | |
2072 | if (SvIVX (AvARRAY (av)[0]) > 0) |
2075 | if (SvIVX (AvARRAY (av)[0]) > 0) |
2073 | { |
2076 | { |
2074 | frame->data = (void *)av; |
2077 | frame->data = (void *)av; |
2075 | frame->prepare = prepare_nop; |
2078 | frame->prepare = prepare_nop; |
2076 | SvSTATE_current->on_destroy = coro_semaphore_on_destroy; |
|
|
2077 | } |
2079 | } |
2078 | else |
2080 | else |
2079 | { |
2081 | { |
2080 | av_push (av, SvREFCNT_inc (SvRV (coro_current))); |
2082 | av_push (av, SvREFCNT_inc (SvRV (coro_current))); |
2081 | |
2083 | |
2082 | frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av)); |
2084 | frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av)); |
2083 | frame->prepare = prepare_schedule; |
2085 | frame->prepare = prepare_schedule; |
2084 | |
2086 | |
2085 | /* to avoid race conditions when a woken-up coro gets terminated */ |
2087 | /* to avoid race conditions when a woken-up coro gets terminated */ |
2086 | /* we arrange for a temporary on_destroy that calls adjust (0) */ |
2088 | /* we arrange for a temporary on_destroy that calls adjust (0) */ |
2087 | assert (!SvSTATE_current->on_destroy);//D |
|
|
2088 | SvSTATE_current->on_destroy = coro_semaphore_on_destroy; |
2089 | SvSTATE_current->on_destroy = coro_semaphore_on_destroy; |
2089 | } |
2090 | } |
2090 | |
2091 | |
2091 | frame->check = slf_check_semaphore_down; |
2092 | frame->check = slf_check_semaphore_down; |
2092 | |
2093 | |
… | |
… | |
2169 | |
2170 | |
2170 | static int |
2171 | static int |
2171 | slf_check_aio_req (pTHX_ struct CoroSLF *frame) |
2172 | slf_check_aio_req (pTHX_ struct CoroSLF *frame) |
2172 | { |
2173 | { |
2173 | AV *state = (AV *)frame->data; |
2174 | AV *state = (AV *)frame->data; |
|
|
2175 | |
|
|
2176 | /* if we are about to throw, return early */ |
|
|
2177 | /* this does not cancel the aio request, but at least */ |
|
|
2178 | /* it quickly returns */ |
|
|
2179 | if (coro_throw) |
|
|
2180 | return 0; |
2174 | |
2181 | |
2175 | /* one element that is an RV? repeat! */ |
2182 | /* one element that is an RV? repeat! */ |
2176 | if (AvFILLp (state) == 0 && SvROK (AvARRAY (state)[0])) |
2183 | if (AvFILLp (state) == 0 && SvROK (AvARRAY (state)[0])) |
2177 | return 1; |
2184 | return 1; |
2178 | |
2185 | |