Apache2-SSI
view release on metacpan or search on metacpan
lib/Apache2/SSI/SharedMem.pm view on Meta::CPAN
}
my $create = 0;
if( $opts->{mode} eq 'w' || $opts->{key} =~ s/^>// )
{
$create++;
}
elsif( $opts->{mode} eq 'r' || $opts->{key} =~ s/^<// )
{
$create = 0;
}
else
{
$create = $self->create;
}
my $flags = $self->flags( create => $create );
my $id = shmget( $serial, $opts->{size}, $flags );
if( defined( $id ) )
{
# Got shared memory
}
else
{
my $newflags = ( $flags & &IPC::SysV::IPC_CREAT ) ? $flags : ( $flags | &IPC::SysV::IPC_CREAT );
my $limit = ( $serial + 10 );
# IPC::SysV::ftok has likely made the serial unique, but as stated in the manual page, there is no guarantee
while( $serial <= $limit )
{
$id = shmget( $serial, $opts->{size}, $newflags | &IPC::SysV::IPC_CREAT );
$serial++;
last if( defined( $id ) );
}
}
if( !defined( $id ) )
{
return( $self->error( "Unable to create shared memory id with key \"$serial\" and flags \"$flags\": $!" ) );
}
$self->serial( $serial );
# The value 3 can be anything above 0 and below the limit set by SEMMSL. On Linux system, this is usually 32,000. Seem semget(2) man page
my $semid = semget( $serial, 3, $flags );
if( !defined( $semid ) )
{
my $newflags = ( $flags | &IPC::SysV::IPC_CREAT );
$semid = semget( $serial, 3, $newflags );
return( $self->error( "Unable to get a semaphore for shared memory key \"", ( $opts->{key} || $self->key ), "\" wth id \"$id\": $!" ) ) if( !defined( $semid ) );
}
my $new = $self->new(
key => $opts->{key} || $self->key,
debug => $self->debug,
mode => $self->mode,
destroy => $self->destroy,
) || return;
$new->id( $id );
$new->semid( $semid );
if( !defined( $new->op( @{$SEMOP_ARGS->{LOCK_SH}} ) ) )
{
return( $self->error( "Unable to set lock on sempahore: $!" ) );
}
my $there = $new->stat( SEM_MARKER );
$new->size( $opts->{size} );
$new->flags( $flags );
if( $there == SHM_EXISTS )
{
}
else
{
# We initialise the semaphore with value of 1
$new->stat( SEM_MARKER, SHM_EXISTS ) ||
return( $self->error( "Unable to set semaphore during object creation: $!" ) );
$SHEM_REPO->{ $id } = $new;
}
$new->op( @{$SEMOP_ARGS->{(LOCK_SH | LOCK_UN)}} );
return( $new );
}
sub owner { return( shift->_set_get_scalar( 'owner', @_ ) ); }
sub pid
{
my $self = shift( @_ );
my $sem = shift( @_ );
my $semid = $self->semid ||
return( $self->error( "No semaphore set yet. You must open the shared memory first to remove semaphore." ) );
my $v = semctl( $semid, $sem, &IPC::SysV::GETPID, 0 );
return( $v ? 0 + $v : undef() );
}
sub rand
{
my $self = shift( @_ );
my $size = $self->size || 1024;
my $key = shmget( &IPC::SysV::IPC_PRIVATE, $size, &IPC::SysV::S_IRWXU|&IPC::SysV::S_IRWXG|&IPC::SysV::S_IRWXO ) ||
return( $self->error( "Unable to generate a share memory key: $!" ) );
return( $key );
}
# $self->read( $buffer, $size );
sub read
{
my $self = shift( @_ );
my $id = $self->id;
# Optional length parameter for non-reference data only
my $size = int( $_[1] || $self->size || SHM_BUFSIZ );
return( $self->error( "No shared memory id! Have you opened it first?" ) ) if( !length( $id ) );
my $buffer = '';
my $addr = $self->addr;
if( $addr )
{
memread( $addr, $buffer, 0, $size ) ||
return( $self->error( "Unable to read data from shared memory address \"$addr\" using memread: $!" ) );
}
else
{
shmread( $id, $buffer, 0, $size ) ||
return( $self->error( "Unable to read data from shared memory id \"$id\": $!" ) );
}
# Get rid of nulls end padded
$buffer = unpack( "A*", $buffer );
my $first_char = substr( $buffer, 0, 1 );
my $j = JSON->new->utf8->relaxed->allow_nonref;
my $data;
local $@;
# try-catch
eval
{
# Does the value have any typical json format? " for a string, { for an hash and [ for an array
if( $first_char eq '"' || $first_char eq '{' || $first_char eq '[' )
{
( run in 2.568 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )