… | |
… | |
937 | cctx_first = cctx; |
937 | cctx_first = cctx; |
938 | } |
938 | } |
939 | |
939 | |
940 | /** coroutine switching *****************************************************/ |
940 | /** coroutine switching *****************************************************/ |
941 | |
941 | |
942 | /* never call directly, always through the coro_state_transfer global variable */ |
942 | static void NOINLINE |
|
|
943 | transfer_check (pTHX_ struct coro *prev, struct coro *next) |
|
|
944 | { |
|
|
945 | if (prev != next) |
|
|
946 | { |
|
|
947 | if (!(prev->flags & (CF_RUNNING | CF_NEW))) |
|
|
948 | croak ("Coro::State::transfer called with non-running/new prev Coro::State, but can only transfer from running or new states"); |
|
|
949 | |
|
|
950 | if (next->flags & CF_RUNNING) |
|
|
951 | croak ("Coro::State::transfer called with running next Coro::State, but can only transfer to inactive states"); |
|
|
952 | |
|
|
953 | if (next->flags & CF_DESTROYED) |
|
|
954 | croak ("Coro::State::transfer called with destroyed next Coro::State, but can only transfer to inactive states"); |
|
|
955 | |
|
|
956 | if (PL_lex_state != LEX_NOTPARSING) |
|
|
957 | croak ("Coro::State::transfer called while parsing, but this is not supported"); |
|
|
958 | } |
|
|
959 | } |
|
|
960 | |
|
|
961 | /* always use the TRANSFER macro */ |
943 | static void NOINLINE |
962 | static void NOINLINE |
944 | transfer (pTHX_ struct coro *prev, struct coro *next) |
963 | transfer (pTHX_ struct coro *prev, struct coro *next) |
945 | { |
964 | { |
946 | dSTACKLEVEL; |
965 | dSTACKLEVEL; |
947 | |
966 | |
… | |
… | |
960 | /* create a new empty context */ |
979 | /* create a new empty context */ |
961 | Newz (0, prev->cctx, 1, coro_cctx); |
980 | Newz (0, prev->cctx, 1, coro_cctx); |
962 | prev->flags &= ~CF_NEW; |
981 | prev->flags &= ~CF_NEW; |
963 | prev->flags |= CF_RUNNING; |
982 | prev->flags |= CF_RUNNING; |
964 | } |
983 | } |
965 | |
|
|
966 | /*TODO: must not croak here */ |
|
|
967 | if (!prev->flags & CF_RUNNING) |
|
|
968 | croak ("Coro::State::transfer called with non-running prev Coro::State, but can only transfer from running states"); |
|
|
969 | |
|
|
970 | if (next->flags & CF_RUNNING) |
|
|
971 | croak ("Coro::State::transfer called with running next Coro::State, but can only transfer to inactive states"); |
|
|
972 | |
|
|
973 | if (next->flags & CF_DESTROYED) |
|
|
974 | croak ("Coro::State::transfer called with destroyed next Coro::State, but can only transfer to inactive states"); |
|
|
975 | |
984 | |
976 | prev->flags &= ~CF_RUNNING; |
985 | prev->flags &= ~CF_RUNNING; |
977 | next->flags |= CF_RUNNING; |
986 | next->flags |= CF_RUNNING; |
978 | |
987 | |
979 | LOCK; |
988 | LOCK; |
… | |
… | |
1026 | { |
1035 | { |
1027 | struct coro *prev, *next; |
1036 | struct coro *prev, *next; |
1028 | }; |
1037 | }; |
1029 | |
1038 | |
1030 | #define TRANSFER(ta) transfer (aTHX_ (ta).prev, (ta).next) |
1039 | #define TRANSFER(ta) transfer (aTHX_ (ta).prev, (ta).next) |
|
|
1040 | #define TRANSFER_CHECK(ta) transfer_check (aTHX_ (ta).prev, (ta).next) |
1031 | |
1041 | |
1032 | /** high level stuff ********************************************************/ |
1042 | /** high level stuff ********************************************************/ |
1033 | |
1043 | |
1034 | static int |
1044 | static int |
1035 | coro_state_destroy (pTHX_ struct coro *coro) |
1045 | coro_state_destroy (pTHX_ struct coro *coro) |
… | |
… | |
1123 | static void |
1133 | static void |
1124 | prepare_transfer (pTHX_ struct transfer_args *ta, SV *prev_sv, SV *next_sv) |
1134 | prepare_transfer (pTHX_ struct transfer_args *ta, SV *prev_sv, SV *next_sv) |
1125 | { |
1135 | { |
1126 | ta->prev = SvSTATE (prev_sv); |
1136 | ta->prev = SvSTATE (prev_sv); |
1127 | ta->next = SvSTATE (next_sv); |
1137 | ta->next = SvSTATE (next_sv); |
|
|
1138 | TRANSFER_CHECK (*ta); |
1128 | } |
1139 | } |
1129 | |
1140 | |
1130 | static void |
1141 | static void |
1131 | api_transfer (SV *prev_sv, SV *next_sv) |
1142 | api_transfer (SV *prev_sv, SV *next_sv) |
1132 | { |
1143 | { |
… | |
… | |
1249 | break; |
1260 | break; |
1250 | } |
1261 | } |
1251 | |
1262 | |
1252 | /* free this only after the transfer */ |
1263 | /* free this only after the transfer */ |
1253 | prev_sv = SvRV (coro_current); |
1264 | prev_sv = SvRV (coro_current); |
1254 | SvRV_set (coro_current, next_sv); |
|
|
1255 | ta->prev = SvSTATE (prev_sv); |
1265 | ta->prev = SvSTATE (prev_sv); |
1256 | |
1266 | TRANSFER_CHECK (*ta); |
1257 | assert (ta->next->flags & CF_READY); |
1267 | assert (ta->next->flags & CF_READY); |
1258 | ta->next->flags &= ~CF_READY; |
1268 | ta->next->flags &= ~CF_READY; |
|
|
1269 | SvRV_set (coro_current, next_sv); |
1259 | |
1270 | |
1260 | LOCK; |
1271 | LOCK; |
1261 | free_coro_mortal (aTHX); |
1272 | free_coro_mortal (aTHX); |
1262 | coro_mortal = prev_sv; |
1273 | coro_mortal = prev_sv; |
1263 | UNLOCK; |
1274 | UNLOCK; |