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.366 by root, Tue Jul 21 03:39:58 2009 UTC vs.
Revision 1.371 by root, Sat Aug 22 22:36: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)
1915{ 1915{
1916 int i; 1916 int i;
1917 HV *hv = (HV *)SvRV (coro_current); 1917 HV *hv = (HV *)SvRV (coro_current);
1918 AV *av = newAV (); 1918 AV *av = newAV ();
1919 1919
1920 /* items are actually not so common, so optimise for this case */
1921 if (items)
1922 {
1920 av_extend (av, items - 1); 1923 av_extend (av, items - 1);
1924
1921 for (i = 0; i < items; ++i) 1925 for (i = 0; i < items; ++i)
1922 av_push (av, SvREFCNT_inc_NN (arg [i])); 1926 av_push (av, SvREFCNT_inc_NN (arg [i]));
1927 }
1923 1928
1924 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);
1925 1930
1926 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 */
1927 api_ready (aTHX_ sv_manager); 1932 api_ready (aTHX_ sv_manager);
2909 2914
2910#if CORO_CLONE 2915#if CORO_CLONE
2911# include "clone.c" 2916# include "clone.c"
2912#endif 2917#endif
2913 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
2914MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_ 2977MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_
2915 2978
2916PROTOTYPES: DISABLE 2979PROTOTYPES: DISABLE
2917 2980
2918BOOT: 2981BOOT:
2986 3049
2987 assert (("PRIO_NORMAL must be 0", !CORO_PRIO_NORMAL)); 3050 assert (("PRIO_NORMAL must be 0", !CORO_PRIO_NORMAL));
2988} 3051}
2989 3052
2990SV * 3053SV *
2991new (char *klass, ...) 3054new (SV *klass, ...)
2992 ALIAS: 3055 ALIAS:
2993 Coro::new = 1 3056 Coro::new = 1
2994 CODE: 3057 CODE:
2995{ 3058 RETVAL = coro_new (aTHX_ ix ? coro_stash : coro_state_stash, &ST (1), items - 1, ix);
2996 struct coro *coro; 3059 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 3060 RETVAL
3047 3061
3048void 3062void
3049transfer (...) 3063transfer (...)
3050 PROTOTYPE: $$ 3064 PROTOTYPE: $$
3317 sv_idle = coro_get_sv (aTHX_ "Coro::idle" , TRUE); 3331 sv_idle = coro_get_sv (aTHX_ "Coro::idle" , TRUE);
3318 3332
3319 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);
3320 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro); 3334 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro);
3321 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);
3322 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 */
3323 3337
3324 coro_stash = gv_stashpv ("Coro", TRUE); 3338 coro_stash = gv_stashpv ("Coro", TRUE);
3325 3339
3326 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (CORO_PRIO_MAX)); 3340 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (CORO_PRIO_MAX));
3327 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (CORO_PRIO_HIGH)); 3341 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (CORO_PRIO_HIGH));
3328 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (CORO_PRIO_NORMAL)); 3342 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (CORO_PRIO_NORMAL));
3345 /*GCoroAPI = &coroapi;*/ 3359 /*GCoroAPI = &coroapi;*/
3346 sv_setiv (sv, (IV)&coroapi); 3360 sv_setiv (sv, (IV)&coroapi);
3347 SvREADONLY_on (sv); 3361 SvREADONLY_on (sv);
3348 } 3362 }
3349} 3363}
3364
3365SV *
3366async (...)
3367 PROTOTYPE: &@
3368 CODE:
3369 RETVAL = coro_new (aTHX_ coro_stash, &ST (0), items, 1);
3370 api_ready (aTHX_ RETVAL);
3371 OUTPUT:
3372 RETVAL
3350 3373
3351void 3374void
3352terminate (...) 3375terminate (...)
3353 CODE: 3376 CODE:
3354 CORO_EXECUTE_SLF_XS (slf_init_terminate); 3377 CORO_EXECUTE_SLF_XS (slf_init_terminate);
3472 for (i = 1; i < items; ++i) 3495 for (i = 1; i < items; ++i)
3473 av_push (av, SvREFCNT_inc_NN (ST (i))); 3496 av_push (av, SvREFCNT_inc_NN (ST (i)));
3474 3497
3475 if ((SV *)hv == &PL_sv_undef) 3498 if ((SV *)hv == &PL_sv_undef)
3476 { 3499 {
3477 PUSHMARK (SP); 3500 SV *sv = coro_new (aTHX_ coro_stash, (SV **)&cv_pool_handler, 1, 1);
3478 EXTEND (SP, 2);
3479 PUSHs (sv_Coro);
3480 PUSHs ((SV *)cv_pool_handler);
3481 PUTBACK;
3482 call_sv ((SV *)cv_coro_state_new, G_SCALAR);
3483 SPAGAIN;
3484
3485 hv = (HV *)SvREFCNT_inc_NN (SvRV (POPs)); 3501 hv = (HV *)SvREFCNT_inc_NN (SvRV (sv));
3502 SvREFCNT_dec (sv);
3486 } 3503 }
3487 3504
3488 { 3505 {
3489 struct coro *coro = SvSTATE_hv (hv); 3506 struct coro *coro = SvSTATE_hv (hv);
3490 3507

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines