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.294 by root, Tue Nov 18 08:31:03 2008 UTC vs.
Revision 1.297 by root, Tue Nov 18 11:04:42 2008 UTC

145#define expect_true(expr) expect ((expr) != 0, 1) 145#define expect_true(expr) expect ((expr) != 0, 1)
146 146
147#define NOINLINE attribute ((noinline)) 147#define NOINLINE attribute ((noinline))
148 148
149#include "CoroAPI.h" 149#include "CoroAPI.h"
150#define GCoroAPI (&coroapi) /* very sneaky */
150 151
151#ifdef USE_ITHREADS 152#ifdef USE_ITHREADS
152# if CORO_PTHREAD 153# if CORO_PTHREAD
153static void *coro_thx; 154static void *coro_thx;
154# endif 155# endif
256 /* statistics */ 257 /* statistics */
257 int usecount; /* number of transfers to this coro */ 258 int usecount; /* number of transfers to this coro */
258 259
259 /* coro process data */ 260 /* coro process data */
260 int prio; 261 int prio;
261 SV *throw; /* exception to be thrown */ 262 SV *except; /* exception to be thrown */
262 263
263 /* async_pool */ 264 /* async_pool */
264 SV *saved_deffh; 265 SV *saved_deffh;
265 266
266 /* linked list */ 267 /* linked list */
272 273
273/* the following variables are effectively part of the perl context */ 274/* the following variables are effectively part of the perl context */
274/* and get copied between struct coro and these variables */ 275/* and get copied between struct coro and these variables */
275/* the mainr easonw e don't support windows process emulation */ 276/* the mainr easonw e don't support windows process emulation */
276static struct CoroSLF slf_frame; /* the current slf frame */ 277static struct CoroSLF slf_frame; /* the current slf frame */
277static SV *coro_throw;
278 278
279/** Coro ********************************************************************/ 279/** Coro ********************************************************************/
280 280
281#define PRIO_MAX 3 281#define PRIO_MAX 3
282#define PRIO_HIGH 1 282#define PRIO_HIGH 1
511 511
512 PUTBACK; 512 PUTBACK;
513 } 513 }
514 514
515 slf_frame = c->slf_frame; 515 slf_frame = c->slf_frame;
516 coro_throw = c->throw; 516 CORO_THROW = c->except;
517} 517}
518 518
519static void 519static void
520save_perl (pTHX_ Coro__State c) 520save_perl (pTHX_ Coro__State c)
521{ 521{
522 c->throw = coro_throw; 522 c->except = CORO_THROW;
523 c->slf_frame = slf_frame; 523 c->slf_frame = slf_frame;
524 524
525 { 525 {
526 dSP; 526 dSP;
527 I32 cxix = cxstack_ix; 527 I32 cxix = cxstack_ix;
885 /* no flags required, as an init function won't be called */ 885 /* no flags required, as an init function won't be called */
886 886
887 PL_op = (OP *)&coro_setup_op; 887 PL_op = (OP *)&coro_setup_op;
888 888
889 /* copy throw, in case it was set before coro_setup */ 889 /* copy throw, in case it was set before coro_setup */
890 coro_throw = coro->throw; 890 CORO_THROW = coro->except;
891} 891}
892 892
893static void 893static void
894coro_destruct (pTHX_ struct coro *coro) 894coro_destruct (pTHX_ struct coro *coro)
895{ 895{
919 919
920 SvREFCNT_dec (PL_diehook); 920 SvREFCNT_dec (PL_diehook);
921 SvREFCNT_dec (PL_warnhook); 921 SvREFCNT_dec (PL_warnhook);
922 922
923 SvREFCNT_dec (coro->saved_deffh); 923 SvREFCNT_dec (coro->saved_deffh);
924 SvREFCNT_dec (coro_throw); 924 SvREFCNT_dec (CORO_THROW);
925 925
926 coro_destruct_stacks (aTHX); 926 coro_destruct_stacks (aTHX);
927} 927}
928 928
929INLINE void 929INLINE void
1839 } 1839 }
1840 while (slf_frame.check (aTHX_ &slf_frame)); 1840 while (slf_frame.check (aTHX_ &slf_frame));
1841 1841
1842 slf_frame.prepare = 0; /* invalidate the frame, we are done processing it */ 1842 slf_frame.prepare = 0; /* invalidate the frame, we are done processing it */
1843 1843
1844 /* exception handling */
1845 if (expect_false (CORO_THROW))
1846 {
1847 SV *exception = sv_2mortal (CORO_THROW);
1848
1849 CORO_THROW = 0;
1850 sv_setsv (ERRSV, exception);
1851 croak (0);
1852 }
1853
1844 /* return value handling - mostly like entersub */ 1854 /* return value handling - mostly like entersub */
1845 /* make sure we put something on the stack in scalar context */ 1855 /* make sure we put something on the stack in scalar context */
1846 if (GIMME_V == G_SCALAR) 1856 if (GIMME_V == G_SCALAR)
1847 { 1857 {
1848 dSP; 1858 dSP;
1854 bot [1] = *sp; 1864 bot [1] = *sp;
1855 1865
1856 SP = bot + 1; 1866 SP = bot + 1;
1857 1867
1858 PUTBACK; 1868 PUTBACK;
1859 }
1860
1861 /* exception handling */
1862 if (expect_false (coro_throw))
1863 {
1864 SV *exception = sv_2mortal (coro_throw);
1865
1866 coro_throw = 0;
1867 sv_setsv (ERRSV, exception);
1868 croak (0);
1869 } 1869 }
1870 1870
1871 return NORMAL; 1871 return NORMAL;
1872} 1872}
1873 1873
2040slf_check_semaphore_down (pTHX_ struct CoroSLF *frame) 2040slf_check_semaphore_down (pTHX_ struct CoroSLF *frame)
2041{ 2041{
2042 AV *av = (AV *)frame->data; 2042 AV *av = (AV *)frame->data;
2043 SV *count_sv = AvARRAY (av)[0]; 2043 SV *count_sv = AvARRAY (av)[0];
2044 2044
2045 /* if we are about to throw, don't actually acquire the lock, just throw */
2046 if (CORO_THROW)
2047 return 0;
2045 if (SvIVX (count_sv) > 0) 2048 else if (SvIVX (count_sv) > 0)
2046 { 2049 {
2047 SvSTATE_current->on_destroy = 0; 2050 SvSTATE_current->on_destroy = 0;
2048 SvIVX (count_sv) = SvIVX (count_sv) - 1; 2051 SvIVX (count_sv) = SvIVX (count_sv) - 1;
2049 return 0; 2052 return 0;
2050 } 2053 }
2071 2074
2072 if (SvIVX (AvARRAY (av)[0]) > 0) 2075 if (SvIVX (AvARRAY (av)[0]) > 0)
2073 { 2076 {
2074 frame->data = (void *)av; 2077 frame->data = (void *)av;
2075 frame->prepare = prepare_nop; 2078 frame->prepare = prepare_nop;
2076 SvSTATE_current->on_destroy = coro_semaphore_on_destroy;
2077 } 2079 }
2078 else 2080 else
2079 { 2081 {
2080 av_push (av, SvREFCNT_inc (SvRV (coro_current))); 2082 av_push (av, SvREFCNT_inc (SvRV (coro_current)));
2081 2083
2082 frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av)); 2084 frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av));
2083 frame->prepare = prepare_schedule; 2085 frame->prepare = prepare_schedule;
2084 2086
2085 /* to avoid race conditions when a woken-up coro gets terminated */ 2087 /* to avoid race conditions when a woken-up coro gets terminated */
2086 /* we arrange for a temporary on_destroy that calls adjust (0) */ 2088 /* we arrange for a temporary on_destroy that calls adjust (0) */
2087 assert (!SvSTATE_current->on_destroy);//D
2088 SvSTATE_current->on_destroy = coro_semaphore_on_destroy; 2089 SvSTATE_current->on_destroy = coro_semaphore_on_destroy;
2089 } 2090 }
2090 2091
2091 frame->check = slf_check_semaphore_down; 2092 frame->check = slf_check_semaphore_down;
2092 2093
2169 2170
2170static int 2171static int
2171slf_check_aio_req (pTHX_ struct CoroSLF *frame) 2172slf_check_aio_req (pTHX_ struct CoroSLF *frame)
2172{ 2173{
2173 AV *state = (AV *)frame->data; 2174 AV *state = (AV *)frame->data;
2175
2176 /* if we are about to throw, return early */
2177 /* this does not cancel the aio request, but at least */
2178 /* it quickly returns */
2179 if (CORO_THROW)
2180 return 0;
2174 2181
2175 /* one element that is an RV? repeat! */ 2182 /* one element that is an RV? repeat! */
2176 if (AvFILLp (state) == 0 && SvROK (AvARRAY (state)[0])) 2183 if (AvFILLp (state) == 0 && SvROK (AvARRAY (state)[0]))
2177 return 1; 2184 return 1;
2178 2185
2510throw (Coro::State self, SV *throw = &PL_sv_undef) 2517throw (Coro::State self, SV *throw = &PL_sv_undef)
2511 PROTOTYPE: $;$ 2518 PROTOTYPE: $;$
2512 CODE: 2519 CODE:
2513{ 2520{
2514 struct coro *current = SvSTATE_current; 2521 struct coro *current = SvSTATE_current;
2515 SV **throwp = self == current ? &coro_throw : &self->throw; 2522 SV **throwp = self == current ? &CORO_THROW : &self->except;
2516 SvREFCNT_dec (*throwp); 2523 SvREFCNT_dec (*throwp);
2517 *throwp = SvOK (throw) ? newSVsv (throw) : 0; 2524 *throwp = SvOK (throw) ? newSVsv (throw) : 0;
2518} 2525}
2519 2526
2520void 2527void
2609 coroapi.ready = api_ready; 2616 coroapi.ready = api_ready;
2610 coroapi.is_ready = api_is_ready; 2617 coroapi.is_ready = api_is_ready;
2611 coroapi.nready = coro_nready; 2618 coroapi.nready = coro_nready;
2612 coroapi.current = coro_current; 2619 coroapi.current = coro_current;
2613 2620
2614 GCoroAPI = &coroapi; 2621 /*GCoroAPI = &coroapi;*/
2615 sv_setiv (sv, (IV)&coroapi); 2622 sv_setiv (sv, (IV)&coroapi);
2616 SvREADONLY_on (sv); 2623 SvREADONLY_on (sv);
2617 } 2624 }
2618} 2625}
2619 2626

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines