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.303 by root, Wed Nov 19 05:52:42 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 */
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
2158 AvARRAY (av)[0] = AvARRAY (av)[1]; 2294 AvARRAY (av)[0] = AvARRAY (av)[1];
2159 AvARRAY (av)[1] = cb; 2295 AvARRAY (av)[1] = cb;
2160 2296
2161 cb = av_shift (av); 2297 cb = av_shift (av);
2162 2298
2163 api_ready (cb); 2299 api_ready (aTHX_ cb);
2164 sv_setiv (cb, 0); /* signal waiter */ 2300 sv_setiv (cb, 0); /* signal waiter */
2165 SvREFCNT_dec (cb); 2301 SvREFCNT_dec (cb);
2166 2302
2167 --count; 2303 --count;
2168 } 2304 }
2194 2330
2195 frame->data = (void *)sv_2mortal (SvREFCNT_inc_NN (waiter)); /* owned by process */ 2331 frame->data = (void *)sv_2mortal (SvREFCNT_inc_NN (waiter)); /* owned by process */
2196 frame->prepare = prepare_schedule; 2332 frame->prepare = prepare_schedule;
2197 frame->check = slf_check_signal_wait; 2333 frame->check = slf_check_signal_wait;
2198 } 2334 }
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} 2335}
2223 2336
2224/*****************************************************************************/ 2337/*****************************************************************************/
2225/* Coro::AIO */ 2338/* Coro::AIO */
2226 2339
2867 api_trace (aTHX_ coro_current, 0); 2980 api_trace (aTHX_ coro_current, 0);
2868 2981
2869 av_push (av_async_pool, newSVsv (coro_current)); 2982 av_push (av_async_pool, newSVsv (coro_current));
2870} 2983}
2871 2984
2985SV *
2986rouse_cb ()
2987 PROTOTYPE:
2988 CODE:
2989 RETVAL = coro_new_rouse_cb (aTHX);
2990 OUTPUT:
2991 RETVAL
2992
2993void
2994rouse_wait (SV *cb = 0)
2995 PROTOTYPE: ;$
2996 PPCODE:
2997 CORO_EXECUTE_SLF_XS (slf_init_rouse_wait);
2998
2872 2999
2873MODULE = Coro::State PACKAGE = PerlIO::cede 3000MODULE = Coro::State PACKAGE = PerlIO::cede
2874 3001
2875BOOT: 3002BOOT:
2876 PerlIO_define_layer (aTHX_ &PerlIO_cede); 3003 PerlIO_define_layer (aTHX_ &PerlIO_cede);
2986 CODE: 3113 CODE:
2987{ 3114{
2988 AV *av = (AV *)SvRV (self); 3115 AV *av = (AV *)SvRV (self);
2989 3116
2990 if (AvFILLp (av)) 3117 if (AvFILLp (av))
2991 coro_signal_wake (av, 1); 3118 coro_signal_wake (aTHX_ av, 1);
2992 else 3119 else
2993 SvIVX (AvARRAY (av)[0]) = 1; /* remember the signal */ 3120 SvIVX (AvARRAY (av)[0]) = 1; /* remember the signal */
2994} 3121}
2995 3122
2996IV 3123IV

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines