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.340 by root, Mon Dec 15 00:30:40 2008 UTC vs.
Revision 1.346 by root, Tue Jun 9 18:56:45 2009 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{
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
1486coro_state_destroy (pTHX_ struct coro *coro) 1484coro_state_destroy (pTHX_ struct coro *coro)
1487{ 1485{
1488 if (coro->flags & CF_DESTROYED) 1486 if (coro->flags & CF_DESTROYED)
1489 return 0; 1487 return 0;
1490 1488
1491 if (coro->on_destroy) 1489 if (coro->on_destroy && !PL_dirty)
1492 coro->on_destroy (aTHX_ coro); 1490 coro->on_destroy (aTHX_ coro);
1493 1491
1494 coro->flags |= CF_DESTROYED; 1492 coro->flags |= CF_DESTROYED;
1495 1493
1496 if (coro->flags & CF_READY) 1494 if (coro->flags & CF_READY)
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;
1990 SV *data = (SV *)GENSUB_ARG; 1988 SV *data = (SV *)GENSUB_ARG;
1991 1989
1992 if (SvTYPE (SvRV (data)) != SVt_PVAV) 1990 if (SvTYPE (SvRV (data)) != SVt_PVAV)
1993 { 1991 {
1994 /* first call, set args */ 1992 /* first call, set args */
1993 SV *coro = SvRV (data);
1995 AV *av = newAV (); 1994 AV *av = newAV ();
1996 SV *coro = SvRV (data);
1997 1995
1998 SvRV_set (data, (SV *)av); 1996 SvRV_set (data, (SV *)av);
1999 api_ready (aTHX_ coro);
2000 SvREFCNT_dec (coro);
2001 1997
2002 /* better take a full copy of the arguments */ 1998 /* better take a full copy of the arguments */
2003 while (items--) 1999 while (items--)
2004 av_store (av, items, newSVsv (ST (items))); 2000 av_store (av, items, newSVsv (ST (items)));
2001
2002 api_ready (aTHX_ coro);
2003 SvREFCNT_dec (coro);
2005 } 2004 }
2006 2005
2007 XSRETURN_EMPTY; 2006 XSRETURN_EMPTY;
2008} 2007}
2009 2008
2026 2025
2027 EXTEND (SP, AvFILLp (av) + 1); 2026 EXTEND (SP, AvFILLp (av) + 1);
2028 for (i = 0; i <= AvFILLp (av); ++i) 2027 for (i = 0; i <= AvFILLp (av); ++i)
2029 PUSHs (sv_2mortal (AvARRAY (av)[i])); 2028 PUSHs (sv_2mortal (AvARRAY (av)[i]));
2030 2029
2031 /* we have stolen the elements, so ste length to zero and free */ 2030 /* we have stolen the elements, so set length to zero and free */
2032 AvFILLp (av) = -1; 2031 AvFILLp (av) = -1;
2033 av_undef (av); 2032 av_undef (av);
2034 2033
2035 PUTBACK; 2034 PUTBACK;
2036 } 2035 }
3100 if (ix) 3099 if (ix)
3101 eval_sv (coderef, 0); 3100 eval_sv (coderef, 0);
3102 else 3101 else
3103 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 3102 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
3104 3103
3104 POPSTACK;
3105 SPAGAIN; 3105 SPAGAIN;
3106 POPSTACK;
3107 3106
3108 if (current != coro) 3107 if (current != coro)
3109 { 3108 {
3110 PUTBACK; 3109 PUTBACK;
3111 save_perl (aTHX_ coro); 3110 save_perl (aTHX_ coro);
3121 ALIAS: 3120 ALIAS:
3122 is_ready = CF_READY 3121 is_ready = CF_READY
3123 is_running = CF_RUNNING 3122 is_running = CF_RUNNING
3124 is_new = CF_NEW 3123 is_new = CF_NEW
3125 is_destroyed = CF_DESTROYED 3124 is_destroyed = CF_DESTROYED
3125 is_suspended = CF_SUSPENDED
3126 CODE: 3126 CODE:
3127 RETVAL = boolSV (coro->flags & ix); 3127 RETVAL = boolSV (coro->flags & ix);
3128 OUTPUT: 3128 OUTPUT:
3129 RETVAL 3129 RETVAL
3130 3130
3195 SV **dst = ix ? (SV **)&self->slot->defav : (SV **)&self->slot->defsv; 3195 SV **dst = ix ? (SV **)&self->slot->defav : (SV **)&self->slot->defsv;
3196 3196
3197 SV *tmp = *src; *src = *dst; *dst = tmp; 3197 SV *tmp = *src; *src = *dst; *dst = tmp;
3198 } 3198 }
3199 3199
3200void
3201cancel (Coro::State self)
3202 CODE:
3203 coro_state_destroy (aTHX_ self);
3204 coro_call_on_destroy (aTHX_ self); /* actually only for Coro objects */
3205
3200 3206
3201MODULE = Coro::State PACKAGE = Coro 3207MODULE = Coro::State PACKAGE = Coro
3202 3208
3203BOOT: 3209BOOT:
3204{ 3210{
3278cede_notself (...) 3284cede_notself (...)
3279 CODE: 3285 CODE:
3280 CORO_EXECUTE_SLF_XS (slf_init_cede_notself); 3286 CORO_EXECUTE_SLF_XS (slf_init_cede_notself);
3281 3287
3282void 3288void
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) 3289_set_current (SV *current)
3290 PROTOTYPE: $ 3290 PROTOTYPE: $
3291 CODE: 3291 CODE:
3292 SvREFCNT_dec (SvRV (coro_current)); 3292 SvREFCNT_dec (SvRV (coro_current));
3293 SvRV_set (coro_current, SvREFCNT_inc_NN (SvRV (current))); 3293 SvRV_set (coro_current, SvREFCNT_inc_NN (SvRV (current)));
3335 PROTOTYPE: 3335 PROTOTYPE:
3336 CODE: 3336 CODE:
3337 RETVAL = coro_nready; 3337 RETVAL = coro_nready;
3338 OUTPUT: 3338 OUTPUT:
3339 RETVAL 3339 RETVAL
3340
3341void
3342suspend (Coro::State self)
3343 PROTOTYPE: $
3344 CODE:
3345 self->flags |= CF_SUSPENDED;
3346
3347void
3348resume (Coro::State self)
3349 PROTOTYPE: $
3350 CODE:
3351 self->flags &= ~CF_SUSPENDED;
3340 3352
3341void 3353void
3342_pool_handler (...) 3354_pool_handler (...)
3343 CODE: 3355 CODE:
3344 CORO_EXECUTE_SLF_XS (slf_init_pool_handler); 3356 CORO_EXECUTE_SLF_XS (slf_init_pool_handler);
3419 av_push (*avp, SvREFCNT_inc (block)); 3431 av_push (*avp, SvREFCNT_inc (block));
3420 3432
3421 if (!ix) 3433 if (!ix)
3422 on_enterleave_call (aTHX_ block); 3434 on_enterleave_call (aTHX_ block);
3423 3435
3424 LEAVE; /* pp_entersub unfortunately forces an ENTER/LEAVE around xs calls */ 3436 LEAVE; /* pp_entersub unfortunately forces an ENTER/LEAVE around XS calls */
3425 SAVEDESTRUCTOR_X (ix ? coro_pop_on_leave : coro_pop_on_enter, (void *)coro); 3437 SAVEDESTRUCTOR_X (ix ? coro_pop_on_leave : coro_pop_on_enter, (void *)coro);
3426 ENTER; /* pp_entersub unfortunately forces an ENTER/LEAVE around xs calls */ 3438 ENTER; /* pp_entersub unfortunately forces an ENTER/LEAVE around XS calls */
3427} 3439}
3428 3440
3429 3441
3430MODULE = Coro::State PACKAGE = PerlIO::cede 3442MODULE = Coro::State PACKAGE = PerlIO::cede
3431 3443
3443 GvSTASH (CvGV (cv)) 3455 GvSTASH (CvGV (cv))
3444 ); 3456 );
3445 OUTPUT: 3457 OUTPUT:
3446 RETVAL 3458 RETVAL
3447 3459
3448# helper for Coro::Channel 3460# helper for Coro::Channel and others
3449SV * 3461SV *
3450_alloc (int count) 3462_alloc (int count)
3451 CODE: 3463 CODE:
3452 RETVAL = coro_waitarray_new (aTHX_ count); 3464 RETVAL = coro_waitarray_new (aTHX_ count);
3453 OUTPUT: 3465 OUTPUT:
3511 for (i = 1; i <= wcount; ++i) 3523 for (i = 1; i <= wcount; ++i)
3512 PUSHs (sv_2mortal (newRV_inc (AvARRAY (av)[i]))); 3524 PUSHs (sv_2mortal (newRV_inc (AvARRAY (av)[i])));
3513 } 3525 }
3514} 3526}
3515 3527
3528MODULE = Coro::State PACKAGE = Coro::SemaphoreSet
3529
3530void
3531_may_delete (SV *sem, int count, int extra_refs)
3532 PPCODE:
3533{
3534 AV *av = (AV *)SvRV (sem);
3535
3536 if (SvREFCNT ((SV *)av) == 1 + extra_refs
3537 && AvFILLp (av) == 0 /* no waiters, just count */
3538 && SvIV (AvARRAY (av)[0]) == count)
3539 XSRETURN_YES;
3540
3541 XSRETURN_NO;
3542}
3543
3516MODULE = Coro::State PACKAGE = Coro::Signal 3544MODULE = Coro::State PACKAGE = Coro::Signal
3517 3545
3518SV * 3546SV *
3519new (SV *klass) 3547new (SV *klass)
3520 CODE: 3548 CODE:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines