File Coverage

IPC/Shm.pm
Criterion Covered Total %
statement 76 80 95.0
branch 30 40 75.0
condition n/a
subroutine 17 17 100.0
pod 0 3 0.0
total 123 140 87.8


line stmt bran cond sub pod time code
1             package IPC::Shm;
2 6     6   182986 use warnings;
  6         12  
  6         273  
3 6     6   39 use strict;
  6         10  
  6         211  
4 6     6   30 use Carp;
  6         16  
  6         801  
5             #
6             # Copyright (c) 2014 by Kevin Cody-Little
7             #
8             # This code may be modified or redistributed under the terms
9             # of either the Artistic or GNU General Public licenses, at
10             # the modifier or redistributor's discretion.
11             #
12              
13             =head1 NAME
14              
15             IPC::Shm - Easily store variables in SysV shared memory.
16              
17             =head1 SYNOPSIS
18              
19             use IPC::Shm;
20             our %variable : shm;
21              
22             Then, just use it like any other variable.
23              
24             =head1 EXPLANATION
25              
26             The "shm" variable attribute confers two properties to a package variable:
27              
28             =over
29              
30             =item 1. The variable will persist beyond the program's end.
31              
32             =item 2. All simultaneous processes will see the same value.
33              
34             =back
35              
36             Scalars, hashes, and arrays are supported. Filehandles and code are not.
37              
38             Storing references is legal; however, the target of the reference will itself
39             be moved into its own anonymous shared memory segment with contents preserved.
40             That is to say, the original variable the reference points at gets tied, and
41             its contents restored. Thus, any other Perlish reference copying will behave
42             as expected.
43              
44             Blessed references might work but are entirely untested.
45              
46             =head1 LEXICALS
47              
48             use IPC::Shm;
49             my $lexical1 : shm;
50             my $lexical2 : shm = 'foo';
51              
52             Lexical variables are supported, and have slightly different semantics. The
53             properties conferred by the "shm" attribute are:
54              
55             =over
56              
57             =item 1. The variable will only persist beyond the program's end if another
58             shared variable contains a reference to it.
59              
60             =item 2. The parent and all children will see the same value. Unrelated programs
61             only have access if a reference is stored via some shared package variable.
62              
63             =item 3. They will automatically disappear from the system when all copies have
64             gone out of scope and no reference exists in another shared variable.
65              
66             =back
67              
68             =head1 LOCKING
69              
70             If you need the state of the variable to remain unchanged between two
71             or more operations, the calling program should assert a lock thus:
72              
73             my $obj = tied %variable;
74             my $locked = $obj->writelock; # or readlock, if no changes will be made
75              
76             $variable{foo} = "bar";
77             $variable{bar} = $variable{foo};
78              
79             $obj->unlock if $locked; # don't forget
80              
81             If a lock is already held by another process, newer locks will block and
82             wait. However, if the same process is asking for the same lock, it will
83             return zero. This allows pseudo nested locking.
84              
85             To summarize the locking behavior, reads are prohibited while a
86             writelock is in effect (and only one writelock may be held), and
87             writes are prohibited while one or more readlocks are in effect.
88              
89             If the process exits, any held locks are released, assuming the
90             exit was sufficiently clean to allow destructors to run. Something
91             more severe, such as a segmentation fault, would leave stale locks.
92              
93             =head1 CACHING
94              
95             To avoid excessive serialization and deserialization, the underlying
96             IPC::Shm::Simple class provides a serial number that automatically
97             increments during writes. Perl uses this to indicate when a change
98             has been made by another process, and otherwise the in-process
99             cached copy is trusted.
100              
101             =head1 ATOMICITY
102              
103             Perl will read and write the entire variable at once, whether it be a scalar,
104             array, or hash. At the lowest level, a C implementation just sees the
105             serialized string. Updates can be considered atomic as reads are locked
106             out during writes, and vice versa, using a SysV semaphore array.
107              
108             =head1 PERMISSIONS
109              
110             SysV shared memory segments have only a user ownership. The group bits
111             of its UNIX permissions refer to the owner's primary group.
112              
113             Currently, all users see the same shared memory namespace. This may
114             change in future versions.
115              
116             See below for how to influence the permission bits.
117              
118             =head1 CLEANING UP
119              
120             If you wish to remove all IPC::Shm segments from the system, do this:
121              
122             use IPC::Shm;
123             IPC::Shm->cleanup;
124              
125             Accessing shared variables is not valid after calling this, so you
126             should probably only call it from an END block.
127              
128             =head1 IMPLEMENTATION DETAILS
129              
130             One SysV shared memory segment and one SysV semaphore array for locking
131             are created for each Perl variable, named or anonymous.
132              
133             Only one segment, containing %IPC::Shm::NAMEVARS, uses an IPCKEY. It
134             is currently defaulted to 0xdeadbeef, and will likely change in the
135             future. One possible path would be to relate the IPCKEY to the
136             effective userid.
137              
138             By default, segments are created with 4096 bytes and 0660 permissions.
139             To change that, you'd need to change the default before the variables
140             are created:
141              
142             sub BEGIN {
143             IPC::Shm::Tied->Size( 8192 );
144             IPC::Shm::Tied->Mode( 0600 );
145             }
146              
147             Storable freeze() and thaw() are used for serialization and deserialization,
148             respectively.
149              
150             Variables are mapped using a hash table. When the next process starts,
151             it attaches to that first hash table using a four byte IPCKEY. All
152             other variables are mentioned directly or indirectly in that table,
153             allowing transparent reconnection.
154              
155             =head1 CURRENT STATUS
156              
157             This is alpha code. There are no doubt many bugs.
158              
159             In particular, the multiple simultaneous process use case has not been tested.
160              
161             Also, the garbage collection is a bit tenative, and removing named segments
162             causes them to be cleared immediately rather than during global destruction.
163              
164             =cut
165              
166             ###############################################################################
167             # library dependencies
168              
169 6     6   8265 use Attribute::Handlers;
  6         64018  
  6         69  
170              
171             our $VERSION = '0.35';
172              
173              
174             ###############################################################################
175             # argument normalizers
176              
177             sub _attrtie_normalize_data {
178 27     27   38 my ( $data ) = @_;
179              
180 27 50       72 if ( not defined $data ) {
    0          
181 27         48 $data = [];
182             }
183              
184             elsif ( ref( $data ) ne 'ARRAY' ) {
185 0         0 $data = [ $data ];
186             }
187              
188 27         51 return $data;
189             }
190              
191             sub _attrtie_normalize_symbol {
192 27     27   44 my ( $sym, $type ) = @_;
193              
194 27 100       76 return $sym if $sym eq 'LEXICAL';
195              
196 25         46 $sym = *$sym;
197              
198 25 50       75 my $tmp = $type eq 'HASH' ? '%'
    100          
    100          
199             : $type eq 'ARRAY' ? '@'
200             : $type eq 'SCALAR' ? '$'
201             : '*';
202              
203 25         209 $sym =~ s/^\*/$tmp/;
204              
205 25         74 return $sym;
206             }
207              
208              
209             ###############################################################################
210             # sanity checks
211              
212             sub _attrtie_check_ref_sanity {
213 27     27   36 my ( $ref ) = @_;
214              
215 27 50       87 my $rv = ref( $ref )
216             or confess "BUG:\$_[2] is not a reference";
217              
218 27 50       65 if ( $rv eq 'CODE' ) {
219 0         0 confess "Subroutines cannot be placed in shared memory";
220             }
221              
222 27 50       74 if ( $rv eq 'HANDLE' ) {
223 0         0 confess "Handles cannot be placed in shared memory";
224             }
225              
226 27 100       87 return $rv if $rv eq 'HASH';
227 8 100       29 return $rv if $rv eq 'ARRAY';
228 7 50       27 return $rv if $rv eq 'SCALAR';
229              
230 0         0 confess "Unknown reference type '$rv'";
231             }
232              
233              
234             ###############################################################################
235             # shared memory attribute handler
236              
237             sub UNIVERSAL::shm : ATTR(ANY) {
238 27     27 0 63 my ( $pkg, $sym, $ref, $attr, $data, $phase ) = @_;
239 27         33 my ( $type, $obj );
240              
241 27         75 $data = _attrtie_normalize_data( $data );
242 27         61 $type = _attrtie_check_ref_sanity( $ref );
243 27         74 $sym = _attrtie_normalize_symbol( $sym, $type );
244              
245 27 100       151 my $segment = $sym eq 'LEXICAL'
    50          
246             ? IPC::Shm::Segment->anonymous
247             : IPC::Shm::Segment->named( $sym )
248             or confess "Unable to find shm store";
249              
250 27 100       98 if ( $type eq 'HASH' ) {
    100          
    50          
251 19         90 $obj = tie %$ref, 'IPC::Shm::Tied', $segment, @$data;
252             }
253              
254             elsif ( $type eq 'ARRAY' ) {
255 1         5 $obj = tie @$ref, 'IPC::Shm::Tied', $segment, @$data;
256             }
257              
258             elsif ( $type eq 'SCALAR' ) {
259 7         43 $obj = tie $$ref, 'IPC::Shm::Tied', $segment, @$data;
260             }
261              
262 27         139 $obj->tiedref( $ref );
263              
264 27 100       130 if ( $sym eq '%IPC::Shm::NAMEVARS' ) {
265 6 100       46 unless ( $IPC::Shm::NAMEVARS{$sym} ) {
266 2         15 $IPC::Shm::NAMEVARS{$sym} = $segment->shmid;
267             }
268             }
269              
270 6     6   4873 }
  6         15  
  6         44  
271              
272             ###############################################################################
273             # alias to avoid warnings during make test
274              
275             sub UNIVERSAL::Shm : ATTR(ANY) {
276 27     27 0 18155 UNIVERSAL::shm(@_);
277 6     6   2092 }
  6         12  
  6         28  
278              
279              
280             ###############################################################################
281             # late library dependencies - after the above compiles
282              
283 6     6   8022 use IPC::Shm::Segment;
  6         31  
  6         95  
284 6     6   7348 use IPC::Shm::Tied;
  6         35  
  6         111  
285              
286              
287             ###############################################################################
288             # shared memory variables used by this package
289              
290 6     6   370 our %NAMEVARS : Shm;
  6         12  
  6         66  
291 6     6   1533 our %ANONVARS : Shm;
  6         12  
  6         28  
292 6     6   925 our %ANONTYPE : Shm;
  6         12  
  6         25  
293              
294              
295             ###############################################################################
296             # global cleanup routine
297              
298             sub cleanup {
299              
300 2     2 0 567 foreach my $vanon ( keys %ANONVARS ) {
301 2         61 my $shmid = $ANONVARS{$vanon};
302 2         20 my $share = IPC::Shm::Segment->shmat( $shmid );
303 2         73 $share->remove;
304             }
305              
306 2         95 foreach my $vname ( keys %NAMEVARS ) {
307 7 100       112 next if $vname eq '%IPC::Shm::NAMEVARS';
308 5         54 my $shmid = $NAMEVARS{$vname};
309 5         30 my $share = IPC::Shm::Segment->shmat( $shmid );
310 5         147 $share->remove;
311             }
312              
313 2         18 my $obj = tied %NAMEVARS;
314 2         15 $obj->remove;
315              
316             }
317              
318              
319             ###############################################################################
320             ###############################################################################
321              
322             =head1 AUTHOR
323              
324             Kevin Cody-Little
325              
326             =cut
327              
328             1;