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.339 by root, Mon Dec 15 00:28:30 2008 UTC vs.
Revision 1.343 by root, Mon Dec 15 16:41:43 2008 UTC

238enum { 238enum {
239 CF_RUNNING = 0x0001, /* coroutine is running */ 239 CF_RUNNING = 0x0001, /* coroutine is running */
240 CF_READY = 0x0002, /* coroutine is ready */ 240 CF_READY = 0x0002, /* coroutine is ready */
241 CF_NEW = 0x0004, /* has never been switched to */ 241 CF_NEW = 0x0004, /* has never been switched to */
242 CF_DESTROYED = 0x0008, /* coroutine data has been freed */ 242 CF_DESTROYED = 0x0008, /* coroutine data has been freed */
243 CF_SUSPENDED = 0x0010, /* coroutine can't be scheduled */
243}; 244};
244 245
245/* the structure where most of the perl state is stored, overlaid on the cxstack */ 246/* the structure where most of the perl state is stored, overlaid on the cxstack */
246typedef struct 247typedef struct
247{ 248{
574 if (expect_false (c->on_enter)) 575 if (expect_false (c->on_enter))
575 { 576 {
576 int i; 577 int i;
577 578
578 for (i = 0; i <= AvFILLp (c->on_enter); ++i) 579 for (i = 0; i <= AvFILLp (c->on_enter); ++i)
579 on_enterleave_call (AvARRAY (c->on_enter)[i]); 580 on_enterleave_call (aTHX_ AvARRAY (c->on_enter)[i]);
580 } 581 }
581} 582}
582 583
583static void 584static void
584save_perl (pTHX_ Coro__State c) 585save_perl (pTHX_ Coro__State c)
586 if (expect_false (c->on_leave)) 587 if (expect_false (c->on_leave))
587 { 588 {
588 int i; 589 int i;
589 590
590 for (i = AvFILLp (c->on_leave); i >= 0; --i) 591 for (i = AvFILLp (c->on_leave); i >= 0; --i)
591 on_enterleave_call (AvARRAY (c->on_leave)[i]); 592 on_enterleave_call (aTHX_ AvARRAY (c->on_leave)[i]);
592 } 593 }
593 594
594 c->except = CORO_THROW; 595 c->except = CORO_THROW;
595 c->slf_frame = slf_frame; 596 c->slf_frame = slf_frame;
596 597
1382 /* TODO: throwing up here is considered harmful */ 1383 /* TODO: throwing up here is considered harmful */
1383 1384
1384 if (expect_true (prev != next)) 1385 if (expect_true (prev != next))
1385 { 1386 {
1386 if (expect_false (!(prev->flags & (CF_RUNNING | CF_NEW)))) 1387 if (expect_false (!(prev->flags & (CF_RUNNING | CF_NEW))))
1387 croak ("Coro::State::transfer called with a suspended prev Coro::State, but can only transfer from running or new states,"); 1388 croak ("Coro::State::transfer called with a blocked prev Coro::State, but can only transfer from running or new states,");
1388 1389
1389 if (expect_false (next->flags & CF_RUNNING))
1390 croak ("Coro::State::transfer called with running next Coro::State, but can only transfer to inactive states,");
1391
1392 if (expect_false (next->flags & CF_DESTROYED)) 1390 if (expect_false (next->flags & (CF_RUNNING | CF_DESTROYED | CF_SUSPENDED)))
1393 croak ("Coro::State::transfer called with destroyed next Coro::State, but can only transfer to inactive states,"); 1391 croak ("Coro::State::transfer called with running, destroyed or suspended next Coro::State, but can only transfer to inactive states,");
1394 1392
1395#if !PERL_VERSION_ATLEAST (5,10,0) 1393#if !PERL_VERSION_ATLEAST (5,10,0)
1396 if (expect_false (PL_lex_state != LEX_NOTPARSING)) 1394 if (expect_false (PL_lex_state != LEX_NOTPARSING))
1397 croak ("Coro::State::transfer called while parsing, but this is not supported in your perl version,"); 1395 croak ("Coro::State::transfer called while parsing, but this is not supported in your perl version,");
1398#endif 1396#endif
1705 if (expect_true (next_sv)) 1703 if (expect_true (next_sv))
1706 { 1704 {
1707 struct coro *next = SvSTATE_hv (next_sv); 1705 struct coro *next = SvSTATE_hv (next_sv);
1708 1706
1709 /* cannot transfer to destroyed coros, skip and look for next */ 1707 /* cannot transfer to destroyed coros, skip and look for next */
1710 if (expect_false (next->flags & CF_DESTROYED)) 1708 if (expect_false (next->flags & (CF_DESTROYED | CF_SUSPENDED)))
1711 SvREFCNT_dec (next_sv); /* coro_nready has already been taken care of by destroy */ 1709 SvREFCNT_dec (next_sv); /* coro_nready has already been taken care of by destroy */
1712 else 1710 else
1713 { 1711 {
1714 next->flags &= ~CF_READY; 1712 next->flags &= ~CF_READY;
1715 --coro_nready; 1713 --coro_nready;
2347 2345
2348 POPSTACK; 2346 POPSTACK;
2349} 2347}
2350 2348
2351static SV * 2349static SV *
2352coro_avp_pop_and_free (AV **avp) 2350coro_avp_pop_and_free (pTHX_ AV **avp)
2353{ 2351{
2354 AV *av = *avp; 2352 AV *av = *avp;
2355 SV *res = av_pop (av); 2353 SV *res = av_pop (av);
2356 2354
2357 if (AvFILLp (av) < 0) 2355 if (AvFILLp (av) < 0)
2364} 2362}
2365 2363
2366static void 2364static void
2367coro_pop_on_enter (pTHX_ void *coro) 2365coro_pop_on_enter (pTHX_ void *coro)
2368{ 2366{
2369 SV *cb = coro_avp_pop_and_free (&((struct coro *)coro)->on_enter); 2367 SV *cb = coro_avp_pop_and_free (aTHX_ &((struct coro *)coro)->on_enter);
2370 SvREFCNT_dec (cb); 2368 SvREFCNT_dec (cb);
2371} 2369}
2372 2370
2373static void 2371static void
2374coro_pop_on_leave (pTHX_ void *coro) 2372coro_pop_on_leave (pTHX_ void *coro)
2375{ 2373{
2376 SV *cb = coro_avp_pop_and_free (&((struct coro *)coro)->on_leave); 2374 SV *cb = coro_avp_pop_and_free (aTHX_ &((struct coro *)coro)->on_leave);
2377 on_enterleave_call (sv_2mortal (cb)); 2375 on_enterleave_call (aTHX_ sv_2mortal (cb));
2378} 2376}
2379 2377
2380/*****************************************************************************/ 2378/*****************************************************************************/
2381/* PerlIO::cede */ 2379/* PerlIO::cede */
2382 2380
3100 if (ix) 3098 if (ix)
3101 eval_sv (coderef, 0); 3099 eval_sv (coderef, 0);
3102 else 3100 else
3103 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 3101 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
3104 3102
3103 POPSTACK;
3105 SPAGAIN; 3104 SPAGAIN;
3106 POPSTACK;
3107 3105
3108 if (current != coro) 3106 if (current != coro)
3109 { 3107 {
3110 PUTBACK; 3108 PUTBACK;
3111 save_perl (aTHX_ coro); 3109 save_perl (aTHX_ coro);
3121 ALIAS: 3119 ALIAS:
3122 is_ready = CF_READY 3120 is_ready = CF_READY
3123 is_running = CF_RUNNING 3121 is_running = CF_RUNNING
3124 is_new = CF_NEW 3122 is_new = CF_NEW
3125 is_destroyed = CF_DESTROYED 3123 is_destroyed = CF_DESTROYED
3124 is_suspended = CF_SUSPENDED
3126 CODE: 3125 CODE:
3127 RETVAL = boolSV (coro->flags & ix); 3126 RETVAL = boolSV (coro->flags & ix);
3128 OUTPUT: 3127 OUTPUT:
3129 RETVAL 3128 RETVAL
3130 3129
3195 SV **dst = ix ? (SV **)&self->slot->defav : (SV **)&self->slot->defsv; 3194 SV **dst = ix ? (SV **)&self->slot->defav : (SV **)&self->slot->defsv;
3196 3195
3197 SV *tmp = *src; *src = *dst; *dst = tmp; 3196 SV *tmp = *src; *src = *dst; *dst = tmp;
3198 } 3197 }
3199 3198
3199void
3200cancel (Coro::State self)
3201 CODE:
3202 coro_state_destroy (aTHX_ self);
3203 coro_call_on_destroy (aTHX_ self); /* actually only for Coro objects */
3204
3200 3205
3201MODULE = Coro::State PACKAGE = Coro 3206MODULE = Coro::State PACKAGE = Coro
3202 3207
3203BOOT: 3208BOOT:
3204{ 3209{
3278cede_notself (...) 3283cede_notself (...)
3279 CODE: 3284 CODE:
3280 CORO_EXECUTE_SLF_XS (slf_init_cede_notself); 3285 CORO_EXECUTE_SLF_XS (slf_init_cede_notself);
3281 3286
3282void 3287void
3283_cancel (Coro::State self)
3284 CODE:
3285 coro_state_destroy (aTHX_ self);
3286 coro_call_on_destroy (aTHX_ self);
3287
3288void
3289_set_current (SV *current) 3288_set_current (SV *current)
3290 PROTOTYPE: $ 3289 PROTOTYPE: $
3291 CODE: 3290 CODE:
3292 SvREFCNT_dec (SvRV (coro_current)); 3291 SvREFCNT_dec (SvRV (coro_current));
3293 SvRV_set (coro_current, SvREFCNT_inc_NN (SvRV (current))); 3292 SvRV_set (coro_current, SvREFCNT_inc_NN (SvRV (current)));
3409 CODE: 3408 CODE:
3410{ 3409{
3411 struct coro *coro = SvSTATE_current; 3410 struct coro *coro = SvSTATE_current;
3412 AV **avp = ix ? &coro->on_leave : &coro->on_enter; 3411 AV **avp = ix ? &coro->on_leave : &coro->on_enter;
3413 3412
3414 block = (SV *)coro_sv_2cv (block); 3413 block = (SV *)coro_sv_2cv (aTHX_ block);
3415 3414
3416 if (!*avp) 3415 if (!*avp)
3417 *avp = newAV (); 3416 *avp = newAV ();
3418 3417
3419 av_push (*avp, SvREFCNT_inc (block)); 3418 av_push (*avp, SvREFCNT_inc (block));
3443 GvSTASH (CvGV (cv)) 3442 GvSTASH (CvGV (cv))
3444 ); 3443 );
3445 OUTPUT: 3444 OUTPUT:
3446 RETVAL 3445 RETVAL
3447 3446
3448# helper for Coro::Channel 3447# helper for Coro::Channel and others
3449SV * 3448SV *
3450_alloc (int count) 3449_alloc (int count)
3451 CODE: 3450 CODE:
3452 RETVAL = coro_waitarray_new (aTHX_ count); 3451 RETVAL = coro_waitarray_new (aTHX_ count);
3453 OUTPUT: 3452 OUTPUT:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines