Apache::Mmap - Associates a scalar with a mmap'd file
use Apache::Mmap qw(mmap munmap); $mappedfile = mmap 'example.html'; print $$mappedfile; munmap 'example.html'; open( FILE, "jrandomfile" ) or die "Can't open file: $!"; tie $scalar, 'Apache::Mmap', *FILE, 0, Apache::Mmap::PROT_READ, Apache::Mmap::MAP_SHARED; print "jrandomfile contents:\n$scalar\n"; untie $scalar;
Apache::Mmap provides a facility for using the mmap(2) system call to have the OS map a file into a process' address space.
Apache::Mmap
mmap(2)
Two interfaces are provided:
mmap and munmap methods which provide a persistant caching mechanisim similar to that provided by Apache::DBI for database handles.
mmap
munmap
Apache::DBI
A set of methods which implement the TIESCALAR interface allowing a scalar variable to be tied to a mapped region of memory. Reading or writing to the tied scalar accesses the mapped buffer.
TIESCALAR
The simple interface provides two functions, mmap and munmap, to manipulate a mapped area. The mapped area is accessed using the scalar reference returned by mmap.
The mmap function takes the name of a file to map into memory as its argument. An optional second argument may be given to specify what protections should be set on the mapped region. This argument should be one of "r" (the default), "w", or "rw". If the file is successfully mapped a reference to a scalar will be returned. Remember that you need to prepend an $ to dereference the scalar and get the contents:
$
$mapped = mmap '/tmp/foo', "rw"; print "/tmp/foo:\n", $$mapped, "\n"; $$mapped = "New contents\n";
The Apache::Mmap module keeps track of all of the files mapped using the mmap function. If you call mmap with a file which is alredy mapped a reference to the already mapped scalar will be returned.
Calling munmap with a filename removes the association between memory and existing mmapped file. If munmap is called with a file which is not currently mapped, undef will be returned. If the file is successfully unmapped 1 will be returned. Keep in mind that you should be careful unmapping a file if you have multiple copies of the reference returned by mmap.
To be written. Look at how Apache::Mmap::mmap does it.
A handler method is provided by the Apache::Mmap module suitable for use under mod_perl with Apache. To use the handler, add something similar to the following to your access.conf file:
mod_perl
access.conf
<Location /mmapped.html> SetHandler perl-script PerlHandler Apache::Mmap </Location>
replacing /mmaped.html as apropriate. Your performance may vary. See the benchmarking scripts in the eg directory of the distribution.
eg
Some platforms (Solaris for example) require files to be mapped on memory page boundaries. If you map with an offset, the offset must be on a page boundary (e.g. with 4k pages, if you wanted to map with an offset of 6k into the file, you would need to map starting at an offset of 4k and look 2k in from the beginning of the mapped region (I hope that made sense)).
A future version will provide access to the getpagesize() system call on platforms where it is available (SYSV and 4.4BSD). You may also look into the Sys::Sysconf module which provides access to _SC macros from system header files for use with POSIX::sysconf. Some platforms (again, Solaris) provide an _SC_PAGESIZE constant.
getpagesize()
Sys::Sysconf
_SC
POSIX::sysconf
_SC_PAGESIZE
Keep track of the mode a file was mapped as for caching purposes. Warn if a different mode is specified, or remap as requested?
Implement some sort of locking (flock, SysV semaphores, . . .) on the mapped area.
Add support for the msync(2) and mlock(2) system calls.
Add support for madvise(2) on platforms supporting it.
Add hook to getpagesize(2) for platforms which require mappings at offsets to be on page boundaries.
Add some way of specifying if the file's size should be truncated to the length of the last scalar inserted on unmapping. Likewise figure out a good way to extend the file/mapped region if needed.
Look into using the Storable module for sharing hashes and arrays (like IPC::Shareable module does for shm).
Make sure things work on more architectures/os's than Sparc/Solaris 2.5.1 and i586/Linux 2.0.30.
Mike Fletcher, lemur1@mindspring.com
This module is based on (and incorporates some code from) Malcolm Beattie's Mmap-alpha2 module.
mmap(2), perltie(1), perl(1), Malcolm Beattie's Mmap module.
To install Apache::Mmap, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Apache::Mmap
CPAN shell
perl -MCPAN -e shell install Apache::Mmap
For more information on module installation, please visit the detailed CPAN module installation guide.