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.300 by root, Wed Nov 19 02:07:48 2008 UTC vs.
Revision 1.305 by root, Wed Nov 19 10:44:41 2008 UTC

16 16
17#ifdef WIN32 17#ifdef WIN32
18# undef setjmp 18# undef setjmp
19# undef longjmp 19# undef longjmp
20# undef _exit 20# undef _exit
21# define setjmp _setjmp // deep magic, don't ask 21# define setjmp _setjmp /* deep magic */
22#else 22#else
23# include <inttypes.h> /* most portable stdint.h */ 23# include <inttypes.h> /* most portable stdint.h */
24#endif 24#endif
25 25
26#ifdef HAVE_MMAP 26#ifdef HAVE_MMAP
258 int usecount; /* number of transfers to this coro */ 258 int usecount; /* number of transfers to this coro */
259 259
260 /* coro process data */ 260 /* coro process data */
261 int prio; 261 int prio;
262 SV *except; /* exception to be thrown */ 262 SV *except; /* exception to be thrown */
263 SV *rouse_cb;
263 264
264 /* async_pool */ 265 /* async_pool */
265 SV *saved_deffh; 266 SV *saved_deffh;
266 267
267 /* linked list */ 268 /* linked list */
448 else 449 else
449 { 450 {
450#if CORO_PREFER_PERL_FUNCTIONS 451#if CORO_PREFER_PERL_FUNCTIONS
451 /* this is probably cleaner? but also slower! */ 452 /* this is probably cleaner? but also slower! */
452 /* in practise, it seems to be less stable */ 453 /* in practise, it seems to be less stable */
453 CV *cp = Perl_cv_clone (cv); 454 CV *cp = Perl_cv_clone (aTHX_ cv);
454 CvPADLIST (cv) = CvPADLIST (cp); 455 CvPADLIST (cv) = CvPADLIST (cp);
455 CvPADLIST (cp) = 0; 456 CvPADLIST (cp) = 0;
456 SvREFCNT_dec (cp); 457 SvREFCNT_dec (cp);
457#else 458#else
458 CvPADLIST (cv) = coro_clone_padlist (aTHX_ cv); 459 CvPADLIST (cv) = coro_clone_padlist (aTHX_ cv);
602 * of perl.c:init_stacks, except that it uses less memory 603 * of perl.c:init_stacks, except that it uses less memory
603 * on the (sometimes correct) assumption that coroutines do 604 * on the (sometimes correct) assumption that coroutines do
604 * not usually need a lot of stackspace. 605 * not usually need a lot of stackspace.
605 */ 606 */
606#if CORO_PREFER_PERL_FUNCTIONS 607#if CORO_PREFER_PERL_FUNCTIONS
607# define coro_init_stacks init_stacks 608# define coro_init_stacks(thx) init_stacks ()
608#else 609#else
609static void 610static void
610coro_init_stacks (pTHX) 611coro_init_stacks (pTHX)
611{ 612{
612 PL_curstackinfo = new_stackinfo(32, 8); 613 PL_curstackinfo = new_stackinfo(32, 8);
918 SvREFCNT_dec (GvSV (irsgv)); 919 SvREFCNT_dec (GvSV (irsgv));
919 920
920 SvREFCNT_dec (PL_diehook); 921 SvREFCNT_dec (PL_diehook);
921 SvREFCNT_dec (PL_warnhook); 922 SvREFCNT_dec (PL_warnhook);
922 923
924 SvREFCNT_dec (CORO_THROW);
923 SvREFCNT_dec (coro->saved_deffh); 925 SvREFCNT_dec (coro->saved_deffh);
924 SvREFCNT_dec (CORO_THROW); 926 SvREFCNT_dec (coro->rouse_cb);
925 927
926 coro_destruct_stacks (aTHX); 928 coro_destruct_stacks (aTHX);
927} 929}
928 930
929INLINE void 931INLINE void
1497 1499
1498 prepare_transfer (aTHX_ &ta, prev_sv, next_sv); 1500 prepare_transfer (aTHX_ &ta, prev_sv, next_sv);
1499 TRANSFER (ta, 1); 1501 TRANSFER (ta, 1);
1500} 1502}
1501 1503
1504/*****************************************************************************/
1505/* gensub: simple closure generation utility */
1506
1507#define GENSUB_ARG CvXSUBANY (cv).any_ptr
1508
1509/* create a closure from XS, returns a code reference */
1510/* the arg can be accessed via GENSUB_ARG from the callback */
1511/* the callback must use dXSARGS/XSRETURN */
1512static SV *
1513gensub (pTHX_ void (*xsub)(pTHX_ CV *), void *arg)
1514{
1515 CV *cv = (CV *)newSV (0);
1516
1517 sv_upgrade ((SV *)cv, SVt_PVCV);
1518
1519 CvANON_on (cv);
1520 CvISXSUB_on (cv);
1521 CvXSUB (cv) = xsub;
1522 GENSUB_ARG = arg;
1523
1524 return newRV_noinc ((SV *)cv);
1525}
1526
1502/** Coro ********************************************************************/ 1527/** Coro ********************************************************************/
1503 1528
1504INLINE void 1529INLINE void
1505coro_enq (pTHX_ struct coro *coro) 1530coro_enq (pTHX_ struct coro *coro)
1506{ 1531{
1703 if (coro->flags & CF_RUNNING) 1728 if (coro->flags & CF_RUNNING)
1704 PL_runops = RUNOPS_DEFAULT; 1729 PL_runops = RUNOPS_DEFAULT;
1705 else 1730 else
1706 coro->slot->runops = RUNOPS_DEFAULT; 1731 coro->slot->runops = RUNOPS_DEFAULT;
1707 } 1732 }
1733}
1734
1735/*****************************************************************************/
1736/* rouse callback */
1737
1738#define CORO_MAGIC_type_rouse PERL_MAGIC_ext
1739
1740static void
1741coro_rouse_callback (pTHX_ CV *cv)
1742{
1743 dXSARGS;
1744 SV *data = (SV *)GENSUB_ARG;
1745
1746 if (SvTYPE (SvRV (data)) != SVt_PVAV)
1747 {
1748 /* first call, set args */
1749 int i;
1750 AV *av = newAV ();
1751 SV *coro = SvRV (data);
1752
1753 SvRV_set (data, (SV *)av);
1754 api_ready (aTHX_ coro);
1755 SvREFCNT_dec (coro);
1756
1757 /* better take a full copy of the arguments */
1758 while (items--)
1759 av_store (av, items, newSVsv (ST (items)));
1760 }
1761
1762 XSRETURN_EMPTY;
1763}
1764
1765static int
1766slf_check_rouse_wait (pTHX_ struct CoroSLF *frame)
1767{
1768 SV *data = (SV *)frame->data;
1769
1770 if (CORO_THROW)
1771 return 0;
1772
1773 if (SvTYPE (SvRV (data)) != SVt_PVAV)
1774 return 1;
1775
1776 /* now push all results on the stack */
1777 {
1778 dSP;
1779 AV *av = (AV *)SvRV (data);
1780 int i;
1781
1782 EXTEND (SP, AvFILLp (av) + 1);
1783 for (i = 0; i <= AvFILLp (av); ++i)
1784 PUSHs (sv_2mortal (AvARRAY (av)[i]));
1785
1786 /* we have stolen the elements, so ste length to zero and free */
1787 AvFILLp (av) = -1;
1788 av_undef (av);
1789
1790 PUTBACK;
1791 }
1792
1793 return 0;
1794}
1795
1796static void
1797slf_init_rouse_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1798{
1799 SV *cb;
1800
1801 if (items)
1802 cb = arg [0];
1803 else
1804 {
1805 struct coro *coro = SvSTATE_current;
1806
1807 if (!coro->rouse_cb)
1808 croak ("Coro::rouse_wait called without rouse callback, and no default rouse callback found either,");
1809
1810 cb = sv_2mortal (coro->rouse_cb);
1811 coro->rouse_cb = 0;
1812 }
1813
1814 if (!SvROK (cb)
1815 || SvTYPE (SvRV (cb)) != SVt_PVCV
1816 || CvXSUB ((CV *)SvRV (cb)) != coro_rouse_callback)
1817 croak ("Coro::rouse_wait called with illegal callback argument,");
1818
1819 {
1820 CV *cv = (CV *)SvRV (cb); /* for GENSUB_ARG */
1821 SV *data = (SV *)GENSUB_ARG;
1822
1823 frame->data = (void *)data;
1824 frame->prepare = SvTYPE (SvRV (data)) == SVt_PVAV ? prepare_nop : prepare_schedule;
1825 frame->check = slf_check_rouse_wait;
1826 }
1827}
1828
1829static SV *
1830coro_new_rouse_cb (pTHX)
1831{
1832 HV *hv = (HV *)SvRV (coro_current);
1833 struct coro *coro = SvSTATE_hv (hv);
1834 SV *data = newRV_inc ((SV *)hv);
1835 SV *cb = gensub (aTHX_ coro_rouse_callback, (void *)data);
1836
1837 sv_magicext (SvRV (cb), data, CORO_MAGIC_type_rouse, 0, 0, 0);
1838 SvREFCNT_dec (data); /* magicext increases the refcount */
1839
1840 SvREFCNT_dec (coro->rouse_cb);
1841 coro->rouse_cb = SvREFCNT_inc_NN (cb);
1842
1843 return cb;
1708} 1844}
1709 1845
1710/*****************************************************************************/ 1846/*****************************************************************************/
1711/* schedule-like-function opcode (SLF) */ 1847/* schedule-like-function opcode (SLF) */
1712 1848
2007 SV **ary; 2143 SV **ary;
2008 2144
2009 /* unfortunately, building manually saves memory */ 2145 /* unfortunately, building manually saves memory */
2010 Newx (ary, 2, SV *); 2146 Newx (ary, 2, SV *);
2011 AvALLOC (av) = ary; 2147 AvALLOC (av) = ary;
2012 AvARRAY (av) = ary; 2148 /*AvARRAY (av) = ary;*/
2149 SvPVX ((SV *)av) = (char *)ary; /* 5.8.8 needs this syntax instead of AvARRAY = ary */
2013 AvMAX (av) = 1; 2150 AvMAX (av) = 1;
2014 AvFILLp (av) = 0; 2151 AvFILLp (av) = 0;
2015 ary [0] = newSViv (count); 2152 ary [0] = newSViv (count);
2016 2153
2017 return newRV_noinc ((SV *)av); 2154 return newRV_noinc ((SV *)av);
2158 AvARRAY (av)[0] = AvARRAY (av)[1]; 2295 AvARRAY (av)[0] = AvARRAY (av)[1];
2159 AvARRAY (av)[1] = cb; 2296 AvARRAY (av)[1] = cb;
2160 2297
2161 cb = av_shift (av); 2298 cb = av_shift (av);
2162 2299
2163 api_ready (cb); 2300 api_ready (aTHX_ cb);
2164 sv_setiv (cb, 0); /* signal waiter */ 2301 sv_setiv (cb, 0); /* signal waiter */
2165 SvREFCNT_dec (cb); 2302 SvREFCNT_dec (cb);
2166 2303
2167 --count; 2304 --count;
2168 } 2305 }
2194 2331
2195 frame->data = (void *)sv_2mortal (SvREFCNT_inc_NN (waiter)); /* owned by process */ 2332 frame->data = (void *)sv_2mortal (SvREFCNT_inc_NN (waiter)); /* owned by process */
2196 frame->prepare = prepare_schedule; 2333 frame->prepare = prepare_schedule;
2197 frame->check = slf_check_signal_wait; 2334 frame->check = slf_check_signal_wait;
2198 } 2335 }
2199}
2200
2201/*****************************************************************************/
2202/* gensub: simple closure generation utility */
2203
2204#define GENSUB_ARG CvXSUBANY (cv).any_ptr
2205
2206/* create a closure from XS, returns a code reference */
2207/* the arg can be accessed via GENSUB_ARG from the callback */
2208/* the callback must use dXSARGS/XSRETURN */
2209static SV *
2210gensub (pTHX_ void (*xsub)(pTHX_ CV *), void *arg)
2211{
2212 CV *cv = (CV *)newSV (0);
2213
2214 sv_upgrade ((SV *)cv, SVt_PVCV);
2215
2216 CvANON_on (cv);
2217 CvISXSUB_on (cv);
2218 CvXSUB (cv) = xsub;
2219 GENSUB_ARG = arg;
2220
2221 return newRV_noinc ((SV *)cv);
2222} 2336}
2223 2337
2224/*****************************************************************************/ 2338/*****************************************************************************/
2225/* Coro::AIO */ 2339/* Coro::AIO */
2226 2340
2867 api_trace (aTHX_ coro_current, 0); 2981 api_trace (aTHX_ coro_current, 0);
2868 2982
2869 av_push (av_async_pool, newSVsv (coro_current)); 2983 av_push (av_async_pool, newSVsv (coro_current));
2870} 2984}
2871 2985
2986SV *
2987rouse_cb ()
2988 PROTOTYPE:
2989 CODE:
2990 RETVAL = coro_new_rouse_cb (aTHX);
2991 OUTPUT:
2992 RETVAL
2993
2994void
2995rouse_wait (SV *cb = 0)
2996 PROTOTYPE: ;$
2997 PPCODE:
2998 CORO_EXECUTE_SLF_XS (slf_init_rouse_wait);
2999
2872 3000
2873MODULE = Coro::State PACKAGE = PerlIO::cede 3001MODULE = Coro::State PACKAGE = PerlIO::cede
2874 3002
2875BOOT: 3003BOOT:
2876 PerlIO_define_layer (aTHX_ &PerlIO_cede); 3004 PerlIO_define_layer (aTHX_ &PerlIO_cede);
2986 CODE: 3114 CODE:
2987{ 3115{
2988 AV *av = (AV *)SvRV (self); 3116 AV *av = (AV *)SvRV (self);
2989 3117
2990 if (AvFILLp (av)) 3118 if (AvFILLp (av))
2991 coro_signal_wake (av, 1); 3119 coro_signal_wake (aTHX_ av, 1);
2992 else 3120 else
2993 SvIVX (AvARRAY (av)[0]) = 1; /* remember the signal */ 3121 SvIVX (AvARRAY (av)[0]) = 1; /* remember the signal */
2994} 3122}
2995 3123
2996IV 3124IV

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines