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.370 by root, Thu Aug 20 21:38:51 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 */
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
1920{ 1915{
1921 int i; 1916 int i;
1922 HV *hv = (HV *)SvRV (coro_current); 1917 HV *hv = (HV *)SvRV (coro_current);
1923 AV *av = newAV (); 1918 AV *av = newAV ();
1924 1919
1920 /* items are actually not so common, so optimise for this case */
1921 if (items)
1922 {
1925 av_extend (av, items - 1); 1923 av_extend (av, items - 1);
1924
1926 for (i = 0; i < items; ++i) 1925 for (i = 0; i < items; ++i)
1927 av_push (av, SvREFCNT_inc_NN (arg [i])); 1926 av_push (av, SvREFCNT_inc_NN (arg [i]));
1927 }
1928 1928
1929 hv_store (hv, "_status", sizeof ("_status") - 1, newRV_noinc ((SV *)av), 0); 1929 hv_store (hv, "_status", sizeof ("_status") - 1, newRV_noinc ((SV *)av), 0);
1930 1930
1931 av_push (av_destroy, (SV *)newRV_inc ((SV *)hv)); /* RVinc for perl */ 1931 av_push (av_destroy, (SV *)newRV_inc ((SV *)hv)); /* RVinc for perl */
1932 api_ready (aTHX_ sv_manager); 1932 api_ready (aTHX_ sv_manager);
2914 2914
2915#if CORO_CLONE 2915#if CORO_CLONE
2916# include "clone.c" 2916# include "clone.c"
2917#endif 2917#endif
2918 2918
2919/*****************************************************************************/
2920
2921static SV *
2922coro_new (pTHX_ HV *stash, SV **argv, int argc, int is_coro)
2923{
2924 SV *coro_sv;
2925 struct coro *coro;
2926 MAGIC *mg;
2927 HV *hv;
2928 SV *cb;
2929 int i;
2930
2931 if (argc > 0)
2932 {
2933 cb = s_get_cv_croak (argv [0]);
2934
2935 if (!is_coro)
2936 {
2937 if (CvISXSUB (cb))
2938 croak ("Coro::State doesn't support XS functions as coroutine start, caught");
2939
2940 if (!CvROOT (cb))
2941 croak ("Coro::State doesn't support autoloaded or undefined functions as coroutine start, caught");
2942 }
2943 }
2944
2945 Newz (0, coro, 1, struct coro);
2946 coro->args = newAV ();
2947 coro->flags = CF_NEW;
2948
2949 if (coro_first) coro_first->prev = coro;
2950 coro->next = coro_first;
2951 coro_first = coro;
2952
2953 coro->hv = hv = newHV ();
2954 mg = sv_magicext ((SV *)hv, 0, CORO_MAGIC_type_state, &coro_state_vtbl, (char *)coro, 0);
2955 mg->mg_flags |= MGf_DUP;
2956 coro_sv = sv_bless (newRV_noinc ((SV *)hv), stash);
2957
2958 if (argc > 0)
2959 {
2960 av_extend (coro->args, argc + is_coro - 1);
2961
2962 if (is_coro)
2963 {
2964 av_push (coro->args, SvREFCNT_inc_NN ((SV *)cb));
2965 cb = (SV *)cv_coro_run;
2966 }
2967
2968 coro->startcv = (CV *)SvREFCNT_inc_NN ((SV *)cb);
2969
2970 for (i = 1; i < argc; i++)
2971 av_push (coro->args, newSVsv (argv [i]));
2972 }
2973
2974 return coro_sv;
2975}
2976
2919MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_ 2977MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_
2920 2978
2921PROTOTYPES: DISABLE 2979PROTOTYPES: DISABLE
2922 2980
2923BOOT: 2981BOOT:
2991 3049
2992 assert (("PRIO_NORMAL must be 0", !CORO_PRIO_NORMAL)); 3050 assert (("PRIO_NORMAL must be 0", !CORO_PRIO_NORMAL));
2993} 3051}
2994 3052
2995SV * 3053SV *
2996new (char *klass, ...) 3054new (SV *klass, ...)
2997 ALIAS: 3055 ALIAS:
2998 Coro::new = 1 3056 Coro::new = 1
2999 CODE: 3057 CODE:
3000{ 3058 RETVAL = coro_new (aTHX_ ix ? coro_stash : coro_state_stash, &ST (1), items - 1, ix);
3001 struct coro *coro; 3059 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 3060 RETVAL
3052 3061
3053void 3062void
3054transfer (...) 3063transfer (...)
3055 PROTOTYPE: $$ 3064 PROTOTYPE: $$
3322 sv_idle = coro_get_sv (aTHX_ "Coro::idle" , TRUE); 3331 sv_idle = coro_get_sv (aTHX_ "Coro::idle" , TRUE);
3323 3332
3324 sv_async_pool_idle = newSVpv ("[async pool idle]", 0); SvREADONLY_on (sv_async_pool_idle); 3333 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); 3334 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); 3335 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); 3336 CvNODEBUG_on (get_cv ("Coro::_pool_handler", 0)); /* work around a debugger bug */
3328 3337
3329 coro_stash = gv_stashpv ("Coro", TRUE); 3338 coro_stash = gv_stashpv ("Coro", TRUE);
3330 3339
3331 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (CORO_PRIO_MAX)); 3340 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (CORO_PRIO_MAX));
3332 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (CORO_PRIO_HIGH)); 3341 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (CORO_PRIO_HIGH));
3333 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (CORO_PRIO_NORMAL)); 3342 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (CORO_PRIO_NORMAL));
3351 sv_setiv (sv, (IV)&coroapi); 3360 sv_setiv (sv, (IV)&coroapi);
3352 SvREADONLY_on (sv); 3361 SvREADONLY_on (sv);
3353 } 3362 }
3354} 3363}
3355 3364
3365SV *
3366async (...)
3367 PROTOTYPE: &@
3368 CODE:
3369 RETVAL = coro_new (aTHX_ coro_stash, &ST (0), items, 1);
3370 api_ready (RETVAL);
3371 OUTPUT:
3372 RETVAL
3373
3356void 3374void
3357terminate (...) 3375terminate (...)
3358 CODE: 3376 CODE:
3359 CORO_EXECUTE_SLF_XS (slf_init_terminate); 3377 CORO_EXECUTE_SLF_XS (slf_init_terminate);
3360 3378
3394_set_readyhook (SV *hook) 3412_set_readyhook (SV *hook)
3395 PROTOTYPE: $ 3413 PROTOTYPE: $
3396 CODE: 3414 CODE:
3397 SvREFCNT_dec (coro_readyhook); 3415 SvREFCNT_dec (coro_readyhook);
3398 SvGETMAGIC (hook); 3416 SvGETMAGIC (hook);
3417 if (SvOK (hook))
3418 {
3399 coro_readyhook = SvOK (hook) ? newSVsv (hook) : 0; 3419 coro_readyhook = newSVsv (hook);
3420 CORO_READYHOOK = invoke_sv_ready_hook_helper;
3421 }
3422 else
3423 {
3424 coro_readyhook = 0;
3425 CORO_READYHOOK = 0;
3426 }
3400 3427
3401int 3428int
3402prio (Coro::State coro, int newprio = 0) 3429prio (Coro::State coro, int newprio = 0)
3403 PROTOTYPE: $;$ 3430 PROTOTYPE: $;$
3404 ALIAS: 3431 ALIAS:
3468 for (i = 1; i < items; ++i) 3495 for (i = 1; i < items; ++i)
3469 av_push (av, SvREFCNT_inc_NN (ST (i))); 3496 av_push (av, SvREFCNT_inc_NN (ST (i)));
3470 3497
3471 if ((SV *)hv == &PL_sv_undef) 3498 if ((SV *)hv == &PL_sv_undef)
3472 { 3499 {
3473 PUSHMARK (SP); 3500 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)); 3501 hv = (HV *)SvREFCNT_inc_NN (SvRV (sv));
3502 SvREFCNT_dec (sv);
3482 } 3503 }
3483 3504
3484 { 3505 {
3485 struct coro *coro = SvSTATE_hv (hv); 3506 struct coro *coro = SvSTATE_hv (hv);
3486 3507

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines