Coro-LocalScalar-XS
view release on metacpan or search on metacpan
Makefile.PL view on Meta::CPAN
use 5.008; #Unicode
use ExtUtils::MakeMaker;
eval "use Coro::MakeMaker qw(coro_args);";
if($@){ die 'Install Coro first! '};
WriteMakefile(coro_args(
'NAME' => 'Coro::LocalScalar::XS',
'VERSION' => '0.2',
'OPTIMIZE' => ' -O2'));
# Remove the Makefile dependency. Causes problems on a few systems.
sub MY::makefile { '' }
require DynaLoader;
use Coro;
use Exporter 'import';
our @EXPORT = qw/localize/;
$Coro::LocalScalar::XS = '0.2';
DynaLoader::bootstrap Coro::LocalScalar::XS $Coro::LocalScalar::XS;
=head1 NAME
Coro::LocalScalar::XS - Different scalar values in coroutines
=head1 ABOUT
This is optimized XS version of L<Coro::LocalScalar>. It's almost two times faster and has simplier api - only one function.
This module destroys all local data(and DESTROYs are called) when coroutine get destroyed. This is useful for example if you want to have global variable $request with different object in each coro.
Coro::LocalScalar::XS keeps reference to localized variable, so localize only variables, that will persist all execution time. Localizing hundreds of variables is also bad idea, because each variable adds little overhead when each coro is destroyed
=head1 SYNOPSIS
use Coro;
use Coro::EV;
my $scalar;
use Coro::LocalScalar::XS;
localize($scalar); # $scalar is now different in all coros. Current value of $scalar is deleted.
# $hash{element} = undef; # hash element MUST exist if you want to localize it correctly
# localize($hash{element});
# localizing arrays or hashes unsupported, use refs
# or
# use Coro::LocalScalar::XS qw//; # don't export localize
# Coro::LocalScalar::XS->localize($scalar);
async {
Coro::LocalScalar::XS 18282/s 83% -- -12%
Coro::Localize 20661/s 107% 13% --
L<Coro::Localize> is little bit faster, but Coro::LocalScalar::XS allows localizing hash elements
=cut
sub _set_ondestroy_cb {
my $coro = $Coro::current;
$coro->on_destroy(sub {
# when i use magick to store local copy of var for each coroutine the current value is stored in localized scalar itself
# sv_setsv(sv, &PL_sv_undef ); from XS has no effect and value is still stored in scalar
# so if value in scalar is object, then when coroutine gets destroyed Coro::LocalScalar::XS destroys it's internal storage,
# but one reference persists in scalar itself and object destructor will not be called till scalar will be reassigned
Coro::LocalScalar::XS::cleanup($coro); # clean internal storage and disable magick
$$_ = undef for @Coro::LocalScalar::XS::localized; # reassign all localized scalar to call destructors
Coro::LocalScalar::XS::reenable_magick(); # enable magick
$coro = undef ;
});
undef;
}
our @localized;
sub localize($) {
shift if $_[0] eq __PACKAGE__;
_get_data_hash()
CODE:
RETVAL = (HV*) SvREFCNT_inc((SV*)data_hash);
OUTPUT:
RETVAL
void
cleanup(coro)
SV* coro
CODE:
hv_delete(data_hash, (char *) SvRV(coro), sizeof(HV*), G_DISCARD);
disable_magick = 1;
void
reenable_magick()
CODE:
disable_magick = 0;
t/benchmark.pl view on Meta::CPAN
};
cede;
cede;
cede;
},
'Coro::Localize' => sub {
async {
corolocal $cscalar = "thread 1";
cede;
die unless $cscalar eq "thread 1";
$cscalar = "thread 1 rewrite";
cede;
die unless $cscalar eq "thread 1 rewrite";
# warn 1;
};
async {
corolocal $cscalar = "thread 2";
cede;
die unless $cscalar eq "thread 2";
$cscalar = "thread 2 rewrite";
cede;
die unless $cscalar eq "thread 2 rewrite";
};
cede;
cede;
cede;
t/example.pl view on Meta::CPAN
use Coro;
use Coro::EV;
my $scalar;
use Coro::LocalScalar::XS;
localize($scalar); # $scalar is now different in all coros. Current value of $scalar is deleted.
# $hash{element} = undef; # hash element MUST exist if you want to localize it correctly
# localize($hash{element});
# or
# use Coro::LocalScalar::XS qw//; # don't export localize
# Coro::LocalScalar::XS->localize($scalar);
async {
$scalar = "thread 1";
( run in 0.616 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )