Coro
view release on metacpan or search on metacpan
Coro/State.xs view on Meta::CPAN
clone (Coro::State coro)
CODE:
{
#if CORO_CLONE
struct coro *ncoro = coro_clone (aTHX_ coro);
MAGIC *mg;
/* TODO: too much duplication */
ncoro->hv = newHV ();
mg = sv_magicext ((SV *)ncoro->hv, 0, CORO_MAGIC_type_state, &coro_state_vtbl, (char *)ncoro, 0);
mg->mg_flags |= MGf_DUP;
RETVAL = sv_bless (newRV_noinc ((SV *)ncoro->hv), SvSTASH (coro->hv));
#else
croak ("Coro::State->clone has not been configured into this installation of Coro, realised");
#endif
}
OUTPUT:
RETVAL
int
cctx_stacksize (int new_stacksize = 0)
PROTOTYPE: ;$
CODE:
RETVAL = cctx_stacksize;
if (new_stacksize)
{
cctx_stacksize = new_stacksize;
++cctx_gen;
}
OUTPUT:
RETVAL
int
cctx_max_idle (int max_idle = 0)
PROTOTYPE: ;$
CODE:
RETVAL = cctx_max_idle;
if (max_idle > 1)
cctx_max_idle = max_idle;
OUTPUT:
RETVAL
int
cctx_count ()
PROTOTYPE:
CODE:
RETVAL = cctx_count;
OUTPUT:
RETVAL
int
cctx_idle ()
PROTOTYPE:
CODE:
RETVAL = cctx_idle;
OUTPUT:
RETVAL
void
list ()
PROTOTYPE:
PPCODE:
{
struct coro *coro;
for (coro = coro_first; coro; coro = coro->next)
if (coro->hv)
XPUSHs (sv_2mortal (newRV_inc ((SV *)coro->hv)));
}
void
call (Coro::State coro, SV *coderef)
ALIAS:
eval = 1
CODE:
{
if (coro->mainstack && ((coro->flags & CF_RUNNING) || coro->slot))
{
struct coro *current = SvSTATE_current;
struct CoroSLF slf_save;
if (current != coro)
{
PUTBACK;
save_perl (aTHX_ current);
load_perl (aTHX_ coro);
/* the coro is most likely in an active SLF call.
* while not strictly required (the code we execute is
* not allowed to call any SLF functions), it's cleaner
* to reinitialise the slf_frame and restore it later.
* This might one day allow us to actually do SLF calls
* from code executed here.
*/
slf_save = slf_frame;
slf_frame.prepare = 0;
SPAGAIN;
}
PUSHSTACK;
PUSHMARK (SP);
PUTBACK;
if (ix)
eval_sv (coderef, 0);
else
call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
POPSTACK;
SPAGAIN;
if (current != coro)
{
PUTBACK;
slf_frame = slf_save;
save_perl (aTHX_ coro);
load_perl (aTHX_ current);
SPAGAIN;
}
}
}
SV *
Coro/State.xs view on Meta::CPAN
UV
rss (Coro::State coro)
PROTOTYPE: $
ALIAS:
usecount = 1
CODE:
switch (ix)
{
case 0: RETVAL = coro_rss (aTHX_ coro); break;
case 1: RETVAL = coro->usecount; break;
}
OUTPUT:
RETVAL
void
force_cctx ()
PROTOTYPE:
CODE:
cctx_current->idle_sp = 0;
void
swap_defsv (Coro::State self)
PROTOTYPE: $
ALIAS:
swap_defav = 1
CODE:
if (!self->slot)
croak ("cannot swap state with coroutine that has no saved state,");
else
{
SV **src = ix ? (SV **)&GvAV (PL_defgv) : &GvSV (PL_defgv);
SV **dst = ix ? (SV **)&self->slot->defav : (SV **)&self->slot->defsv;
SV *tmp = *src; *src = *dst; *dst = tmp;
}
void
cancel (Coro::State self)
CODE:
coro_state_destroy (aTHX_ self);
SV *
enable_times (int enabled = enable_times)
CODE:
{
RETVAL = boolSV (enable_times);
if (enabled != enable_times)
{
enable_times = enabled;
coro_times_update ();
(enabled ? coro_times_sub : coro_times_add)(SvSTATE (coro_current));
}
}
OUTPUT:
RETVAL
void
times (Coro::State self)
PPCODE:
{
struct coro *current = SvSTATE (coro_current);
if (ecb_expect_false (current == self))
{
coro_times_update ();
coro_times_add (SvSTATE (coro_current));
}
EXTEND (SP, 2);
PUSHs (sv_2mortal (newSVnv (self->t_real [0] + self->t_real [1] * 1e-9)));
PUSHs (sv_2mortal (newSVnv (self->t_cpu [0] + self->t_cpu [1] * 1e-9)));
if (ecb_expect_false (current == self))
coro_times_sub (SvSTATE (coro_current));
}
void
swap_sv (Coro::State coro, SV *sva, SV *svb)
CODE:
{
struct coro *current = SvSTATE_current;
AV *swap_sv;
int i;
sva = SvRV (sva);
svb = SvRV (svb);
if (current == coro)
SWAP_SVS_LEAVE (current);
if (!coro->swap_sv)
coro->swap_sv = newAV ();
swap_sv = coro->swap_sv;
for (i = AvFILLp (swap_sv) - 1; i >= 0; i -= 2)
{
SV *a = AvARRAY (swap_sv)[i ];
SV *b = AvARRAY (swap_sv)[i + 1];
if (a == sva && b == svb)
{
SvREFCNT_dec_NN (a);
SvREFCNT_dec_NN (b);
for (; i <= AvFILLp (swap_sv) - 2; i++)
AvARRAY (swap_sv)[i] = AvARRAY (swap_sv)[i + 2];
AvFILLp (swap_sv) -= 2;
goto removed;
}
}
av_push (swap_sv, SvREFCNT_inc_NN (sva));
av_push (swap_sv, SvREFCNT_inc_NN (svb));
removed:
Coro/State.xs view on Meta::CPAN
int
prio (Coro::State coro, int newprio = 0)
PROTOTYPE: $;$
ALIAS:
nice = 1
CODE:
{
RETVAL = coro->prio;
if (items > 1)
{
if (ix)
newprio = coro->prio - newprio;
if (newprio < CORO_PRIO_MIN) newprio = CORO_PRIO_MIN;
if (newprio > CORO_PRIO_MAX) newprio = CORO_PRIO_MAX;
coro->prio = newprio;
}
}
OUTPUT:
RETVAL
SV *
ready (SV *self)
PROTOTYPE: $
CODE:
RETVAL = boolSV (api_ready (aTHX_ self));
OUTPUT:
RETVAL
int
nready (...)
PROTOTYPE:
CODE:
RETVAL = coro_nready;
OUTPUT:
RETVAL
void
suspend (Coro::State self)
PROTOTYPE: $
CODE:
self->flags |= CF_SUSPENDED;
void
resume (Coro::State self)
PROTOTYPE: $
CODE:
self->flags &= ~CF_SUSPENDED;
void
_pool_handler (...)
CODE:
CORO_EXECUTE_SLF_XS (slf_init_pool_handler);
void
async_pool (SV *cv, ...)
PROTOTYPE: &@
PPCODE:
{
HV *hv = (HV *)av_pop (av_async_pool);
AV *av = newAV ();
SV *cb = ST (0);
int i;
av_extend (av, items - 2);
for (i = 1; i < items; ++i)
av_push (av, SvREFCNT_inc_NN (ST (i)));
if ((SV *)hv == &PL_sv_undef)
{
SV *sv = coro_new (aTHX_ coro_stash, (SV **)&cv_pool_handler, 1, 1);
hv = (HV *)SvREFCNT_inc_NN (SvRV (sv));
SvREFCNT_dec_NN (sv);
}
{
struct coro *coro = SvSTATE_hv (hv);
assert (!coro->invoke_cb);
assert (!coro->invoke_av);
coro->invoke_cb = SvREFCNT_inc (cb);
coro->invoke_av = av;
}
api_ready (aTHX_ (SV *)hv);
if (GIMME_V != G_VOID)
XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv)));
else
SvREFCNT_dec_NN (hv);
}
SV *
rouse_cb ()
PROTOTYPE:
CODE:
RETVAL = coro_new_rouse_cb (aTHX);
OUTPUT:
RETVAL
void
rouse_wait (...)
PROTOTYPE: ;$
PPCODE:
CORO_EXECUTE_SLF_XS (slf_init_rouse_wait);
void
on_enter (SV *block)
ALIAS:
on_leave = 1
PROTOTYPE: &
CODE:
{
struct coro *coro = SvSTATE_current;
AV **avp = ix ? &coro->on_leave : &coro->on_enter;
block = s_get_cv_croak (block);
if (!*avp)
*avp = newAV ();
av_push (*avp, SvREFCNT_inc (block));
if (!ix)
on_enterleave_call (aTHX_ block);
LEAVE; /* pp_entersub unfortunately forces an ENTER/LEAVE around XS calls */
SAVEDESTRUCTOR_X (ix ? coro_pop_on_leave : coro_pop_on_enter, (void *)coro);
ENTER; /* pp_entersub unfortunately forces an ENTER/LEAVE around XS calls */
}
MODULE = Coro::State PACKAGE = PerlIO::cede
BOOT:
PerlIO_define_layer (aTHX_ &PerlIO_cede);
MODULE = Coro::State PACKAGE = Coro::Semaphore
SV *
new (SV *klass, SV *count = 0)
CODE:
{
int semcnt = 1;
if (count)
{
SvGETMAGIC (count);
if (SvOK (count))
semcnt = SvIV (count);
}
RETVAL = sv_bless (
coro_waitarray_new (aTHX_ semcnt),
GvSTASH (CvGV (cv))
);
}
OUTPUT:
RETVAL
# helper for Coro::Channel and others
SV *
_alloc (int count)
CODE:
RETVAL = coro_waitarray_new (aTHX_ count);
OUTPUT:
RETVAL
SV *
count (SV *self)
CODE:
RETVAL = newSVsv (AvARRAY ((AV *)SvRV (self))[0]);
OUTPUT:
RETVAL
void
up (SV *self)
CODE:
coro_semaphore_adjust (aTHX_ (AV *)SvRV (self), 1);
void
adjust (SV *self, int adjust)
CODE:
coro_semaphore_adjust (aTHX_ (AV *)SvRV (self), adjust);
void
down (...)
CODE:
CORO_EXECUTE_SLF_XS (slf_init_semaphore_down);
void
wait (...)
CODE:
CORO_EXECUTE_SLF_XS (slf_init_semaphore_wait);
void
try (SV *self)
PPCODE:
{
AV *av = (AV *)SvRV (self);
SV *count_sv = AvARRAY (av)[0];
IV count = SvIVX (count_sv);
if (count > 0)
{
--count;
SvIVX (count_sv) = count;
XSRETURN_YES;
}
else
XSRETURN_NO;
}
void
waiters (SV *self)
PPCODE:
{
AV *av = (AV *)SvRV (self);
int wcount = AvFILLp (av) + 1 - 1;
if (GIMME_V == G_SCALAR)
XPUSHs (sv_2mortal (newSViv (wcount)));
else
{
int i;
EXTEND (SP, wcount);
for (i = 1; i <= wcount; ++i)
PUSHs (sv_2mortal (newRV_inc (AvARRAY (av)[i])));
}
}
MODULE = Coro::State PACKAGE = Coro::SemaphoreSet
void
_may_delete (SV *sem, int count, unsigned int extra_refs)
PPCODE:
{
AV *av = (AV *)SvRV (sem);
if (SvREFCNT ((SV *)av) == 1 + extra_refs
&& AvFILLp (av) == 0 /* no waiters, just count */
&& SvIV (AvARRAY (av)[0]) == count)
XSRETURN_YES;
XSRETURN_NO;
}
MODULE = Coro::State PACKAGE = Coro::Signal
SV *
new (SV *klass)
CODE:
RETVAL = sv_bless (
coro_waitarray_new (aTHX_ 0),
GvSTASH (CvGV (cv))
);
OUTPUT:
RETVAL
void
wait (...)
CODE:
CORO_EXECUTE_SLF_XS (slf_init_signal_wait);
void
broadcast (SV *self)
CODE:
{
AV *av = (AV *)SvRV (self);
coro_signal_wake (aTHX_ av, AvFILLp (av));
}
void
send (SV *self)
CODE:
{
AV *av = (AV *)SvRV (self);
if (AvFILLp (av))
coro_signal_wake (aTHX_ av, 1);
else
SvIVX (AvARRAY (av)[0]) = 1; /* remember the signal */
}
IV
awaited (SV *self)
CODE:
RETVAL = AvFILLp ((AV *)SvRV (self)) + 1 - 1;
OUTPUT:
RETVAL
MODULE = Coro::State PACKAGE = Coro::AnyEvent
BOOT:
sv_activity = coro_get_sv (aTHX_ "Coro::AnyEvent::ACTIVITY", TRUE);
Coro/State.xs view on Meta::CPAN
{
PUSHMARK (SP);
PUTBACK;
call_pv ("Coro::AnyEvent::_activity", G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
}
--incede;
}
MODULE = Coro::State PACKAGE = Coro::AIO
void
_register (char *target, char *proto, SV *req)
CODE:
{
SV *req_cv = s_get_cv_croak (req);
/* newXSproto doesn't return the CV on 5.8 */
CV *slf_cv = newXS (target, coro_aio_req_xs, __FILE__);
sv_setpv ((SV *)slf_cv, proto);
sv_magicext ((SV *)slf_cv, (SV *)req_cv, CORO_MAGIC_type_aio, 0, 0, 0);
}
MODULE = Coro::State PACKAGE = Coro::Select
void
patch_pp_sselect ()
CODE:
if (!coro_old_pp_sselect)
{
coro_select_select = (SV *)get_cv ("Coro::Select::select", 0);
coro_old_pp_sselect = PL_ppaddr [OP_SSELECT];
PL_ppaddr [OP_SSELECT] = coro_pp_sselect;
}
void
unpatch_pp_sselect ()
CODE:
if (coro_old_pp_sselect)
{
PL_ppaddr [OP_SSELECT] = coro_old_pp_sselect;
coro_old_pp_sselect = 0;
}
MODULE = Coro::State PACKAGE = Coro::Util
void
_exit (int code)
CODE:
_exit (code);
NV
time ()
CODE:
RETVAL = nvtime (aTHX);
OUTPUT:
RETVAL
NV
gettimeofday ()
PPCODE:
{
UV tv [2];
u2time (aTHX_ tv);
EXTEND (SP, 2);
PUSHs (sv_2mortal (newSVuv (tv [0])));
PUSHs (sv_2mortal (newSVuv (tv [1])));
}
( run in 1.261 second using v1.01-cache-2.11-cpan-71847e10f99 )