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 { '' }

XS.pm  view on Meta::CPAN

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 {

XS.pm  view on Meta::CPAN

	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__;

XS.xs  view on Meta::CPAN

_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 )