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.365 by root, Mon Jul 20 16:18:30 2009 UTC vs.
Revision 1.368 by root, Thu Aug 13 02:35:41 2009 UTC

1275 /* somebody or something will hit me for both perl_run and PL_restartop */ 1275 /* somebody or something will hit me for both perl_run and PL_restartop */
1276 PL_restartop = PL_op; 1276 PL_restartop = PL_op;
1277 perl_run (PL_curinterp); 1277 perl_run (PL_curinterp);
1278 /* 1278 /*
1279 * Unfortunately, there is no way to get at the return values of the 1279 * Unfortunately, there is no way to get at the return values of the
1280 * coro body here, as perl_run destroys these 1280 * coro body here, as perl_run destroys these. Likewise, we cannot catch
1281 * runtime errors here, as this is just a random interpreter, not a thread.
1281 */ 1282 */
1282 1283
1283 /* 1284 /*
1284 * If perl-run returns we assume exit() was being called or the coro 1285 * 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) 1286 * fell off the end, which seems to be the only valid (non-bug)
1915{ 1916{
1916 int i; 1917 int i;
1917 HV *hv = (HV *)SvRV (coro_current); 1918 HV *hv = (HV *)SvRV (coro_current);
1918 AV *av = newAV (); 1919 AV *av = newAV ();
1919 1920
1921 /* items are actually not so common, so optimise for this case */
1922 if (items)
1923 {
1920 av_extend (av, items - 1); 1924 av_extend (av, items - 1);
1925
1921 for (i = 0; i < items; ++i) 1926 for (i = 0; i < items; ++i)
1922 av_push (av, SvREFCNT_inc_NN (arg [i])); 1927 av_push (av, SvREFCNT_inc_NN (arg [i]));
1928 }
1923 1929
1924 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);
1925 1931
1926 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 */
1927 api_ready (aTHX_ sv_manager); 1933 api_ready (aTHX_ sv_manager);
2909 2915
2910#if CORO_CLONE 2916#if CORO_CLONE
2911# include "clone.c" 2917# include "clone.c"
2912#endif 2918#endif
2913 2919
2920/*****************************************************************************/
2921
2922static SV *
2923coro_new (HV *stash, SV **argv, int argc, int is_coro)
2924{
2925 SV *coro_sv;
2926 struct coro *coro;
2927 MAGIC *mg;
2928 HV *hv;
2929 SV *cb;
2930 int i;
2931
2932 if (argc > 0)
2933 {
2934 cb = s_get_cv_croak (argv [0]);
2935
2936 if (!is_coro)
2937 {
2938 if (CvISXSUB (cb))
2939 croak ("Coro::State doesn't support XS functions as coroutine start, caught");
2940
2941 if (!CvROOT (cb))
2942 croak ("Coro::State doesn't support autoloaded or undefined functions as coroutine start, caught");
2943 }
2944 }
2945
2946 Newz (0, coro, 1, struct coro);
2947 coro->args = newAV ();
2948 coro->flags = CF_NEW;
2949
2950 if (coro_first) coro_first->prev = coro;
2951 coro->next = coro_first;
2952 coro_first = coro;
2953
2954 coro->hv = hv = newHV ();
2955 mg = sv_magicext ((SV *)hv, 0, CORO_MAGIC_type_state, &coro_state_vtbl, (char *)coro, 0);
2956 mg->mg_flags |= MGf_DUP;
2957 coro_sv = sv_bless (newRV_noinc ((SV *)hv), stash);
2958
2959 if (argc > 0)
2960 {
2961 av_extend (coro->args, argc + is_coro - 1);
2962
2963 if (is_coro)
2964 {
2965 av_push (coro->args, SvREFCNT_inc_NN ((SV *)cb));
2966 cb = (SV *)cv_coro_run;
2967 }
2968
2969 coro->startcv = (CV *)SvREFCNT_inc_NN ((SV *)cb);
2970
2971 for (i = 1; i < argc; i++)
2972 av_push (coro->args, newSVsv (argv [i]));
2973 }
2974
2975 return coro_sv;
2976}
2977
2914MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_ 2978MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_
2915 2979
2916PROTOTYPES: DISABLE 2980PROTOTYPES: DISABLE
2917 2981
2918BOOT: 2982BOOT:
2986 3050
2987 assert (("PRIO_NORMAL must be 0", !CORO_PRIO_NORMAL)); 3051 assert (("PRIO_NORMAL must be 0", !CORO_PRIO_NORMAL));
2988} 3052}
2989 3053
2990SV * 3054SV *
2991new (char *klass, ...) 3055new (SV *klass, ...)
2992 ALIAS: 3056 ALIAS:
2993 Coro::new = 1 3057 Coro::new = 1
2994 CODE: 3058 CODE:
2995{ 3059 RETVAL = coro_new (ix ? coro_stash : coro_state_stash, &ST (1), items - 1, ix);
2996 struct coro *coro; 3060 OUTPUT:
2997 MAGIC *mg;
2998 HV *hv;
2999 SV *cb;
3000 int i;
3001
3002 if (items > 1)
3003 {
3004 cb = s_get_cv_croak (ST (1));
3005
3006 if (!ix)
3007 {
3008 if (CvISXSUB (cb))
3009 croak ("Coro::State doesn't support XS functions as coroutine start, caught");
3010
3011 if (!CvROOT (cb))
3012 croak ("Coro::State doesn't support autoloaded or undefined functions as coroutine start, caught");
3013 }
3014 }
3015
3016 Newz (0, coro, 1, struct coro);
3017 coro->args = newAV ();
3018 coro->flags = CF_NEW;
3019
3020 if (coro_first) coro_first->prev = coro;
3021 coro->next = coro_first;
3022 coro_first = coro;
3023
3024 coro->hv = hv = newHV ();
3025 mg = sv_magicext ((SV *)hv, 0, CORO_MAGIC_type_state, &coro_state_vtbl, (char *)coro, 0);
3026 mg->mg_flags |= MGf_DUP;
3027 RETVAL = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1));
3028
3029 if (items > 1)
3030 {
3031 av_extend (coro->args, items - 1 + ix - 1);
3032
3033 if (ix)
3034 {
3035 av_push (coro->args, SvREFCNT_inc_NN ((SV *)cb));
3036 cb = (SV *)cv_coro_run;
3037 }
3038
3039 coro->startcv = (CV *)SvREFCNT_inc_NN ((SV *)cb);
3040
3041 for (i = 2; i < items; i++)
3042 av_push (coro->args, newSVsv (ST (i)));
3043 }
3044}
3045 OUTPUT:
3046 RETVAL 3061 RETVAL
3047 3062
3048void 3063void
3049transfer (...) 3064transfer (...)
3050 PROTOTYPE: $$ 3065 PROTOTYPE: $$
3346 sv_setiv (sv, (IV)&coroapi); 3361 sv_setiv (sv, (IV)&coroapi);
3347 SvREADONLY_on (sv); 3362 SvREADONLY_on (sv);
3348 } 3363 }
3349} 3364}
3350 3365
3366SV *
3367async (...)
3368 PROTOTYPE: &@
3369 CODE:
3370 RETVAL = coro_new (coro_stash, &ST (0), items, 1);
3371 api_ready (RETVAL);
3372 OUTPUT:
3373 RETVAL
3374
3351void 3375void
3352terminate (...) 3376terminate (...)
3353 CODE: 3377 CODE:
3354 CORO_EXECUTE_SLF_XS (slf_init_terminate); 3378 CORO_EXECUTE_SLF_XS (slf_init_terminate);
3355 3379
3393 SvGETMAGIC (hook); 3417 SvGETMAGIC (hook);
3394 if (SvOK (hook)) 3418 if (SvOK (hook))
3395 { 3419 {
3396 coro_readyhook = newSVsv (hook); 3420 coro_readyhook = newSVsv (hook);
3397 CORO_READYHOOK = invoke_sv_ready_hook_helper; 3421 CORO_READYHOOK = invoke_sv_ready_hook_helper;
3398 CORO_READYHOOK ();
3399 } 3422 }
3400 else 3423 else
3401 { 3424 {
3402 coro_readyhook = 0; 3425 coro_readyhook = 0;
3403 CORO_READYHOOK = 0; 3426 CORO_READYHOOK = 0;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines