ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/State.xs
(Generate patch)

Comparing Coro/Coro/State.xs (file contents):
Revision 1.364 by root, Thu Jul 16 02:19:17 2009 UTC vs.
Revision 1.372 by root, Thu Oct 1 23:50:23 2009 UTC

142static SV *sv_pool_size; 142static SV *sv_pool_size;
143static SV *sv_async_pool_idle; /* description string */ 143static SV *sv_async_pool_idle; /* description string */
144static AV *av_async_pool; /* idle pool */ 144static AV *av_async_pool; /* idle pool */
145static SV *sv_Coro; /* class string */ 145static SV *sv_Coro; /* class string */
146static CV *cv_pool_handler; 146static CV *cv_pool_handler;
147static CV *cv_coro_state_new;
148 147
149/* Coro::AnyEvent */ 148/* Coro::AnyEvent */
150static SV *sv_activity; 149static SV *sv_activity;
151 150
152/* enable processtime/realtime profiling */ 151/* enable processtime/realtime profiling */
290static OP *(*coro_old_pp_sselect) (pTHX); 289static OP *(*coro_old_pp_sselect) (pTHX);
291static SV *coro_select_select; 290static SV *coro_select_select;
292 291
293/* horrible hack, but if it works... */ 292/* horrible hack, but if it works... */
294static OP * 293static OP *
295coro_pp_sselect (aTHX) 294coro_pp_sselect (pTHX)
296{ 295{
297 dSP; 296 dSP;
298 PUSHMARK (SP - 4); /* fake argument list */ 297 PUSHMARK (SP - 4); /* fake argument list */
299 XPUSHs (coro_select_select); 298 XPUSHs (coro_select_select);
300 PUTBACK; 299 PUTBACK;
1275 /* somebody or something will hit me for both perl_run and PL_restartop */ 1274 /* somebody or something will hit me for both perl_run and PL_restartop */
1276 PL_restartop = PL_op; 1275 PL_restartop = PL_op;
1277 perl_run (PL_curinterp); 1276 perl_run (PL_curinterp);
1278 /* 1277 /*
1279 * Unfortunately, there is no way to get at the return values of the 1278 * Unfortunately, there is no way to get at the return values of the
1280 * coro body here, as perl_run destroys these 1279 * coro body here, as perl_run destroys these. Likewise, we cannot catch
1280 * runtime errors here, as this is just a random interpreter, not a thread.
1281 */ 1281 */
1282 1282
1283 /* 1283 /*
1284 * If perl-run returns we assume exit() was being called or the coro 1284 * If perl-run returns we assume exit() was being called or the coro
1285 * fell off the end, which seems to be the only valid (non-bug) 1285 * fell off the end, which seems to be the only valid (non-bug)
1668 } 1668 }
1669 1669
1670 return 0; 1670 return 0;
1671} 1671}
1672 1672
1673static void
1674invoke_sv_ready_hook_helper (void)
1675{
1676 dTHX;
1677 dSP;
1678
1679 ENTER;
1680 SAVETMPS;
1681
1682 PUSHMARK (SP);
1683 PUTBACK;
1684 call_sv (coro_readyhook, G_VOID | G_DISCARD);
1685
1686 FREETMPS;
1687 LEAVE;
1688}
1689
1673static int 1690static int
1674api_ready (pTHX_ SV *coro_sv) 1691api_ready (pTHX_ SV *coro_sv)
1675{ 1692{
1676 struct coro *coro;
1677 SV *sv_hook;
1678 void (*xs_hook)(void);
1679
1680 coro = SvSTATE (coro_sv); 1693 struct coro *coro = SvSTATE (coro_sv);
1681 1694
1682 if (coro->flags & CF_READY) 1695 if (coro->flags & CF_READY)
1683 return 0; 1696 return 0;
1684 1697
1685 coro->flags |= CF_READY; 1698 coro->flags |= CF_READY;
1686 1699
1687 sv_hook = coro_nready ? 0 : coro_readyhook;
1688 xs_hook = coro_nready ? 0 : coroapi.readyhook;
1689
1690 coro_enq (aTHX_ coro); 1700 coro_enq (aTHX_ coro);
1691 ++coro_nready;
1692 1701
1693 if (sv_hook) 1702 if (!coro_nready++)
1694 { 1703 if (coroapi.readyhook)
1695 dSP; 1704 coroapi.readyhook ();
1696
1697 ENTER;
1698 SAVETMPS;
1699
1700 PUSHMARK (SP);
1701 PUTBACK;
1702 call_sv (sv_hook, G_VOID | G_DISCARD);
1703
1704 FREETMPS;
1705 LEAVE;
1706 }
1707
1708 if (xs_hook)
1709 xs_hook ();
1710 1705
1711 return 1; 1706 return 1;
1712} 1707}
1713 1708
1714static int 1709static int
1765 api_ready (aTHX_ SvRV (sv_idle)); 1760 api_ready (aTHX_ SvRV (sv_idle));
1766 --coro_nready; 1761 --coro_nready;
1767 } 1762 }
1768 else 1763 else
1769 { 1764 {
1765 /* TODO: deprecated, remove, cannot work reliably *//*D*/
1770 dSP; 1766 dSP;
1771 1767
1772 ENTER; 1768 ENTER;
1773 SAVETMPS; 1769 SAVETMPS;
1774 1770
1920{ 1916{
1921 int i; 1917 int i;
1922 HV *hv = (HV *)SvRV (coro_current); 1918 HV *hv = (HV *)SvRV (coro_current);
1923 AV *av = newAV (); 1919 AV *av = newAV ();
1924 1920
1921 /* items are actually not so common, so optimise for this case */
1922 if (items)
1923 {
1925 av_extend (av, items - 1); 1924 av_extend (av, items - 1);
1925
1926 for (i = 0; i < items; ++i) 1926 for (i = 0; i < items; ++i)
1927 av_push (av, SvREFCNT_inc_NN (arg [i])); 1927 av_push (av, SvREFCNT_inc_NN (arg [i]));
1928 }
1928 1929
1929 hv_store (hv, "_status", sizeof ("_status") - 1, newRV_noinc ((SV *)av), 0); 1930 hv_store (hv, "_status", sizeof ("_status") - 1, newRV_noinc ((SV *)av), 0);
1930 1931
1931 av_push (av_destroy, (SV *)newRV_inc ((SV *)hv)); /* RVinc for perl */ 1932 av_push (av_destroy, (SV *)newRV_inc ((SV *)hv)); /* RVinc for perl */
1932 api_ready (aTHX_ sv_manager); 1933 api_ready (aTHX_ sv_manager);
2330 if (PL_op->op_ppaddr != PL_ppaddr [OP_ENTERSUB] 2331 if (PL_op->op_ppaddr != PL_ppaddr [OP_ENTERSUB]
2331 && PL_op->op_ppaddr != pp_slf) 2332 && PL_op->op_ppaddr != pp_slf)
2332 croak ("FATAL: Coro SLF calls can only be made normally, not via goto or any other means, caught"); 2333 croak ("FATAL: Coro SLF calls can only be made normally, not via goto or any other means, caught");
2333 2334
2334 CvFLAGS (cv) |= CVf_SLF; 2335 CvFLAGS (cv) |= CVf_SLF;
2336 CvNODEBUG_on (cv);
2335 CvXSUBANY (cv).any_ptr = (void *)init_cb; 2337 CvXSUBANY (cv).any_ptr = (void *)init_cb;
2336 slf_cv = cv; 2338 slf_cv = cv;
2337 2339
2338 /* we patch the op, and then re-run the whole call */ 2340 /* we patch the op, and then re-run the whole call */
2339 /* we have to put the same argument on the stack for this to work */ 2341 /* we have to put the same argument on the stack for this to work */
2914 2916
2915#if CORO_CLONE 2917#if CORO_CLONE
2916# include "clone.c" 2918# include "clone.c"
2917#endif 2919#endif
2918 2920
2921/*****************************************************************************/
2922
2923static SV *
2924coro_new (pTHX_ HV *stash, SV **argv, int argc, int is_coro)
2925{
2926 SV *coro_sv;
2927 struct coro *coro;
2928 MAGIC *mg;
2929 HV *hv;
2930 SV *cb;
2931 int i;
2932
2933 if (argc > 0)
2934 {
2935 cb = s_get_cv_croak (argv [0]);
2936
2937 if (!is_coro)
2938 {
2939 if (CvISXSUB (cb))
2940 croak ("Coro::State doesn't support XS functions as coroutine start, caught");
2941
2942 if (!CvROOT (cb))
2943 croak ("Coro::State doesn't support autoloaded or undefined functions as coroutine start, caught");
2944 }
2945 }
2946
2947 Newz (0, coro, 1, struct coro);
2948 coro->args = newAV ();
2949 coro->flags = CF_NEW;
2950
2951 if (coro_first) coro_first->prev = coro;
2952 coro->next = coro_first;
2953 coro_first = coro;
2954
2955 coro->hv = hv = newHV ();
2956 mg = sv_magicext ((SV *)hv, 0, CORO_MAGIC_type_state, &coro_state_vtbl, (char *)coro, 0);
2957 mg->mg_flags |= MGf_DUP;
2958 coro_sv = sv_bless (newRV_noinc ((SV *)hv), stash);
2959
2960 if (argc > 0)
2961 {
2962 av_extend (coro->args, argc + is_coro - 1);
2963
2964 if (is_coro)
2965 {
2966 av_push (coro->args, SvREFCNT_inc_NN ((SV *)cb));
2967 cb = (SV *)cv_coro_run;
2968 }
2969
2970 coro->startcv = (CV *)SvREFCNT_inc_NN ((SV *)cb);
2971
2972 for (i = 1; i < argc; i++)
2973 av_push (coro->args, newSVsv (argv [i]));
2974 }
2975
2976 return coro_sv;
2977}
2978
2919MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_ 2979MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_
2920 2980
2921PROTOTYPES: DISABLE 2981PROTOTYPES: DISABLE
2922 2982
2923BOOT: 2983BOOT:
2991 3051
2992 assert (("PRIO_NORMAL must be 0", !CORO_PRIO_NORMAL)); 3052 assert (("PRIO_NORMAL must be 0", !CORO_PRIO_NORMAL));
2993} 3053}
2994 3054
2995SV * 3055SV *
2996new (char *klass, ...) 3056new (SV *klass, ...)
2997 ALIAS: 3057 ALIAS:
2998 Coro::new = 1 3058 Coro::new = 1
2999 CODE: 3059 CODE:
3000{ 3060 RETVAL = coro_new (aTHX_ ix ? coro_stash : coro_state_stash, &ST (1), items - 1, ix);
3001 struct coro *coro; 3061 OUTPUT:
3002 MAGIC *mg;
3003 HV *hv;
3004 SV *cb;
3005 int i;
3006
3007 if (items > 1)
3008 {
3009 cb = s_get_cv_croak (ST (1));
3010
3011 if (!ix)
3012 {
3013 if (CvISXSUB (cb))
3014 croak ("Coro::State doesn't support XS functions as coroutine start, caught");
3015
3016 if (!CvROOT (cb))
3017 croak ("Coro::State doesn't support autoloaded or undefined functions as coroutine start, caught");
3018 }
3019 }
3020
3021 Newz (0, coro, 1, struct coro);
3022 coro->args = newAV ();
3023 coro->flags = CF_NEW;
3024
3025 if (coro_first) coro_first->prev = coro;
3026 coro->next = coro_first;
3027 coro_first = coro;
3028
3029 coro->hv = hv = newHV ();
3030 mg = sv_magicext ((SV *)hv, 0, CORO_MAGIC_type_state, &coro_state_vtbl, (char *)coro, 0);
3031 mg->mg_flags |= MGf_DUP;
3032 RETVAL = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1));
3033
3034 if (items > 1)
3035 {
3036 av_extend (coro->args, items - 1 + ix - 1);
3037
3038 if (ix)
3039 {
3040 av_push (coro->args, SvREFCNT_inc_NN ((SV *)cb));
3041 cb = (SV *)cv_coro_run;
3042 }
3043
3044 coro->startcv = (CV *)SvREFCNT_inc_NN ((SV *)cb);
3045
3046 for (i = 2; i < items; i++)
3047 av_push (coro->args, newSVsv (ST (i)));
3048 }
3049}
3050 OUTPUT:
3051 RETVAL 3062 RETVAL
3052 3063
3053void 3064void
3054transfer (...) 3065transfer (...)
3055 PROTOTYPE: $$ 3066 PROTOTYPE: $$
3322 sv_idle = coro_get_sv (aTHX_ "Coro::idle" , TRUE); 3333 sv_idle = coro_get_sv (aTHX_ "Coro::idle" , TRUE);
3323 3334
3324 sv_async_pool_idle = newSVpv ("[async pool idle]", 0); SvREADONLY_on (sv_async_pool_idle); 3335 sv_async_pool_idle = newSVpv ("[async pool idle]", 0); SvREADONLY_on (sv_async_pool_idle);
3325 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro); 3336 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro);
3326 cv_pool_handler = get_cv ("Coro::pool_handler", GV_ADD); SvREADONLY_on (cv_pool_handler); 3337 cv_pool_handler = get_cv ("Coro::pool_handler", GV_ADD); SvREADONLY_on (cv_pool_handler);
3327 cv_coro_state_new = get_cv ("Coro::State::new", 0); SvREADONLY_on (cv_coro_state_new); 3338 CvNODEBUG_on (get_cv ("Coro::_pool_handler", 0)); /* work around a debugger bug */
3328 3339
3329 coro_stash = gv_stashpv ("Coro", TRUE); 3340 coro_stash = gv_stashpv ("Coro", TRUE);
3330 3341
3331 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (CORO_PRIO_MAX)); 3342 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (CORO_PRIO_MAX));
3332 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (CORO_PRIO_HIGH)); 3343 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (CORO_PRIO_HIGH));
3333 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (CORO_PRIO_NORMAL)); 3344 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (CORO_PRIO_NORMAL));
3351 sv_setiv (sv, (IV)&coroapi); 3362 sv_setiv (sv, (IV)&coroapi);
3352 SvREADONLY_on (sv); 3363 SvREADONLY_on (sv);
3353 } 3364 }
3354} 3365}
3355 3366
3367SV *
3368async (...)
3369 PROTOTYPE: &@
3370 CODE:
3371 RETVAL = coro_new (aTHX_ coro_stash, &ST (0), items, 1);
3372 api_ready (aTHX_ RETVAL);
3373 OUTPUT:
3374 RETVAL
3375
3356void 3376void
3357terminate (...) 3377terminate (...)
3358 CODE: 3378 CODE:
3359 CORO_EXECUTE_SLF_XS (slf_init_terminate); 3379 CORO_EXECUTE_SLF_XS (slf_init_terminate);
3360 3380
3394_set_readyhook (SV *hook) 3414_set_readyhook (SV *hook)
3395 PROTOTYPE: $ 3415 PROTOTYPE: $
3396 CODE: 3416 CODE:
3397 SvREFCNT_dec (coro_readyhook); 3417 SvREFCNT_dec (coro_readyhook);
3398 SvGETMAGIC (hook); 3418 SvGETMAGIC (hook);
3419 if (SvOK (hook))
3420 {
3399 coro_readyhook = SvOK (hook) ? newSVsv (hook) : 0; 3421 coro_readyhook = newSVsv (hook);
3422 CORO_READYHOOK = invoke_sv_ready_hook_helper;
3423 }
3424 else
3425 {
3426 coro_readyhook = 0;
3427 CORO_READYHOOK = 0;
3428 }
3400 3429
3401int 3430int
3402prio (Coro::State coro, int newprio = 0) 3431prio (Coro::State coro, int newprio = 0)
3403 PROTOTYPE: $;$ 3432 PROTOTYPE: $;$
3404 ALIAS: 3433 ALIAS:
3468 for (i = 1; i < items; ++i) 3497 for (i = 1; i < items; ++i)
3469 av_push (av, SvREFCNT_inc_NN (ST (i))); 3498 av_push (av, SvREFCNT_inc_NN (ST (i)));
3470 3499
3471 if ((SV *)hv == &PL_sv_undef) 3500 if ((SV *)hv == &PL_sv_undef)
3472 { 3501 {
3473 PUSHMARK (SP); 3502 SV *sv = coro_new (aTHX_ coro_stash, (SV **)&cv_pool_handler, 1, 1);
3474 EXTEND (SP, 2);
3475 PUSHs (sv_Coro);
3476 PUSHs ((SV *)cv_pool_handler);
3477 PUTBACK;
3478 call_sv ((SV *)cv_coro_state_new, G_SCALAR);
3479 SPAGAIN;
3480
3481 hv = (HV *)SvREFCNT_inc_NN (SvRV (POPs)); 3503 hv = (HV *)SvREFCNT_inc_NN (SvRV (sv));
3504 SvREFCNT_dec (sv);
3482 } 3505 }
3483 3506
3484 { 3507 {
3485 struct coro *coro = SvSTATE_hv (hv); 3508 struct coro *coro = SvSTATE_hv (hv);
3486 3509

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines