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.347 by root, Wed Jun 10 00:00:02 2009 UTC vs.
Revision 1.356 by root, Sat Jun 27 14:06:59 2009 UTC

137 137
138#define IN_DESTRUCT PL_dirty 138#define IN_DESTRUCT PL_dirty
139 139
140#if __GNUC__ >= 3 140#if __GNUC__ >= 3
141# define attribute(x) __attribute__(x) 141# define attribute(x) __attribute__(x)
142# define expect(expr,value) __builtin_expect ((expr),(value)) 142# define expect(expr,value) __builtin_expect ((expr), (value))
143# define INLINE static inline 143# define INLINE static inline
144#else 144#else
145# define attribute(x) 145# define attribute(x)
146# define expect(expr,value) (expr) 146# define expect(expr,value) (expr)
147# define INLINE static 147# define INLINE static
615 { 615 {
616 while (expect_true (cxix >= 0)) 616 while (expect_true (cxix >= 0))
617 { 617 {
618 PERL_CONTEXT *cx = &ccstk[cxix--]; 618 PERL_CONTEXT *cx = &ccstk[cxix--];
619 619
620 if (expect_true (CxTYPE (cx) == CXt_SUB || CxTYPE (cx) == CXt_FORMAT)) 620 if (expect_true (CxTYPE (cx) == CXt_SUB) || expect_false (CxTYPE (cx) == CXt_FORMAT))
621 { 621 {
622 CV *cv = cx->blk_sub.cv; 622 CV *cv = cx->blk_sub.cv;
623 623
624 if (expect_true (CvDEPTH (cv))) 624 if (expect_true (CvDEPTH (cv)))
625 { 625 {
990} 990}
991 991
992static void 992static void
993coro_destruct_perl (pTHX_ struct coro *coro) 993coro_destruct_perl (pTHX_ struct coro *coro)
994{ 994{
995 SV *svf [9];
996
997 {
998 struct coro *current = SvSTATE_current;
999
1000 assert (("FATAL: tried to destroy currently running coroutine", coro->mainstack != PL_mainstack));
1001
1002 save_perl (aTHX_ current);
1003 load_perl (aTHX_ coro);
1004
995 coro_unwind_stacks (aTHX); 1005 coro_unwind_stacks (aTHX);
1006 coro_destruct_stacks (aTHX);
996 1007
997 SvREFCNT_dec (GvSV (PL_defgv)); 1008 // now save some sv's to be free'd later
998 SvREFCNT_dec (GvAV (PL_defgv)); 1009 svf [0] = GvSV (PL_defgv);
999 SvREFCNT_dec (GvSV (PL_errgv)); 1010 svf [1] = (SV *)GvAV (PL_defgv);
1000 SvREFCNT_dec (PL_defoutgv); 1011 svf [2] = GvSV (PL_errgv);
1001 SvREFCNT_dec (PL_rs); 1012 svf [3] = (SV *)PL_defoutgv;
1002 SvREFCNT_dec (GvSV (irsgv)); 1013 svf [4] = PL_rs;
1003 SvREFCNT_dec (GvHV (PL_hintgv)); 1014 svf [5] = GvSV (irsgv);
1015 svf [6] = (SV *)GvHV (PL_hintgv);
1016 svf [7] = PL_diehook;
1017 svf [8] = PL_warnhook;
1018 assert (9 == sizeof (svf) / sizeof (*svf));
1004 1019
1005 SvREFCNT_dec (PL_diehook); 1020 load_perl (aTHX_ current);
1006 SvREFCNT_dec (PL_warnhook);
1007 1021 }
1022
1023 {
1024 int i;
1025
1026 for (i = 0; i < sizeof (svf) / sizeof (*svf); ++i)
1027 SvREFCNT_dec (svf [i]);
1028
1008 SvREFCNT_dec (coro->saved_deffh); 1029 SvREFCNT_dec (coro->saved_deffh);
1009 SvREFCNT_dec (coro->rouse_cb); 1030 SvREFCNT_dec (coro->rouse_cb);
1010 SvREFCNT_dec (coro->invoke_cb); 1031 SvREFCNT_dec (coro->invoke_cb);
1011 SvREFCNT_dec (coro->invoke_av); 1032 SvREFCNT_dec (coro->invoke_av);
1012 1033 }
1013 coro_destruct_stacks (aTHX);
1014} 1034}
1015 1035
1016INLINE void 1036INLINE void
1017free_coro_mortal (pTHX) 1037free_coro_mortal (pTHX)
1018{ 1038{
1505 1525
1506 if (coro->mainstack 1526 if (coro->mainstack
1507 && coro->mainstack != main_mainstack 1527 && coro->mainstack != main_mainstack
1508 && coro->slot 1528 && coro->slot
1509 && !PL_dirty) 1529 && !PL_dirty)
1510 {
1511 struct coro *current = SvSTATE_current;
1512
1513 assert (("FATAL: tried to destroy currently running coroutine", coro->mainstack != PL_mainstack));
1514
1515 save_perl (aTHX_ current);
1516 load_perl (aTHX_ coro);
1517
1518 coro_destruct_perl (aTHX_ coro); 1530 coro_destruct_perl (aTHX_ coro);
1519
1520 load_perl (aTHX_ current);
1521
1522 coro->slot = 0;
1523 }
1524 1531
1525 cctx_destroy (coro->cctx); 1532 cctx_destroy (coro->cctx);
1526 SvREFCNT_dec (coro->startcv); 1533 SvREFCNT_dec (coro->startcv);
1527 SvREFCNT_dec (coro->args); 1534 SvREFCNT_dec (coro->args);
1528 SvREFCNT_dec (CORO_THROW); 1535 SvREFCNT_dec (CORO_THROW);
1640 struct coro *coro = ready [0]; 1647 struct coro *coro = ready [0];
1641 ready [0] = coro->next_ready; 1648 ready [0] = coro->next_ready;
1642 return coro; 1649 return coro;
1643 } 1650 }
1644 } 1651 }
1652
1653 return 0;
1645} 1654}
1646 1655
1647static int 1656static int
1648api_ready (pTHX_ SV *coro_sv) 1657api_ready (pTHX_ SV *coro_sv)
1649{ 1658{
2468/* Coro::Semaphore & Coro::Signal */ 2477/* Coro::Semaphore & Coro::Signal */
2469 2478
2470static SV * 2479static SV *
2471coro_waitarray_new (pTHX_ int count) 2480coro_waitarray_new (pTHX_ int count)
2472{ 2481{
2473 /* a semaphore contains a counter IV in $sem->[0] and any waiters after that */ 2482 /* a waitarray=semaphore contains a counter IV in $sem->[0] and any waiters after that */
2474 AV *av = newAV (); 2483 AV *av = newAV ();
2475 SV **ary; 2484 SV **ary;
2476 2485
2477 /* unfortunately, building manually saves memory */ 2486 /* unfortunately, building manually saves memory */
2478 Newx (ary, 2, SV *); 2487 Newx (ary, 2, SV *);
2622 { 2631 {
2623 /* callback form */ 2632 /* callback form */
2624 AV *av = (AV *)SvRV (arg [0]); 2633 AV *av = (AV *)SvRV (arg [0]);
2625 CV *cb_cv = coro_sv_2cv (aTHX_ arg [1]); 2634 CV *cb_cv = coro_sv_2cv (aTHX_ arg [1]);
2626 2635
2627 av_push (av, (SV *)SvREFCNT_inc_NN (cb_cv)); 2636 av_push (av, SvREFCNT_inc_NN (cb_cv));
2628 2637
2629 if (SvIVX (AvARRAY (av)[0]) > 0) 2638 if (SvIVX (AvARRAY (av)[0]) > 0)
2630 coro_semaphore_adjust (aTHX_ av, 0); 2639 coro_semaphore_adjust (aTHX_ av, 0);
2631 2640
2632 frame->prepare = prepare_nop; 2641 frame->prepare = prepare_nop;
2656 AvARRAY (av)[0] = AvARRAY (av)[1]; 2665 AvARRAY (av)[0] = AvARRAY (av)[1];
2657 AvARRAY (av)[1] = cb; 2666 AvARRAY (av)[1] = cb;
2658 2667
2659 cb = av_shift (av); 2668 cb = av_shift (av);
2660 2669
2670 if (SvTYPE (cb) == SVt_PVCV)
2671 {
2672 dSP;
2673 PUSHMARK (SP);
2674 XPUSHs (sv_2mortal (newRV_inc ((SV *)av)));
2675 PUTBACK;
2676 call_sv (cb, G_VOID | G_DISCARD | G_EVAL | G_KEEPERR);
2677 }
2678 else
2679 {
2661 api_ready (aTHX_ cb); 2680 api_ready (aTHX_ cb);
2662 sv_setiv (cb, 0); /* signal waiter */ 2681 sv_setiv (cb, 0); /* signal waiter */
2682 }
2683
2663 SvREFCNT_dec (cb); 2684 SvREFCNT_dec (cb);
2664 2685
2665 --count; 2686 --count;
2666 } 2687 }
2667} 2688}
2676static void 2697static void
2677slf_init_signal_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items) 2698slf_init_signal_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2678{ 2699{
2679 AV *av = (AV *)SvRV (arg [0]); 2700 AV *av = (AV *)SvRV (arg [0]);
2680 2701
2702 if (items >= 2)
2703 {
2704 CV *cb_cv = coro_sv_2cv (aTHX_ arg [1]);
2705 av_push (av, SvREFCNT_inc_NN (cb_cv));
2706
2681 if (SvIVX (AvARRAY (av)[0])) 2707 if (SvIVX (AvARRAY (av)[0]))
2708 coro_signal_wake (aTHX_ av, 1); /* ust be the only waiter */
2709
2710 frame->prepare = prepare_nop;
2711 frame->check = slf_check_nop;
2712 }
2713 else if (SvIVX (AvARRAY (av)[0]))
2682 { 2714 {
2683 SvIVX (AvARRAY (av)[0]) = 0; 2715 SvIVX (AvARRAY (av)[0]) = 0;
2684 frame->prepare = prepare_nop; 2716 frame->prepare = prepare_nop;
2685 frame->check = slf_check_nop; 2717 frame->check = slf_check_nop;
2686 } 2718 }
2687 else 2719 else
2688 { 2720 {
2689 SV *waiter = newRV_inc (SvRV (coro_current)); /* owned by signal av */ 2721 SV *waiter = newSVsv (coro_current); /* owned by signal av */
2690 2722
2691 av_push (av, waiter); 2723 av_push (av, waiter);
2692 2724
2693 frame->data = (void *)sv_2mortal (SvREFCNT_inc_NN (waiter)); /* owned by process */ 2725 frame->data = (void *)sv_2mortal (SvREFCNT_inc_NN (waiter)); /* owned by process */
2694 frame->prepare = prepare_schedule; 2726 frame->prepare = prepare_schedule;
3219 3251
3220MODULE = Coro::State PACKAGE = Coro 3252MODULE = Coro::State PACKAGE = Coro
3221 3253
3222BOOT: 3254BOOT:
3223{ 3255{
3224 int i;
3225
3226 sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE); 3256 sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE);
3227 sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE); 3257 sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE);
3228 cv_coro_run = get_cv ( "Coro::_coro_run" , GV_ADD); 3258 cv_coro_run = get_cv ( "Coro::_coro_run" , GV_ADD);
3229 cv_coro_terminate = get_cv ( "Coro::terminate" , GV_ADD); 3259 cv_coro_terminate = get_cv ( "Coro::terminate" , GV_ADD);
3230 coro_current = coro_get_sv (aTHX_ "Coro::current" , FALSE); SvREADONLY_on (coro_current); 3260 coro_current = coro_get_sv (aTHX_ "Coro::current" , FALSE); SvREADONLY_on (coro_current);
3458MODULE = Coro::State PACKAGE = Coro::Semaphore 3488MODULE = Coro::State PACKAGE = Coro::Semaphore
3459 3489
3460SV * 3490SV *
3461new (SV *klass, SV *count = 0) 3491new (SV *klass, SV *count = 0)
3462 CODE: 3492 CODE:
3493{
3494 int semcnt = 1;
3495
3496 if (count)
3497 {
3498 SvGETMAGIC (count);
3499
3500 if (SvOK (count))
3501 semcnt = SvIV (count);
3502 }
3503
3463 RETVAL = sv_bless ( 3504 RETVAL = sv_bless (
3464 coro_waitarray_new (aTHX_ count && SvOK (count) ? SvIV (count) : 1), 3505 coro_waitarray_new (aTHX_ semcnt),
3465 GvSTASH (CvGV (cv)) 3506 GvSTASH (CvGV (cv))
3466 ); 3507 );
3508}
3467 OUTPUT: 3509 OUTPUT:
3468 RETVAL 3510 RETVAL
3469 3511
3470# helper for Coro::Channel and others 3512# helper for Coro::Channel and others
3471SV * 3513SV *

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines