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.202 by root, Mon Oct 8 02:50:23 2007 UTC vs.
Revision 1.208 by root, Wed Oct 10 00:53:18 2007 UTC

221 221
222 /* process data */ 222 /* process data */
223 AV *mainstack; 223 AV *mainstack;
224 perl_slots *slot; /* basically the saved sp */ 224 perl_slots *slot; /* basically the saved sp */
225 225
226 /* data associated with this coroutine (initial args) */ 226 AV *args; /* data associated with this coroutine (initial args) */
227 AV *args; 227 int refcnt; /* coroutines are refcounted, yes */
228 int refcnt;
229 int flags; /* CF_ flags */ 228 int flags; /* CF_ flags */
229 HV *hv; /* the perl hash associated with this coro, if any */
230 230
231 /* statistics */ 231 /* statistics */
232 int usecount; /* number of transfers to this coro */ 232 int usecount; /* number of transfers to this coro */
233 233
234 /* coro process data */ 234 /* coro process data */
235 int prio; 235 int prio;
236 SV *throw; 236 SV *throw; /* exception to be thrown */
237 237
238 /* async_pool */ 238 /* async_pool */
239 SV *saved_deffh; 239 SV *saved_deffh;
240 240
241 /* linked list */ 241 /* linked list */
242 struct coro *next, *prev; 242 struct coro *next, *prev;
243 HV *hv; /* the perl hash associated with this coro, if any */
244}; 243};
245 244
246typedef struct coro *Coro__State; 245typedef struct coro *Coro__State;
247typedef struct coro *Coro__State_or_hashref; 246typedef struct coro *Coro__State_or_hashref;
248 247
557 * allocate various perl stacks. This is an exact copy 556 * allocate various perl stacks. This is an exact copy
558 * of perl.c:init_stacks, except that it uses less memory 557 * of perl.c:init_stacks, except that it uses less memory
559 * on the (sometimes correct) assumption that coroutines do 558 * on the (sometimes correct) assumption that coroutines do
560 * not usually need a lot of stackspace. 559 * not usually need a lot of stackspace.
561 */ 560 */
562#if 1 561#if CORO_PREFER_PERL_FUNCTIONS
563# define coro_init_stacks init_stacks 562# define coro_init_stacks init_stacks
564#else 563#else
565static void 564static void
566coro_init_stacks (pTHX) 565coro_init_stacks (pTHX)
567{ 566{
1562# function to increase chances that they all will call transfer with the same 1561# function to increase chances that they all will call transfer with the same
1563# stack offset 1562# stack offset
1564void 1563void
1565_set_stacklevel (...) 1564_set_stacklevel (...)
1566 ALIAS: 1565 ALIAS:
1567 Coro::State::transfer = 1 1566 Coro::State::transfer = 1
1568 Coro::schedule = 2 1567 Coro::schedule = 2
1569 Coro::cede = 3 1568 Coro::cede = 3
1570 Coro::cede_notself = 4 1569 Coro::cede_notself = 4
1570 Coro::Event::next = 5
1571 Coro::Event::next_cancel = 6
1571 CODE: 1572 PPCODE:
1572{ 1573{
1573 struct transfer_args ta; 1574 struct transfer_args ta;
1575 int again = 0;
1574 1576
1575 switch (ix) 1577 do
1576 { 1578 {
1579 switch (ix)
1580 {
1577 case 0: 1581 case 0:
1578 ta.prev = (struct coro *)INT2PTR (coro_cctx *, SvIV (ST (0))); 1582 ta.prev = (struct coro *)INT2PTR (coro_cctx *, SvIV (ST (0)));
1579 ta.next = 0; 1583 ta.next = 0;
1580 break; 1584 break;
1581 1585
1582 case 1: 1586 case 1:
1583 if (items != 2) 1587 if (items != 2)
1584 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);
1585 1589
1586 prepare_transfer (aTHX_ &ta, ST (0), ST (1)); 1590 prepare_transfer (aTHX_ &ta, ST (0), ST (1));
1587 break; 1591 break;
1588 1592
1589 case 2: 1593 case 2:
1590 prepare_schedule (aTHX_ &ta); 1594 prepare_schedule (aTHX_ &ta);
1591 break; 1595 break;
1592 1596
1593 case 3: 1597 case 3:
1594 prepare_cede (aTHX_ &ta); 1598 prepare_cede (aTHX_ &ta);
1595 break; 1599 break;
1596 1600
1597 case 4: 1601 case 4:
1598 if (!prepare_cede_notself (aTHX_ &ta)) 1602 if (!prepare_cede_notself (aTHX_ &ta))
1599 XSRETURN_EMPTY; 1603 XSRETURN_EMPTY;
1600 1604
1601 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 again = 1;
1629 break;
1630 }
1631
1632 BARRIER;
1633 TRANSFER (ta);
1634 BARRIER;
1602 } 1635 }
1603 1636 while (again);
1604 BARRIER;
1605 TRANSFER (ta);
1606 1637
1607 if (expect_false (GIMME_V != G_VOID && ta.next != ta.prev)) 1638 if (expect_false (GIMME_V != G_VOID && ta.next != ta.prev))
1608 XSRETURN_YES; 1639 XSRETURN_YES;
1609} 1640
1641 XSRETURN_EMPTY; /* not understood why this is necessary, likely some stack handling bug */
1610 1642
1611bool 1643bool
1612_destroy (SV *coro_sv) 1644_destroy (SV *coro_sv)
1613 CODE: 1645 CODE:
1614 RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv)); 1646 RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv));
1673 1705
1674 { 1706 {
1675 dSP; 1707 dSP;
1676 ENTER; 1708 ENTER;
1677 SAVETMPS; 1709 SAVETMPS;
1710 PUTBACK;
1711 PUSHSTACK;
1678 PUSHMARK (SP); 1712 PUSHMARK (SP);
1679 PUTBACK;
1680 1713
1681 if (ix) 1714 if (ix)
1682 eval_sv (coderef, 0); 1715 eval_sv (coderef, 0);
1683 else 1716 else
1684 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 1717 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1685 1718
1686 SPAGAIN; 1719 POPSTACK;
1687 FREETMPS; 1720 FREETMPS;
1688 LEAVE; 1721 LEAVE;
1689 PUTBACK;
1690 } 1722 }
1691 1723
1692 if (!(coro->flags & CF_RUNNING)) 1724 if (!(coro->flags & CF_RUNNING))
1693 { 1725 {
1694 save_perl (aTHX_ coro); 1726 save_perl (aTHX_ coro);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines