Files
zoneminder/scripts/ZoneMinder/lib/ZoneMinder/Memory/Shared.pm
2016-12-26 09:23:16 -06:00

180 lines
4.7 KiB
Perl

# ==========================================================================
#
# ZoneMinder Shared Memory Access Module, $Date: 2007-08-29 19:11:09 +0100 (Wed, 29 Aug 2007) $, $Revision: 2175 $
# Copyright (C) 2001-2008 Philip Coombes
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# ==========================================================================
#
# This module contains the common definitions and functions used by the rest
# of the ZoneMinder scripts
#
package ZoneMinder::Memory::Shared;
use 5.006;
use strict;
use warnings;
require Exporter;
require ZoneMinder::Base;
our @ISA = qw(Exporter ZoneMinder::Base);
eval 'sub IPC_CREAT {0001000}' unless defined &IPC_CREAT;
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
# This allows declaration use ZoneMinder ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = (
'functions' => [ qw(
zmMemKey
zmMemAttach
zmMemDetach
zmMemGet
zmMemPut
zmMemClean
) ],
);
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = @EXPORT_OK;
our $VERSION = $ZoneMinder::Base::VERSION;
# ==========================================================================
#
# Shared Memory Facilities
#
# ==========================================================================
use ZoneMinder::Config qw(:all);
use ZoneMinder::Logger qw(:all);
sub zmMemKey
{
my $monitor = shift;
return( defined($monitor->{ShmKey})?$monitor->{ShmKey}:undef );
}
sub zmMemAttach
{
my $monitor = shift;
my $size = shift;
if ( !defined($monitor->{ShmId}) )
{
my $shm_key = (hex($Config{ZM_SHM_KEY})&0xffff0000)|$monitor->{Id};
my $shm_id = shmget( $shm_key, $size, &IPC_CREAT | 0777 );
if ( !defined($shm_id) )
{
Error( sprintf( "Can't get shared memory id '%x', %d: $!\n"
, $shm_key
, $monitor->{Id}
)
);
return( undef );
}
$monitor->{ShmKey} = $shm_key;
$monitor->{ShmId} = $shm_id;
}
return( !undef );
}
sub zmMemDetach
{
my $monitor = shift;
delete $monitor->{ShmId};
}
sub zmMemGet
{
my $monitor = shift;
my $offset = shift;
my $size = shift;
my $shm_key = $monitor->{ShmKey};
my $shm_id = $monitor->{ShmId};
my $data;
if ( !shmread( $shm_id, $data, $offset, $size ) )
{
Error( sprintf( "Can't read from shared memory '%x/%d': $!"
, $shm_key
, $shm_id
)
);
return( undef );
}
return( $data );
}
sub zmMemPut
{
my $monitor = shift;
my $offset = shift;
my $size = shift;
my $data = shift;
my $shm_key = $monitor->{ShmKey};
my $shm_id = $monitor->{ShmId};
if ( !shmwrite( $shm_id, $data, $offset, $size ) )
{
Error( sprintf( "Can't write to shared memory '%x/%d': $!"
, $shm_key
, $shm_id
)
);
return( undef );
}
return( !undef );
}
sub zmMemClean
{
Debug( "Removing shared memory\n" );
# Find ZoneMinder shared memory
my $command = "ipcs -m | grep '^"
.substr( sprintf( "0x%x", hex($Config{ZM_SHM_KEY}) ), 0, -2 )
."'"
;
Debug( "Checking for shared memory with '$command'\n" );
open( my $CMD, '<', "$command |" )
or Fatal( "Can't execute '$command': $!" );
while( <$CMD> )
{
chomp;
my ( $key, $id ) = split( /\s+/ );
if ( $id =~ /^(\d+)/ )
{
$id = $1;
$command = "ipcrm shm $id";
Debug( "Removing shared memory with '$command'\n" );
qx( $command );
}
}
close( $CMD );
}
1;
__END__