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.207 by root, Tue Oct 9 22:29:27 2007 UTC vs.
Revision 1.212 by root, Wed Oct 10 04:21:33 2007 UTC

10#include "patchlevel.h" 10#include "patchlevel.h"
11 11
12#include <stdio.h> 12#include <stdio.h>
13#include <errno.h> 13#include <errno.h>
14#include <assert.h> 14#include <assert.h>
15#include <inttypes.h> /* portable stdint.h */
15 16
16#ifdef HAVE_MMAP 17#ifdef HAVE_MMAP
17# include <unistd.h> 18# include <unistd.h>
18# include <sys/mman.h> 19# include <sys/mman.h>
19# ifndef MAP_ANONYMOUS 20# ifndef MAP_ANONYMOUS
130#else 131#else
131# define LOCK (void)0 132# define LOCK (void)0
132# define UNLOCK (void)0 133# define UNLOCK (void)0
133#endif 134#endif
134 135
135#define strpair(const) const, sizeof (const) - 1
136
137/* helper storage struct for Coro::AIO */ 136/* helper storage struct for Coro::AIO */
138struct io_state 137struct io_state
139{ 138{
140 int errorno; 139 int errorno;
141 I32 laststype; 140 I32 laststype;
452 451
453 #define VAR(name,type) PL_ ## name = slot->name; 452 #define VAR(name,type) PL_ ## name = slot->name;
454 # include "state.h" 453 # include "state.h"
455 #undef VAR 454 #undef VAR
456 455
457 /*hv_store (hv_sig, strpair ("__DIE__" ), SvREFCNT_inc (sv_diehook ), 0);*/ 456 /*hv_store (hv_sig, "__DIE__" , sizeof ("__DIE__" ) - 1, SvREFCNT_inc (sv_diehook ), 0);*/
458 /*hv_store (hv_sig, strpair ("__WARN__"), SvREFCNT_inc (sv_warnhook), 0);*/ 457 /*hv_store (hv_sig, "__WARN__", sizeof ("__WARN__") - 1, SvREFCNT_inc (sv_warnhook), 0);*/
459 458
460 { 459 {
461 dSP; 460 dSP;
462 461
463 CV *cv; 462 CV *cv;
686 PL_curpm = 0; 685 PL_curpm = 0;
687 PL_curpad = 0; 686 PL_curpad = 0;
688 PL_localizing = 0; 687 PL_localizing = 0;
689 PL_dirty = 0; 688 PL_dirty = 0;
690 PL_restartop = 0; 689 PL_restartop = 0;
691 PL_diehook = 0; hv_store (hv_sig, strpair ("__DIE__" ), SvREFCNT_inc (sv_diehook ), 0); 690 PL_diehook = 0; hv_store (hv_sig, "__DIE__" , sizeof ("__DIE__" ) - 1, SvREFCNT_inc (sv_diehook ), 0);
692 PL_warnhook = 0; hv_store (hv_sig, strpair ("__WARN__"), SvREFCNT_inc (sv_warnhook), 0); 691 PL_warnhook = 0; hv_store (hv_sig, "__WARN__", sizeof ("__WARN__") - 1, SvREFCNT_inc (sv_warnhook), 0);
693 692
694 GvSV (PL_defgv) = newSV (0); 693 GvSV (PL_defgv) = newSV (0);
695 GvAV (PL_defgv) = coro->args; coro->args = 0; 694 GvAV (PL_defgv) = coro->args; coro->args = 0;
696 GvSV (PL_errgv) = newSV (0); 695 GvSV (PL_errgv) = newSV (0);
697 GvSV (irsgv) = newSVpvn ("\n", 1); sv_magic (GvSV (irsgv), (SV *)irsgv, PERL_MAGIC_sv, "/", 0); 696 GvSV (irsgv) = newSVpvn ("\n", 1); sv_magic (GvSV (irsgv), (SV *)irsgv, PERL_MAGIC_sv, "/", 0);
712 PL_op = (OP *)&myop; 711 PL_op = (OP *)&myop;
713 PL_op = PL_ppaddr[OP_ENTERSUB](aTHX); 712 PL_op = PL_ppaddr[OP_ENTERSUB](aTHX);
714 SPAGAIN; 713 SPAGAIN;
715 } 714 }
716 715
717 ENTER; /* necessary e.g. for dounwind and to balance the xsub-entersub */ 716 /* this newly created coroutine might be run on an existing cctx which most
717 * likely was suspended in set_stacklevel, called from entersub.
718 * set_stacklevl doesn't do anything on return, but entersub does LEAVE,
719 * so we ENTER here for symmetry
720 */
721 ENTER;
718} 722}
719 723
720static void 724static void
721coro_destroy (pTHX_ struct coro *coro) 725coro_destroy (pTHX_ struct coro *coro)
722{ 726{
806 PUSHMARK (SP); 810 PUSHMARK (SP);
807 PUSHs (&PL_sv_no); 811 PUSHs (&PL_sv_no);
808 PUSHs (fullname); 812 PUSHs (fullname);
809 PUSHs (sv_2mortal (newRV_noinc ((SV *)av))); 813 PUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
810 PUTBACK; 814 PUTBACK;
811 cb = hv_fetch ((HV *)SvRV (coro_current), strpair ("_trace_sub_cb"), 0); 815 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0);
812 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 816 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
813 SPAGAIN; 817 SPAGAIN;
814 FREETMPS; 818 FREETMPS;
815 LEAVE; 819 LEAVE;
816 PL_runops = runops_trace; 820 PL_runops = runops_trace;
845 PUSHMARK (SP); 849 PUSHMARK (SP);
846 PUSHs (&PL_sv_yes); 850 PUSHs (&PL_sv_yes);
847 PUSHs (fullname); 851 PUSHs (fullname);
848 PUSHs (cx->blk_sub.hasargs ? sv_2mortal (newRV_inc ((SV *)cx->blk_sub.argarray)) : &PL_sv_undef); 852 PUSHs (cx->blk_sub.hasargs ? sv_2mortal (newRV_inc ((SV *)cx->blk_sub.argarray)) : &PL_sv_undef);
849 PUTBACK; 853 PUTBACK;
850 cb = hv_fetch ((HV *)SvRV (coro_current), strpair ("_trace_sub_cb"), 0); 854 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0);
851 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 855 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
852 SPAGAIN; 856 SPAGAIN;
853 FREETMPS; 857 FREETMPS;
854 LEAVE; 858 LEAVE;
855 PL_runops = runops_trace; 859 PL_runops = runops_trace;
869 PL_runops = RUNOPS_DEFAULT; 873 PL_runops = RUNOPS_DEFAULT;
870 PUSHMARK (SP); 874 PUSHMARK (SP);
871 PUSHs (sv_2mortal (newSVpv (OutCopFILE (oldcop), 0))); 875 PUSHs (sv_2mortal (newSVpv (OutCopFILE (oldcop), 0)));
872 PUSHs (sv_2mortal (newSViv (CopLINE (oldcop)))); 876 PUSHs (sv_2mortal (newSViv (CopLINE (oldcop))));
873 PUTBACK; 877 PUTBACK;
874 cb = hv_fetch ((HV *)SvRV (coro_current), strpair ("_trace_line_cb"), 0); 878 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_line_cb", sizeof ("_trace_line_cb") - 1, 0);
875 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 879 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
876 SPAGAIN; 880 SPAGAIN;
877 FREETMPS; 881 FREETMPS;
878 LEAVE; 882 LEAVE;
879 PL_runops = runops_trace; 883 PL_runops = runops_trace;
1506 1510
1507 hv_sig = coro_get_hv ("SIG", TRUE); 1511 hv_sig = coro_get_hv ("SIG", TRUE);
1508 sv_diehook = coro_get_sv ("Coro::State::DIEHOOK" , TRUE); 1512 sv_diehook = coro_get_sv ("Coro::State::DIEHOOK" , TRUE);
1509 sv_warnhook = coro_get_sv ("Coro::State::WARNHOOK", TRUE); 1513 sv_warnhook = coro_get_sv ("Coro::State::WARNHOOK", TRUE);
1510 1514
1511 if (!PL_diehook ) hv_store (hv_sig, strpair ("__DIE__" ), SvREFCNT_inc (sv_diehook ), 0); 1515 if (!PL_diehook ) hv_store (hv_sig, "__DIE__" , sizeof ("__DIE__" ) - 1, SvREFCNT_inc (sv_diehook ), 0);
1512 if (!PL_warnhook) hv_store (hv_sig, strpair ("__WARN__"), SvREFCNT_inc (sv_warnhook), 0); 1516 if (!PL_warnhook) hv_store (hv_sig, "__WARN__", sizeof ("__WARN__") - 1, SvREFCNT_inc (sv_warnhook), 0);
1513 1517
1514 coro_state_stash = gv_stashpv ("Coro::State", TRUE); 1518 coro_state_stash = gv_stashpv ("Coro::State", TRUE);
1515 1519
1516 newCONSTSUB (coro_state_stash, "CC_TRACE" , newSViv (CC_TRACE)); 1520 newCONSTSUB (coro_state_stash, "CC_TRACE" , newSViv (CC_TRACE));
1517 newCONSTSUB (coro_state_stash, "CC_TRACE_SUB" , newSViv (CC_TRACE_SUB)); 1521 newCONSTSUB (coro_state_stash, "CC_TRACE_SUB" , newSViv (CC_TRACE_SUB));
1523 1527
1524 while (main_top_env->je_prev) 1528 while (main_top_env->je_prev)
1525 main_top_env = main_top_env->je_prev; 1529 main_top_env = main_top_env->je_prev;
1526 1530
1527 coroapi.ver = CORO_API_VERSION; 1531 coroapi.ver = CORO_API_VERSION;
1532 coroapi.rev = CORO_API_REVISION;
1528 coroapi.transfer = api_transfer; 1533 coroapi.transfer = api_transfer;
1529 1534
1530 assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL)); 1535 assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL));
1531} 1536}
1532 1537
1561# function to increase chances that they all will call transfer with the same 1566# function to increase chances that they all will call transfer with the same
1562# stack offset 1567# stack offset
1563void 1568void
1564_set_stacklevel (...) 1569_set_stacklevel (...)
1565 ALIAS: 1570 ALIAS:
1566 Coro::State::transfer = 1 1571 Coro::State::transfer = 1
1567 Coro::schedule = 2 1572 Coro::schedule = 2
1568 Coro::cede = 3 1573 Coro::cede = 3
1569 Coro::cede_notself = 4 1574 Coro::cede_notself = 4
1570 Coro::Event::next = 5
1571 Coro::Event::next_cancel = 6
1572 PPCODE: 1575 CODE:
1573{ 1576{
1574 struct transfer_args ta; 1577 struct transfer_args ta;
1575 int repeat = 0;
1576 1578
1577 do 1579 switch (ix)
1578 { 1580 {
1579 switch (ix)
1580 {
1581 case 0: 1581 case 0:
1582 ta.prev = (struct coro *)INT2PTR (coro_cctx *, SvIV (ST (0))); 1582 ta.prev = (struct coro *)INT2PTR (coro_cctx *, SvIV (ST (0)));
1583 ta.next = 0; 1583 ta.next = 0;
1584 break; 1584 break;
1585 1585
1586 case 1: 1586 case 1:
1587 if (items != 2) 1587 if (items != 2)
1588 croak ("Coro::State::transfer (prev,next) expects two arguments, not %d", items); 1588 croak ("Coro::State::transfer (prev,next) expects two arguments, not %d", items);
1589 1589
1590 prepare_transfer (aTHX_ &ta, ST (0), ST (1)); 1590 prepare_transfer (aTHX_ &ta, ST (0), ST (1));
1591 break; 1591 break;
1592 1592
1593 case 2: 1593 case 2:
1594 prepare_schedule (aTHX_ &ta); 1594 prepare_schedule (aTHX_ &ta);
1595 break; 1595 break;
1596 1596
1597 case 3: 1597 case 3:
1598 prepare_cede (aTHX_ &ta); 1598 prepare_cede (aTHX_ &ta);
1599 break; 1599 break;
1600 1600
1601 case 4: 1601 case 4:
1602 if (!prepare_cede_notself (aTHX_ &ta)) 1602 if (!prepare_cede_notself (aTHX_ &ta))
1603 XSRETURN_EMPTY; 1603 XSRETURN_EMPTY;
1604 1604
1605 break; 1605 break;
1606
1607 case 5:
1608 case 6:
1609 if (items != 1)
1610 croak ("Coro::Event::next (watcher) expects one argument, not %d", items);
1611
1612 {
1613 SV *ev = coroapi.coro_event_next (ST (0), ix == 6, GIMME_V != G_VOID);
1614
1615 if (ev)
1616 {
1617 if (GIMME_V != G_VOID)
1618 {
1619 XPUSHs (ev);
1620 XSRETURN (1);
1621 }
1622 else
1623 XSRETURN_EMPTY;
1624 }
1625 }
1626
1627 prepare_schedule (aTHX_ &ta);
1628 repeat = 1;
1629 break;
1630 }
1631
1632 BARRIER;
1633 TRANSFER (ta);
1634 BARRIER;
1635 } 1606 }
1636 while (repeat);
1637 1607
1638 if (expect_false (GIMME_V != G_VOID && ta.next != ta.prev)) 1608 BARRIER;
1639 XSRETURN_YES; 1609 PUTBACK;
1610 TRANSFER (ta);
1611 SPAGAIN; /* might be the sp of a different coroutine now */
1612 /* be extra careful not to ever do anything after TRANSFER */
1640} 1613}
1641 1614
1642bool 1615bool
1643_destroy (SV *coro_sv) 1616_destroy (SV *coro_sv)
1644 CODE: 1617 CODE:
1704 1677
1705 { 1678 {
1706 dSP; 1679 dSP;
1707 ENTER; 1680 ENTER;
1708 SAVETMPS; 1681 SAVETMPS;
1682 PUTBACK;
1683 PUSHSTACK;
1709 PUSHMARK (SP); 1684 PUSHMARK (SP);
1710 PUTBACK;
1711 1685
1712 if (ix) 1686 if (ix)
1713 eval_sv (coderef, 0); 1687 eval_sv (coderef, 0);
1714 else 1688 else
1715 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 1689 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1716 1690
1691 POPSTACK;
1717 SPAGAIN; 1692 SPAGAIN;
1718 FREETMPS; 1693 FREETMPS;
1719 LEAVE; 1694 LEAVE;
1720 PUTBACK; 1695 PUTBACK;
1721 } 1696 }
1876 CODE: 1851 CODE:
1877{ 1852{
1878 struct coro *coro = SvSTATE (coro_current); 1853 struct coro *coro = SvSTATE (coro_current);
1879 HV *hv = (HV *)SvRV (coro_current); 1854 HV *hv = (HV *)SvRV (coro_current);
1880 AV *defav = GvAV (PL_defgv); 1855 AV *defav = GvAV (PL_defgv);
1881 SV *invoke = hv_delete (hv, strpair ("_invoke"), 0); 1856 SV *invoke = hv_delete (hv, "_invoke", sizeof ("_invoke") - 1, 0);
1882 AV *invoke_av; 1857 AV *invoke_av;
1883 int i, len; 1858 int i, len;
1884 1859
1885 if (!invoke) 1860 if (!invoke)
1886 croak ("\3async_pool terminate\2\n"); 1861 croak ("\3async_pool terminate\2\n");
1887 1862
1888 SvREFCNT_dec (coro->saved_deffh); 1863 SvREFCNT_dec (coro->saved_deffh);
1889 coro->saved_deffh = SvREFCNT_inc ((SV *)PL_defoutgv); 1864 coro->saved_deffh = SvREFCNT_inc ((SV *)PL_defoutgv);
1890 1865
1891 hv_store (hv, "desc", sizeof ("desc") - 1, 1866 hv_store (hv, "desc", sizeof ("desc") - 1,
1892 newSVpvn (strpair ("[async_pool]")), 0); 1867 newSVpvn ("[async_pool]", sizeof ("[async_pool]") - 1), 0);
1893 1868
1894 invoke_av = (AV *)SvRV (invoke); 1869 invoke_av = (AV *)SvRV (invoke);
1895 len = av_len (invoke_av); 1870 len = av_len (invoke_av);
1896 1871
1897 sv_setsv (cb, AvARRAY (invoke_av)[0]); 1872 sv_setsv (cb, AvARRAY (invoke_av)[0]);
1920 if (coro_rss (aTHX_ coro) > SvIV (sv_pool_rss) 1895 if (coro_rss (aTHX_ coro) > SvIV (sv_pool_rss)
1921 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size)) 1896 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size))
1922 croak ("\3async_pool terminate\2\n"); 1897 croak ("\3async_pool terminate\2\n");
1923 1898
1924 av_clear (GvAV (PL_defgv)); 1899 av_clear (GvAV (PL_defgv));
1925 hv_store ((HV *)SvRV (coro_current), strpair ("desc"), 1900 hv_store ((HV *)SvRV (coro_current), "desc", sizeof ("desc") - 1,
1926 newSVpvn (strpair ("[async_pool idle]")), 0); 1901 newSVpvn ("[async_pool idle]", sizeof ("[async_pool idle]") - 1), 0);
1927 1902
1928 coro->prio = 0; 1903 coro->prio = 0;
1929 1904
1930 if (coro->cctx && (coro->cctx->flags & CC_TRACE)) 1905 if (coro->cctx && (coro->cctx->flags & CC_TRACE))
1931 api_trace (coro_current, 0); 1906 api_trace (coro_current, 0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines