… | |
… | |
2035 | /* call $sem->adjust (0) to possibly wake up some other waiters */ |
2035 | /* call $sem->adjust (0) to possibly wake up some other waiters */ |
2036 | coro_semaphore_adjust (aTHX_ (AV *)coro->slf_frame.data, 0); |
2036 | coro_semaphore_adjust (aTHX_ (AV *)coro->slf_frame.data, 0); |
2037 | } |
2037 | } |
2038 | |
2038 | |
2039 | static int |
2039 | static int |
2040 | slf_check_semaphore_down (pTHX_ struct CoroSLF *frame) |
2040 | slf_check_semaphore_down_or_wait (pTHX_ struct CoroSLF *frame, int acquire) |
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 */ |
2045 | /* if we are about to throw, don't actually acquire the lock, just throw */ |
2046 | if (CORO_THROW) |
2046 | if (CORO_THROW) |
2047 | return 0; |
2047 | return 0; |
2048 | else if (SvIVX (count_sv) > 0) |
2048 | else if (SvIVX (count_sv) > 0) |
2049 | { |
2049 | { |
2050 | SvSTATE_current->on_destroy = 0; |
2050 | SvSTATE_current->on_destroy = 0; |
|
|
2051 | |
|
|
2052 | if (acquire) |
2051 | SvIVX (count_sv) = SvIVX (count_sv) - 1; |
2053 | SvIVX (count_sv) = SvIVX (count_sv) - 1; |
|
|
2054 | else |
|
|
2055 | coro_semaphore_adjust (aTHX_ av, 0); |
|
|
2056 | |
2052 | return 0; |
2057 | return 0; |
2053 | } |
2058 | } |
2054 | else |
2059 | else |
2055 | { |
2060 | { |
2056 | int i; |
2061 | int i; |
… | |
… | |
2065 | av_push (av, SvREFCNT_inc (SvRV (coro_current))); |
2070 | av_push (av, SvREFCNT_inc (SvRV (coro_current))); |
2066 | return 1; |
2071 | return 1; |
2067 | } |
2072 | } |
2068 | } |
2073 | } |
2069 | |
2074 | |
2070 | static void |
2075 | static int |
|
|
2076 | slf_check_semaphore_down (pTHX_ struct CoroSLF *frame) |
|
|
2077 | { |
|
|
2078 | return slf_check_semaphore_down_or_wait (aTHX_ frame, 1); |
|
|
2079 | } |
|
|
2080 | |
|
|
2081 | static int |
|
|
2082 | slf_check_semaphore_wait (pTHX_ struct CoroSLF *frame) |
|
|
2083 | { |
|
|
2084 | return slf_check_semaphore_down_or_wait (aTHX_ frame, 0); |
|
|
2085 | } |
|
|
2086 | |
|
|
2087 | static void |
2071 | slf_init_semaphore_down (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items) |
2088 | slf_init_semaphore_down_or_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items) |
2072 | { |
2089 | { |
2073 | AV *av = (AV *)SvRV (arg [0]); |
2090 | AV *av = (AV *)SvRV (arg [0]); |
2074 | |
2091 | |
2075 | if (SvIVX (AvARRAY (av)[0]) > 0) |
2092 | if (SvIVX (AvARRAY (av)[0]) > 0) |
2076 | { |
2093 | { |
… | |
… | |
2086 | |
2103 | |
2087 | /* to avoid race conditions when a woken-up coro gets terminated */ |
2104 | /* to avoid race conditions when a woken-up coro gets terminated */ |
2088 | /* we arrange for a temporary on_destroy that calls adjust (0) */ |
2105 | /* we arrange for a temporary on_destroy that calls adjust (0) */ |
2089 | SvSTATE_current->on_destroy = coro_semaphore_on_destroy; |
2106 | SvSTATE_current->on_destroy = coro_semaphore_on_destroy; |
2090 | } |
2107 | } |
|
|
2108 | } |
2091 | |
2109 | |
|
|
2110 | static void |
|
|
2111 | slf_init_semaphore_down (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items) |
|
|
2112 | { |
|
|
2113 | slf_init_semaphore_down_or_wait (aTHX_ frame, cv, arg, items); |
2092 | frame->check = slf_check_semaphore_down; |
2114 | frame->check = slf_check_semaphore_down; |
|
|
2115 | } |
2093 | |
2116 | |
|
|
2117 | static void |
|
|
2118 | slf_init_semaphore_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items) |
|
|
2119 | { |
|
|
2120 | slf_init_semaphore_down_or_wait (aTHX_ frame, cv, arg, items); |
|
|
2121 | frame->check = slf_check_semaphore_wait; |
2094 | } |
2122 | } |
2095 | |
2123 | |
2096 | /*****************************************************************************/ |
2124 | /*****************************************************************************/ |
2097 | /* gensub: simple closure generation utility */ |
2125 | /* gensub: simple closure generation utility */ |
2098 | |
2126 | |
… | |
… | |
2812 | down (SV *self) |
2840 | down (SV *self) |
2813 | CODE: |
2841 | CODE: |
2814 | CORO_EXECUTE_SLF_XS (slf_init_semaphore_down); |
2842 | CORO_EXECUTE_SLF_XS (slf_init_semaphore_down); |
2815 | |
2843 | |
2816 | void |
2844 | void |
|
|
2845 | wait (SV *self) |
|
|
2846 | CODE: |
|
|
2847 | CORO_EXECUTE_SLF_XS (slf_init_semaphore_wait); |
|
|
2848 | |
|
|
2849 | void |
2817 | try (SV *self) |
2850 | try (SV *self) |
2818 | PPCODE: |
2851 | PPCODE: |
2819 | { |
2852 | { |
2820 | AV *av = (AV *)SvRV (self); |
2853 | AV *av = (AV *)SvRV (self); |
2821 | SV *count_sv = AvARRAY (av)[0]; |
2854 | SV *count_sv = AvARRAY (av)[0]; |