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.274 by root, Sat Nov 15 00:08:30 2008 UTC vs.
Revision 1.276 by root, Sat Nov 15 07:49:48 2008 UTC

1990 if (PL_op->op_ppaddr != PL_ppaddr [OP_ENTERSUB] 1990 if (PL_op->op_ppaddr != PL_ppaddr [OP_ENTERSUB]
1991 && PL_op->op_ppaddr != pp_slf) 1991 && PL_op->op_ppaddr != pp_slf)
1992 croak ("FATAL: Coro SLF calls can only be made normally, not via goto or any other means, caught"); 1992 croak ("FATAL: Coro SLF calls can only be made normally, not via goto or any other means, caught");
1993 1993
1994 if (items > 3) 1994 if (items > 3)
1995 croak ("Coro only supports up to three arguments to SLF functions currently, caught"); 1995 croak ("Coro only supports up to three arguments to SLF functions currently (not %d), caught", items);
1996 1996
1997 CvFLAGS (cv) |= CVf_SLF; 1997 CvFLAGS (cv) |= CVf_SLF;
1998 CvXSUBANY (cv).any_ptr = (void *)init_cb; 1998 CvXSUBANY (cv).any_ptr = (void *)init_cb;
1999 slf_cv = cv; 1999 slf_cv = cv;
2000 2000
2013 PL_op->op_ppaddr = pp_slf; 2013 PL_op->op_ppaddr = pp_slf;
2014 2014
2015 PL_op = (OP *)&slf_restore; 2015 PL_op = (OP *)&slf_restore;
2016} 2016}
2017 2017
2018/*****************************************************************************/
2019
2020static int
2021slf_check_semaphore_down (pTHX_ struct CoroSLF *frame)
2022{
2023 AV *av = (AV *)frame->data;
2024 SV *count_sv = AvARRAY (av)[0];
2025
2026 if (SvIVX (count_sv) > 0)
2027 {
2028 SvIVX (count_sv) = SvIVX (count_sv) - 1;
2029 return 0;
2030 }
2031 else
2032 {
2033 int i;
2034 /* if we were woken up but can't down, we look through the whole */
2035 /* waiters list and only add us if we aren't in there already */
2036 /* this avoids some degenerate memory usage cases */
2037
2038 for (i = 1; i <= AvFILLp (av); ++i)
2039 if (AvARRAY (av)[i] == SvRV (coro_current))
2040 return 1;
2041
2042 av_push (av, SvREFCNT_inc (SvRV (coro_current)));
2043 return 1;
2044 }
2045}
2046
2047static void
2048slf_init_semaphore_down (pTHX_ struct CoroSLF *frame, SV **arg, int items)
2049{
2050 AV *av = (AV *)SvRV (arg [0]);
2051
2052 if (SvIVX (AvARRAY (av)[0]) > 0)
2053 {
2054 frame->data = (void *)av;
2055 frame->prepare = prepare_nop;
2056 }
2057 else
2058 {
2059 av_push (av, SvREFCNT_inc (SvRV (coro_current)));
2060
2061 frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av));
2062 frame->prepare = prepare_schedule;
2063 }
2064
2065 frame->check = slf_check_semaphore_down;
2066
2067}
2068
2018MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_ 2069MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_
2019 2070
2020PROTOTYPES: DISABLE 2071PROTOTYPES: DISABLE
2021 2072
2022BOOT: 2073BOOT:
2111 CODE: 2162 CODE:
2112 api_execute_slf (aTHX_ cv, slf_init_set_stacklevel, &ST (0), items); 2163 api_execute_slf (aTHX_ cv, slf_init_set_stacklevel, &ST (0), items);
2113 2164
2114void 2165void
2115transfer (...) 2166transfer (...)
2167 PROTOTYPE: $$
2116 CODE: 2168 CODE:
2117 api_execute_slf (aTHX_ cv, slf_init_transfer, &ST (0), items); 2169 api_execute_slf (aTHX_ cv, slf_init_transfer, &ST (0), items);
2118 2170
2119bool 2171bool
2120_destroy (SV *coro_sv) 2172_destroy (SV *coro_sv)
2129 CODE: 2181 CODE:
2130 _exit (code); 2182 _exit (code);
2131 2183
2132int 2184int
2133cctx_stacksize (int new_stacksize = 0) 2185cctx_stacksize (int new_stacksize = 0)
2186 PROTOTYPE: ;$
2134 CODE: 2187 CODE:
2135 RETVAL = cctx_stacksize; 2188 RETVAL = cctx_stacksize;
2136 if (new_stacksize) 2189 if (new_stacksize)
2137 { 2190 {
2138 cctx_stacksize = new_stacksize; 2191 cctx_stacksize = new_stacksize;
2141 OUTPUT: 2194 OUTPUT:
2142 RETVAL 2195 RETVAL
2143 2196
2144int 2197int
2145cctx_max_idle (int max_idle = 0) 2198cctx_max_idle (int max_idle = 0)
2199 PROTOTYPE: ;$
2146 CODE: 2200 CODE:
2147 RETVAL = cctx_max_idle; 2201 RETVAL = cctx_max_idle;
2148 if (max_idle > 1) 2202 if (max_idle > 1)
2149 cctx_max_idle = max_idle; 2203 cctx_max_idle = max_idle;
2150 OUTPUT: 2204 OUTPUT:
2151 RETVAL 2205 RETVAL
2152 2206
2153int 2207int
2154cctx_count () 2208cctx_count ()
2209 PROTOTYPE:
2155 CODE: 2210 CODE:
2156 RETVAL = cctx_count; 2211 RETVAL = cctx_count;
2157 OUTPUT: 2212 OUTPUT:
2158 RETVAL 2213 RETVAL
2159 2214
2160int 2215int
2161cctx_idle () 2216cctx_idle ()
2217 PROTOTYPE:
2162 CODE: 2218 CODE:
2163 RETVAL = cctx_idle; 2219 RETVAL = cctx_idle;
2164 OUTPUT: 2220 OUTPUT:
2165 RETVAL 2221 RETVAL
2166 2222
2167void 2223void
2168list () 2224list ()
2225 PROTOTYPE:
2169 PPCODE: 2226 PPCODE:
2170{ 2227{
2171 struct coro *coro; 2228 struct coro *coro;
2172 for (coro = coro_first; coro; coro = coro->next) 2229 for (coro = coro_first; coro; coro = coro->next)
2173 if (coro->hv) 2230 if (coro->hv)
2240 SvREFCNT_dec (self->throw); 2297 SvREFCNT_dec (self->throw);
2241 self->throw = SvOK (throw) ? newSVsv (throw) : 0; 2298 self->throw = SvOK (throw) ? newSVsv (throw) : 0;
2242 2299
2243void 2300void
2244api_trace (SV *coro, int flags = CC_TRACE | CC_TRACE_SUB) 2301api_trace (SV *coro, int flags = CC_TRACE | CC_TRACE_SUB)
2302 PROTOTYPE: $;$
2245 C_ARGS: aTHX_ coro, flags 2303 C_ARGS: aTHX_ coro, flags
2246 2304
2247SV * 2305SV *
2248has_cctx (Coro::State coro) 2306has_cctx (Coro::State coro)
2249 PROTOTYPE: $ 2307 PROTOTYPE: $
2274 OUTPUT: 2332 OUTPUT:
2275 RETVAL 2333 RETVAL
2276 2334
2277void 2335void
2278force_cctx () 2336force_cctx ()
2337 PROTOTYPE:
2279 CODE: 2338 CODE:
2280 struct coro *coro = SvSTATE (coro_current); 2339 struct coro *coro = SvSTATE (coro_current);
2281 coro->cctx->idle_sp = 0; 2340 coro->cctx->idle_sp = 0;
2282 2341
2283void 2342void
2339} 2398}
2340 2399
2341void 2400void
2342schedule (...) 2401schedule (...)
2343 CODE: 2402 CODE:
2344 api_execute_slf (aTHX_ cv, slf_init_schedule, &ST (0), items); 2403 api_execute_slf (aTHX_ cv, slf_init_schedule, &ST (0), 0);
2345 2404
2346void 2405void
2347cede (...) 2406cede (...)
2348 CODE: 2407 CODE:
2349 api_execute_slf (aTHX_ cv, slf_init_cede, &ST (0), items); 2408 api_execute_slf (aTHX_ cv, slf_init_cede, &ST (0), 0);
2350 2409
2351void 2410void
2352cede_notself (...) 2411cede_notself (...)
2353 CODE: 2412 CODE:
2354 api_execute_slf (aTHX_ cv, slf_init_cede_notself, &ST (0), items); 2413 api_execute_slf (aTHX_ cv, slf_init_cede_notself, &ST (0), 0);
2355 2414
2356void 2415void
2357_set_current (SV *current) 2416_set_current (SV *current)
2358 PROTOTYPE: $ 2417 PROTOTYPE: $
2359 CODE: 2418 CODE:
2369 coro_readyhook = SvOK (hook) ? newSVsv (hook) : 0; 2428 coro_readyhook = SvOK (hook) ? newSVsv (hook) : 0;
2370 UNLOCK; 2429 UNLOCK;
2371 2430
2372int 2431int
2373prio (Coro::State coro, int newprio = 0) 2432prio (Coro::State coro, int newprio = 0)
2433 PROTOTYPE: $;$
2374 ALIAS: 2434 ALIAS:
2375 nice = 1 2435 nice = 1
2376 CODE: 2436 CODE:
2377{ 2437{
2378 RETVAL = coro->prio; 2438 RETVAL = coro->prio;
2442 { 2502 {
2443 av_fill (defav, len - 1); 2503 av_fill (defav, len - 1);
2444 for (i = 0; i < len; ++i) 2504 for (i = 0; i < len; ++i)
2445 av_store (defav, i, SvREFCNT_inc_NN (AvARRAY (invoke_av)[i + 1])); 2505 av_store (defav, i, SvREFCNT_inc_NN (AvARRAY (invoke_av)[i + 1]));
2446 } 2506 }
2447
2448 SvREFCNT_dec (invoke);
2449} 2507}
2450 2508
2451void 2509void
2452_pool_2 (SV *cb) 2510_pool_2 (SV *cb)
2453 CODE: 2511 CODE:
2531 2589
2532MODULE = Coro::State PACKAGE = Coro::AIO 2590MODULE = Coro::State PACKAGE = Coro::AIO
2533 2591
2534void 2592void
2535_get_state (SV *self) 2593_get_state (SV *self)
2594 PROTOTYPE: $
2536 PPCODE: 2595 PPCODE:
2537{ 2596{
2538 AV *defav = GvAV (PL_defgv); 2597 AV *defav = GvAV (PL_defgv);
2539 AV *av = newAV (); 2598 AV *av = newAV ();
2540 int i; 2599 int i;
2585BOOT: 2644BOOT:
2586 sv_activity = coro_get_sv (aTHX_ "Coro::AnyEvent::ACTIVITY", TRUE); 2645 sv_activity = coro_get_sv (aTHX_ "Coro::AnyEvent::ACTIVITY", TRUE);
2587 2646
2588SV * 2647SV *
2589_schedule (...) 2648_schedule (...)
2590 PROTOTYPE: @
2591 CODE: 2649 CODE:
2592{ 2650{
2593 static int incede; 2651 static int incede;
2594 2652
2595 api_cede_notself (aTHX); 2653 api_cede_notself (aTHX);
2614MODULE = Coro::State PACKAGE = PerlIO::cede 2672MODULE = Coro::State PACKAGE = PerlIO::cede
2615 2673
2616BOOT: 2674BOOT:
2617 PerlIO_define_layer (aTHX_ &PerlIO_cede); 2675 PerlIO_define_layer (aTHX_ &PerlIO_cede);
2618 2676
2677MODULE = Coro::State PACKAGE = Coro::Semaphore
2678
2679SV *
2680new (SV *klass, SV *count_ = 0)
2681 CODE:
2682{
2683 /* a semaphore contains a counter IV in $sem->[0] and any waiters after that */
2684 AV *av = newAV ();
2685 av_push (av, newSViv (count_ && SvOK (count_) ? SvIV (count_) : 1));
2686 RETVAL = sv_bless (newRV_noinc ((SV *)av), GvSTASH (CvGV (cv)));
2687}
2688 OUTPUT:
2689 RETVAL
2690
2691SV *
2692count (SV *self)
2693 CODE:
2694 RETVAL = newSVsv (AvARRAY ((AV *)SvRV (self))[0]);
2695 OUTPUT:
2696 RETVAL
2697
2698void
2699up (SV *self, int adjust = 1)
2700 ALIAS:
2701 adjust = 1
2702 CODE:
2703{
2704 AV *av = (AV *)SvRV (self);
2705 SV *count_sv = AvARRAY (av)[0];
2706 IV count = SvIVX (count_sv);
2707
2708 count += ix ? adjust : 1;
2709 SvIVX (count_sv) = count;
2710
2711 /* now wake up as many waiters as possible */
2712 while (count > 0 && AvFILLp (av) >= count)
2713 {
2714 SV *cb;
2715
2716 /* swap first two elements so we can shift a waiter */
2717 AvARRAY (av)[0] = AvARRAY (av)[1];
2718 AvARRAY (av)[1] = count_sv;
2719 cb = av_shift (av);
2720
2721 if (SvOBJECT (cb))
2722 api_ready (cb);
2723 else
2724 croak ("callbacks not yet supported");
2725
2726 SvREFCNT_dec (cb);
2727 }
2728}
2729
2730void
2731down (SV *self)
2732 CODE:
2733 api_execute_slf (aTHX_ cv, slf_init_semaphore_down, &ST (0), 1);
2734
2735void
2736try (SV *self)
2737 PPCODE:
2738{
2739 AV *av = (AV *)SvRV (self);
2740 SV *count_sv = AvARRAY (av)[0];
2741 IV count = SvIVX (count_sv);
2742
2743 if (count > 0)
2744 {
2745 --count;
2746 SvIVX (count_sv) = count;
2747 XSRETURN_YES;
2748 }
2749 else
2750 XSRETURN_NO;
2751}
2752
2753void
2754waiters (SV *self)
2755 CODE:
2756{
2757 AV *av = (AV *)SvRV (self);
2758
2759 if (GIMME_V == G_SCALAR)
2760 XPUSHs (sv_2mortal (newSVsv (AvARRAY (av)[0])));
2761 else
2762 {
2763 int i;
2764 EXTEND (SP, AvFILLp (av) + 1 - 1);
2765 for (i = 1; i <= AvFILLp (av); ++i)
2766 PUSHs (newSVsv (AvARRAY (av)[i]));
2767 }
2768}
2769

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines