line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
=head1 NAME |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
Hash::SharedMem - efficient shared mutable hash |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 SYNOPSIS |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
use Hash::SharedMem qw(shash_referential_handle); |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
if(shash_referential_handle) { ... |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
use Hash::SharedMem qw(is_shash check_shash); |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
if(is_shash($arg)) { ... |
14
|
|
|
|
|
|
|
check_shash($arg); |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
use Hash::SharedMem qw(shash_open); |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
$shash = shash_open($filename, "rwc"); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
use Hash::SharedMem |
21
|
|
|
|
|
|
|
qw(shash_is_readable shash_is_writable shash_mode); |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
if(shash_is_readable($shash)) { ... |
24
|
|
|
|
|
|
|
if(shash_is_writable($shash)) { ... |
25
|
|
|
|
|
|
|
$mode = shash_mode($shash); |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
use Hash::SharedMem qw( |
28
|
|
|
|
|
|
|
shash_getd shash_get shash_set shash_gset shash_cset |
29
|
|
|
|
|
|
|
); |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
if(shash_getd($shash, $key)) { ... |
32
|
|
|
|
|
|
|
$value = shash_get($shash, $key); |
33
|
|
|
|
|
|
|
shash_set($shash, $key, $newvalue); |
34
|
|
|
|
|
|
|
$oldvalue = shash_gset($shash, $key, $newvalue); |
35
|
|
|
|
|
|
|
if(shash_cset($shash, $key, $chkvalue, $newvalue)) { ... |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
use Hash::SharedMem qw(shash_snapshot shash_is_snapshot); |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
$snap_shash = shash_snapshot($shash); |
40
|
|
|
|
|
|
|
if(shash_is_snapshot($shash)) { ... |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
use Hash::SharedMem qw(shash_idle shash_tidy); |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
shash_idle($shash); |
45
|
|
|
|
|
|
|
shash_tidy($shash); |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
use Hash::SharedMem qw( |
48
|
|
|
|
|
|
|
shash_tally_get shash_tally_zero shash_tally_gzero |
49
|
|
|
|
|
|
|
); |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
$tally = shash_tally_get($shash); |
52
|
|
|
|
|
|
|
shash_tally_zero($shash); |
53
|
|
|
|
|
|
|
$tally = shash_tally_gzero($shash); |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head1 DESCRIPTION |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
This module provides a facility for efficiently sharing mutable data |
58
|
|
|
|
|
|
|
between processes on one host. Data is organised as a key/value store, |
59
|
|
|
|
|
|
|
resembling a Perl hash. The keys and values are restricted to octet |
60
|
|
|
|
|
|
|
(Latin-1) strings. Structured objects may be stored by serialising them |
61
|
|
|
|
|
|
|
using a mechanism such as L. |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
The data is represented in files that are mapped into each process's |
64
|
|
|
|
|
|
|
memory space, which for interprocess communication amounts to the |
65
|
|
|
|
|
|
|
processes sharing memory. Processes are never blocked waiting for each |
66
|
|
|
|
|
|
|
other. The use of files means that there is some persistence, with the |
67
|
|
|
|
|
|
|
data continuing to exist when there are no processes with it mapped. |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
The data structure is optimised for the case where all the data fits |
70
|
|
|
|
|
|
|
into RAM. This happens either via buffering of a disk-based filesystem, |
71
|
|
|
|
|
|
|
or as the normal operation of a memory-backed filesystem, in either case |
72
|
|
|
|
|
|
|
as long as there isn't much swapping activity. If RAM isn't large enough, |
73
|
|
|
|
|
|
|
such that the data has to reside mainly on disk and parts of it have to |
74
|
|
|
|
|
|
|
be frequently reread from disk, speed will seriously suffer. The data |
75
|
|
|
|
|
|
|
structure exhibits poor locality of reference, and is not designed to |
76
|
|
|
|
|
|
|
play nicely with filesystem block sizes. |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=head2 Consistency and synchronisation |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
A shared hash is held in regular files, grouped in a directory. At all |
81
|
|
|
|
|
|
|
times, the OS-visible state of the files provides a consistent view of the |
82
|
|
|
|
|
|
|
hash's content, from which read and write operations can proceed. It is |
83
|
|
|
|
|
|
|
no problem for a process using the shared hash to crash; other processes, |
84
|
|
|
|
|
|
|
running concurrently or later, will be unimpeded in using the shared hash. |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
It is mainly intended that the shared hash should be held on a |
87
|
|
|
|
|
|
|
memory-backed filesystem, and will therefore only last as long as the |
88
|
|
|
|
|
|
|
machine stays up. However, it can use any filesystem that supports |
89
|
|
|
|
|
|
|
L, including conventional disk filesystems such as ext2. |
90
|
|
|
|
|
|
|
In this case, as long as the OS shuts down cleanly (synching all file |
91
|
|
|
|
|
|
|
writes to the underlying disk), a consistent state of the shared hash |
92
|
|
|
|
|
|
|
will persist between boots, and usage of the shared hash can continue |
93
|
|
|
|
|
|
|
after the OS boots again. Note that only the OS is required to shut |
94
|
|
|
|
|
|
|
down cleanly; it still doesn't matter if user processes crash. |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
Because the OS is likely to reorder file writes when writing them to disk, |
97
|
|
|
|
|
|
|
the instantaneous state of the shared hash's files on disk is generally |
98
|
|
|
|
|
|
|
I guaranteed to be consistent. So if the OS crashes, upon reboot |
99
|
|
|
|
|
|
|
the files are liable to be in an inconsistent state (corrupted). |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
Maintaining consistency across an OS crash is a feature likely to be |
102
|
|
|
|
|
|
|
added to this module in the future. Durability of writes, for which |
103
|
|
|
|
|
|
|
that is a prerequisite, is another likely future addition. |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=head2 File permissions |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
To read normally from a shared hash requires read and search (execute) |
108
|
|
|
|
|
|
|
permission on the shared hash directory and read permission on all the |
109
|
|
|
|
|
|
|
regular files in the directory. To write normally requires read, write, |
110
|
|
|
|
|
|
|
and search permissions on the directory and read and write permissions |
111
|
|
|
|
|
|
|
on all the regular files. For security purposes, some information about |
112
|
|
|
|
|
|
|
shared hash content can be gleaned by anyone who has read or search |
113
|
|
|
|
|
|
|
permission on the directory, and content can be modified by anyone who |
114
|
|
|
|
|
|
|
has search permission on the directory and write permission on either |
115
|
|
|
|
|
|
|
the directory or any of the regular files. |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
The file permission bits on a shared hash are determined by the |
118
|
|
|
|
|
|
|
circumstances in which it was created, specifically by the umask in |
119
|
|
|
|
|
|
|
effect at the point of creation. As shared hash creation is unavoidably |
120
|
|
|
|
|
|
|
non-atomic, competing creation attempts can cause trouble, and the |
121
|
|
|
|
|
|
|
resulting permissions are only guaranteed if all competing attempts at |
122
|
|
|
|
|
|
|
creation use the same umask. After the shared hash is fully created, |
123
|
|
|
|
|
|
|
subsequently opening it with the create flag set doesn't affect |
124
|
|
|
|
|
|
|
permissions. |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
The directory gets permissions C modified by the creation |
127
|
|
|
|
|
|
|
umask, and the regular files in it get permissions C modified |
128
|
|
|
|
|
|
|
by the creation umask. All the regular files that contain any part of |
129
|
|
|
|
|
|
|
the shared hash content will get the same permission bits. This includes |
130
|
|
|
|
|
|
|
files created long after initial creation of the shared hash, which are |
131
|
|
|
|
|
|
|
created as part of shared hash write operations; the umask in effect at |
132
|
|
|
|
|
|
|
the point of those operations is insignificant. |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
File ownership and group assignment are not so controlled. An attempt |
135
|
|
|
|
|
|
|
is made to give all files the same group assignment and ownership, |
136
|
|
|
|
|
|
|
determined by the creation of the shared hash, but the ability to do so |
137
|
|
|
|
|
|
|
is limited by OS semantics. Typically, users other than the superuser |
138
|
|
|
|
|
|
|
cannot affect ownership, and can only assign files to groups of which |
139
|
|
|
|
|
|
|
they are members. Also, as with permission bits, competing creation |
140
|
|
|
|
|
|
|
attempts can make ownerships and group assignments inconsistent, even |
141
|
|
|
|
|
|
|
if they are generally controllable. |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
Where they can't be freely set, each regular file gets whatever ownership |
144
|
|
|
|
|
|
|
and group assignment arise naturally from the circumstances in which it |
145
|
|
|
|
|
|
|
was created. If multiple users write to a single shared hash, it is to be |
146
|
|
|
|
|
|
|
expected that the constituent files will end up having different owners. |
147
|
|
|
|
|
|
|
It is up to the user to ensure that the varying ownerships combined |
148
|
|
|
|
|
|
|
with the consistent permission bits yield compatible permissions for all |
149
|
|
|
|
|
|
|
intended users of the shared hash. Group-based permissions should work |
150
|
|
|
|
|
|
|
provided that all writers are members of the relevant group. |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=head2 Filesystem referential integrity |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
If the system calls L et al are supported by the kernel |
155
|
|
|
|
|
|
|
and the C library, then an open shared hash handle contains an |
156
|
|
|
|
|
|
|
OS-supported first-class reference to the shared hash to which it refers. |
157
|
|
|
|
|
|
|
(Specifically, it has a file descriptor referring to the shared hash |
158
|
|
|
|
|
|
|
directory.) In this situation, the reference remains valid regardless of |
159
|
|
|
|
|
|
|
filename changes. The shared hash can be renamed or moved arbitrarily, |
160
|
|
|
|
|
|
|
within the filesystem, or the process can change its current directory |
161
|
|
|
|
|
|
|
or root directory, and the handle remains valid. |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
If these modern system calls are not available, then an open shared |
164
|
|
|
|
|
|
|
hash handle cannot contain a first-class reference to the shared hash |
165
|
|
|
|
|
|
|
directory. Instead it must repeatedly refer to the directory by name. |
166
|
|
|
|
|
|
|
The name supplied to L is resolved to an absolute pathname, |
167
|
|
|
|
|
|
|
so the handle will continue to work if the process changes its current |
168
|
|
|
|
|
|
|
directory. But any renaming of the shared hash, or the process changing |
169
|
|
|
|
|
|
|
its root directory, will cause the handle to fail at the next operation |
170
|
|
|
|
|
|
|
that requires the use of filenames. (This is unlikely to be the very |
171
|
|
|
|
|
|
|
next operation after the pathname becomes invalid.) An attempt is made to |
172
|
|
|
|
|
|
|
ensure that the stored pathname is still correct each time it is used, but |
173
|
|
|
|
|
|
|
there is unavoidably a race condition, whereby some very unluckily timed |
174
|
|
|
|
|
|
|
renaming could cause an operation to be applied to the wrong directory. |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
The means by which shared hash handles reference their directories is |
177
|
|
|
|
|
|
|
indicated by the constant L. |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
When a shared hash is being opened, if it already exists then the name |
180
|
|
|
|
|
|
|
passed to L is resolved just once to determine to what shared |
181
|
|
|
|
|
|
|
hash it refers. If the modern system calls are supported, this yields |
182
|
|
|
|
|
|
|
perfectly clean name resolution semantics. However, if a shared hash does |
183
|
|
|
|
|
|
|
not already exist, its creation cannot currently be so perfectly clean. |
184
|
|
|
|
|
|
|
The name passed to L must be resolved at least twice, once |
185
|
|
|
|
|
|
|
to create the shared hash directory and once to acquire a reference to it |
186
|
|
|
|
|
|
|
(of whichever type). There is unavoidably a race condition here. |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=head2 File operations |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
Because a shared hash is encapsulated in a directory, rather than being a |
191
|
|
|
|
|
|
|
single non-directory file, the ability to perform file operations on it is |
192
|
|
|
|
|
|
|
limited. Although it can be renamed or moved, under POSIX semantics such |
193
|
|
|
|
|
|
|
a rename can't atomically replace any file other than an empty directory. |
194
|
|
|
|
|
|
|
In particular, it can't atomically replace another shared hash. It also |
195
|
|
|
|
|
|
|
can't be hard-linked to have multiple names. (However, a major use |
196
|
|
|
|
|
|
|
case for L, non-overwriting renaming, can be achieved through |
197
|
|
|
|
|
|
|
L due to the latter's limitations for directories.) Finally, |
198
|
|
|
|
|
|
|
it can't be unlinked. (Linking and unlinking directories are possible for |
199
|
|
|
|
|
|
|
root on some systems, but cause undesirable filesystem irregularities.) |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
A shared hash can be disposed of by applying C to its directory. |
202
|
|
|
|
|
|
|
This is not equivalent to L (C) on a regular file, |
203
|
|
|
|
|
|
|
because it not only removes the object's name but also disrupts its |
204
|
|
|
|
|
|
|
internal structure. If a process has an open handle referring to the |
205
|
|
|
|
|
|
|
shared hash at the time of C, the use of the shared hash through |
206
|
|
|
|
|
|
|
that handle is likely to fail, although probably not immediately. If a |
207
|
|
|
|
|
|
|
process is writing to the shared hash at the time of C, there is a |
208
|
|
|
|
|
|
|
race condition that could prevent the removal from completing. C |
209
|
|
|
|
|
|
|
should therefore only be applied after all processes have finished using |
210
|
|
|
|
|
|
|
the shared hash. |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
A shared hash can be copied by means of C (not mere C), C, |
213
|
|
|
|
|
|
|
or similar means. It is safe to do this while processes have open handles |
214
|
|
|
|
|
|
|
referring to the shared hash, and while processes are reading from it. |
215
|
|
|
|
|
|
|
However, as with most forms of database file, if a process is writing to |
216
|
|
|
|
|
|
|
the shared hash then the file copier is liable to pick up an inconsistent |
217
|
|
|
|
|
|
|
(corrupted) view of the shared hash. Copying should therefore only |
218
|
|
|
|
|
|
|
be attempted at a time when no write operations are being performed. |
219
|
|
|
|
|
|
|
It is acceptable for processes to have the shared hash open in write |
220
|
|
|
|
|
|
|
mode, provided that they do not actually perform any write operation |
221
|
|
|
|
|
|
|
while the copy is being made. |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
A file-level copying operation applied to a shared hash is likely to |
224
|
|
|
|
|
|
|
result in a copy that occupies much more filesystem space than the |
225
|
|
|
|
|
|
|
original. This occurs because most of the time a large part of the |
226
|
|
|
|
|
|
|
main data file is a filesystem hole, not occupying any actual storage. |
227
|
|
|
|
|
|
|
Some copying mechanisms (such as GNU C) can recognise this and avoid |
228
|
|
|
|
|
|
|
allocating unnecessary storage for the copy, but others (such as GNU |
229
|
|
|
|
|
|
|
C) will blindly fill space with a lot of zeroes. If the copy is |
230
|
|
|
|
|
|
|
subsequently used in shared hash write operations, ultimately it will |
231
|
|
|
|
|
|
|
recover from this inefficient block allocation. |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
=head2 Forking |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
If a process is duplicated by L while it holds a shared hash |
236
|
|
|
|
|
|
|
handle, the handle is duplicated with the rest of the process, so |
237
|
|
|
|
|
|
|
both resulting processes have handles referring to the same underlying |
238
|
|
|
|
|
|
|
shared hash. Provided that the duplication did not happen during a shared |
239
|
|
|
|
|
|
|
hash operation, both processes' handles will subsequently work normally, |
240
|
|
|
|
|
|
|
and can be used independently. |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
Things are more difficult if a L happens while a shared hash |
243
|
|
|
|
|
|
|
operation is in progress. This should not normally be possible to |
244
|
|
|
|
|
|
|
achieve from Perl code: arbitrary Perl code should not run during the |
245
|
|
|
|
|
|
|
critical part of an operation. If a shared hash operator is given a |
246
|
|
|
|
|
|
|
tied variable as a parameter, the magic method call for access to that |
247
|
|
|
|
|
|
|
parameter occurs before the critical part, so a L |
248
|
|
|
|
|
|
|
in that method is safe. If a signal is received during a shared hash |
249
|
|
|
|
|
|
|
operation, any signal handler installed in L<%SIG|perlvar/%SIG> will |
250
|
|
|
|
|
|
|
be deferred until the operation is complete, so a L |
251
|
|
|
|
|
|
|
in such a signal handler is also safe. A problematic L should |
252
|
|
|
|
|
|
|
only be achievable by XS code. |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
If a L does happen during the critical part of a shared hash |
255
|
|
|
|
|
|
|
operation, the two resulting handles are liable to interfere if the |
256
|
|
|
|
|
|
|
operation is resumed in both processes. In this case, it is safe for at |
257
|
|
|
|
|
|
|
most one process (which may be either of them) to resume the operation. |
258
|
|
|
|
|
|
|
The other process must neither resume the operation in progress nor make |
259
|
|
|
|
|
|
|
any further use of the handle. It is safe for the non-resuming process |
260
|
|
|
|
|
|
|
to chain a new program with L, to terminate with L<_exit(2)>, |
261
|
|
|
|
|
|
|
or generally to make use of the C library before doing either of those. |
262
|
|
|
|
|
|
|
Attempting to run Perl code would be unwise. |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
On platforms lacking a native L, the Perl function |
265
|
|
|
|
|
|
|
L actually creates a Perl L. In that |
266
|
|
|
|
|
|
|
case the behaviour should be similar to that seen with a real L, |
267
|
|
|
|
|
|
|
as described in the next section. |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
=head2 Threads |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
This module can be used in multiple Perl L simultaneously. |
272
|
|
|
|
|
|
|
The module may be loaded by multiple threads separately, or from |
273
|
|
|
|
|
|
|
Perl 5.8.9 onwards may be loaded by a thread that spawns new threads. |
274
|
|
|
|
|
|
|
(Prior to Perl 5.8.9, limitations of the threading system mean that |
275
|
|
|
|
|
|
|
module data can't be correctly cloned upon thread spawning. Any but |
276
|
|
|
|
|
|
|
the most trivial cases of thread spawning with this module loaded will |
277
|
|
|
|
|
|
|
crash the interpreter. The rest of this section only applies to Perls |
278
|
|
|
|
|
|
|
that fully support cloning.) |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
If a thread is spawned while the parent thread has an open shared hash |
281
|
|
|
|
|
|
|
handle, the handle is duplicated, so that both resulting threads have |
282
|
|
|
|
|
|
|
handles referring to the same underlying shared hash. Provided that the |
283
|
|
|
|
|
|
|
duplication did not happen during a shared hash operation, both threads' |
284
|
|
|
|
|
|
|
handles will subsequently work normally, and can be used independently. |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
=head2 Tainting |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
If L is enabled, taintedness is relevant |
289
|
|
|
|
|
|
|
to some operations on shared hashes. Shared hash handles mostly behave |
290
|
|
|
|
|
|
|
like regular file handles for tainting purposes. Where the following |
291
|
|
|
|
|
|
|
description says that a result is "not tainted", that means it does |
292
|
|
|
|
|
|
|
not get the taint flag set merely by virtue of the operation performed; |
293
|
|
|
|
|
|
|
it may still be marked as tainted if other tainted data is part of the |
294
|
|
|
|
|
|
|
same expression, due to Perl's conservative taint tracking. |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
The classification functions are happy to operate on tainted arguments. |
297
|
|
|
|
|
|
|
Their results are not tainted. |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
When opening a shared hash, if the shared hash filename or the mode |
300
|
|
|
|
|
|
|
string is tainted then it is not permitted to open for writing or with |
301
|
|
|
|
|
|
|
the possibility of creating. It is permitted to open non-creatingly for |
302
|
|
|
|
|
|
|
reading regardless of taint status. Of course, any kind of opening is |
303
|
|
|
|
|
|
|
permitted in an untainted expression. |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
A shared hash handle per se is never tainted. |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
The results of the mode checking functions are not tainted. |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
It is permitted to write tainted data to a shared hash. The data |
310
|
|
|
|
|
|
|
operations all accept tainted arguments. When reading from a shared hash, |
311
|
|
|
|
|
|
|
the value referenced by any key existing in the hash is always tainted, |
312
|
|
|
|
|
|
|
but an absent value is treated as clean. So where a data operation |
313
|
|
|
|
|
|
|
returns a value from the shared hash, the value will be tainted if it is |
314
|
|
|
|
|
|
|
a string, but C representing an absent value will not be tainted. |
315
|
|
|
|
|
|
|
The truth values returned by some operations are not tainted, even if |
316
|
|
|
|
|
|
|
they are derived entirely from tainted data. |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
=cut |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
package Hash::SharedMem; |
321
|
|
|
|
|
|
|
|
322
|
29
|
|
|
29
|
|
1562621
|
{ use 5.006; } |
|
29
|
|
|
|
|
113
|
|
|
29
|
|
|
|
|
1238
|
|
323
|
29
|
|
|
29
|
|
153
|
use warnings; |
|
29
|
|
|
|
|
59
|
|
|
29
|
|
|
|
|
922
|
|
324
|
29
|
|
|
29
|
|
145
|
use strict; |
|
29
|
|
|
|
|
75
|
|
|
29
|
|
|
|
|
1566
|
|
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
our $VERSION = "0.003"; |
327
|
|
|
|
|
|
|
|
328
|
29
|
|
|
29
|
|
913
|
use parent "Exporter"; |
|
29
|
|
|
|
|
394
|
|
|
29
|
|
|
|
|
262
|
|
329
|
|
|
|
|
|
|
our @EXPORT_OK = qw( |
330
|
|
|
|
|
|
|
shash_referential_handle |
331
|
|
|
|
|
|
|
is_shash check_shash |
332
|
|
|
|
|
|
|
shash_open |
333
|
|
|
|
|
|
|
shash_is_readable shash_is_writable shash_mode |
334
|
|
|
|
|
|
|
shash_getd shash_get shash_set shash_gset shash_cset |
335
|
|
|
|
|
|
|
shash_snapshot shash_is_snapshot |
336
|
|
|
|
|
|
|
shash_idle shash_tidy |
337
|
|
|
|
|
|
|
shash_tally_get shash_tally_zero shash_tally_gzero |
338
|
|
|
|
|
|
|
); |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
eval { local $SIG{__DIE__}; |
341
|
|
|
|
|
|
|
require Devel::CallChecker; |
342
|
|
|
|
|
|
|
Devel::CallChecker->VERSION(0.003); |
343
|
|
|
|
|
|
|
}; |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
require XSLoader; |
346
|
|
|
|
|
|
|
XSLoader::load(__PACKAGE__, $VERSION); |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
sub _deparse_shash_unop { |
349
|
18
|
|
|
18
|
|
29
|
my($self, $op, $name) = @_; |
350
|
18
|
|
|
|
|
19
|
my @k; |
351
|
18
|
|
|
|
|
152
|
for(my $k = $op->first; !$k->isa("B::NULL"); $k = $k->sibling) { |
352
|
28
|
|
|
|
|
197
|
push @k, $k; |
353
|
|
|
|
|
|
|
} |
354
|
28
|
|
|
|
|
2590
|
return __PACKAGE__."::".$name. |
355
|
18
|
|
|
|
|
38
|
"(".join(", ", map { $self->deparse($_, 6) } @k).")"; |
356
|
|
|
|
|
|
|
} |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
if("$]" >= 5.013007) { |
359
|
|
|
|
|
|
|
foreach my $name (@EXPORT_OK) { |
360
|
|
|
|
|
|
|
next if $name eq "shash_referential_handle"; |
361
|
29
|
|
|
29
|
|
9470
|
no strict "refs"; |
|
29
|
|
|
|
|
60
|
|
|
29
|
|
|
|
|
5594
|
|
362
|
|
|
|
|
|
|
*{"B::Deparse::pp_$name"} = |
363
|
18
|
|
|
18
|
|
15558
|
sub { _deparse_shash_unop($_[0], $_[1], $name) }; |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
=head1 CONSTANTS |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
=over |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
=item shash_referential_handle |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
Truth value indicating whether each shared hash handle contains |
374
|
|
|
|
|
|
|
a first-class reference to the shared hash to which it refers. |
375
|
|
|
|
|
|
|
See L above for discussion of the |
376
|
|
|
|
|
|
|
significance of this. |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
=back |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=head1 FUNCTIONS |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
The I parameter that most of these functions take must be a handle |
383
|
|
|
|
|
|
|
referring to a shared hash object. |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
=head2 Classification |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=over |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=item is_shash(ARG) |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Returns a truth value indicating whether I is a handle referring |
392
|
|
|
|
|
|
|
to a shared hash object. |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=item check_shash(ARG) |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
Checks whether I is a handle referring to a shared hash object. |
397
|
|
|
|
|
|
|
Returns normally if it is, or Cs if it is not. |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=back |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=head2 Opening |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
=over |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
=item shash_open(FILENAME, MODE) |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
Opens and return a handle referring to a shared hash object, or Cs |
408
|
|
|
|
|
|
|
if the shared hash can't be opened as specified. I must |
409
|
|
|
|
|
|
|
refer to the directory that encapsulates the shared hash. |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
If the filename string contains non-ASCII characters, then the filename |
412
|
|
|
|
|
|
|
actually used consists of the octets of the internal encoding of the |
413
|
|
|
|
|
|
|
string, which does not necessarily match the ostensible characters of the |
414
|
|
|
|
|
|
|
string. This gives inconsistent behaviour for the same character sequence |
415
|
|
|
|
|
|
|
represented in the two different ways that Perl uses internally. This is |
416
|
|
|
|
|
|
|
consistent with the treatment of filenames in Perl's built-in operators |
417
|
|
|
|
|
|
|
such as L; see L
|
418
|
|
|
|
|
|
|
Not Happen">. This may change in future versions of Perl (beyond 5.20). |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
I is a string controlling how the shared hash will be used. |
421
|
|
|
|
|
|
|
It can contain these characters: |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
=over |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
=item B |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
The shared hash is to be readable. If this is not specified then |
428
|
|
|
|
|
|
|
read operations through the handle will be denied. Beware that at the |
429
|
|
|
|
|
|
|
system-call level the files are necessarily opened readably. Thus read |
430
|
|
|
|
|
|
|
permission on the files is required even if one will only be writing. |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
=item B |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
The shared hash is to be writable. If this is not specified then write |
435
|
|
|
|
|
|
|
operations through the handle will be denied. This flag also determines |
436
|
|
|
|
|
|
|
in what mode the files are opened at the system-call level, so write |
437
|
|
|
|
|
|
|
permission on the files operates as expected. |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
=item B |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
The shared hash will be created if it does not already exist. The |
442
|
|
|
|
|
|
|
permission bits on the shared hash will be controlled by the creating |
443
|
|
|
|
|
|
|
process's umask. If this flag is not specified then the shared hash |
444
|
|
|
|
|
|
|
must already exist. |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
=item B |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
The shared hash must not already exist. If this is not specified and the |
449
|
|
|
|
|
|
|
shared hash already exists then it will be opened normally. This flag |
450
|
|
|
|
|
|
|
is meant to be used with B; it means that a successful open implies |
451
|
|
|
|
|
|
|
that this process, rather than any other, is the one that created the |
452
|
|
|
|
|
|
|
shared hash. |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=back |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
When a shared hash is created, some of its constituent files will |
457
|
|
|
|
|
|
|
be opened in read/write mode even if read-only mode was requested. |
458
|
|
|
|
|
|
|
Shared hash creation is not an atomic process, so if a creation attempt |
459
|
|
|
|
|
|
|
is interrupted it may leave a half-created shared hash behind. This does |
460
|
|
|
|
|
|
|
not prevent a subsequent creation attempt on the same shared hash from |
461
|
|
|
|
|
|
|
succeeding: creation will continue from whatever stage it had reached. |
462
|
|
|
|
|
|
|
Likewise, multiple simultaneous creation attempts may each do part of the |
463
|
|
|
|
|
|
|
job. This can result in ownerships and permissions being inconsistent; |
464
|
|
|
|
|
|
|
see L above. |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
Regardless of the combination of efforts leading to the creation of a |
467
|
|
|
|
|
|
|
shared hash, completion of the process is atomic. Non-creating open |
468
|
|
|
|
|
|
|
attempts will either report that there is no shared hash or open the |
469
|
|
|
|
|
|
|
created shared hash. Exactly one creation attempt will be judged to have |
470
|
|
|
|
|
|
|
created the shared hash, and this is detectable through the B flag. |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
=back |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
=head2 Mode checking |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
=over |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
=item shash_is_readable(SHASH) |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
Returns a truth value indicating whether the shared hash can be read |
481
|
|
|
|
|
|
|
from through this handle. |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
=item shash_is_writable(SHASH) |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
Returns a truth value indicating whether the shared hash can be written |
486
|
|
|
|
|
|
|
to through this handle. |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
=item shash_mode(SHASH) |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
Returns a string in which characters indicate the mode of this handle. |
491
|
|
|
|
|
|
|
It matches the form of the I parameter to L, but |
492
|
|
|
|
|
|
|
mode flags that are only relevant during the opening process (B |
493
|
|
|
|
|
|
|
and B) are not included. The returned string can therefore contain |
494
|
|
|
|
|
|
|
these characters: |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
=over |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
=item B |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
The shared hash can be read from through this handle. |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
=item B |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
The shared hash can be written to through this handle. |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=back |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
=back |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
=head2 Data operations |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
For all of these functions, the key of interest (I parameter) |
513
|
|
|
|
|
|
|
can be any octet (Latin-1) string, and values (I parameters and |
514
|
|
|
|
|
|
|
some return values) can be any octet string or C. The C |
515
|
|
|
|
|
|
|
value represents the absence of a key from the hash; there is no |
516
|
|
|
|
|
|
|
present-but-undefined state. Strings containing non-octets (Unicode |
517
|
|
|
|
|
|
|
characters above U+FF) and items other than strings cannot be used as |
518
|
|
|
|
|
|
|
keys or values. If a dualvar (scalar with independent string and numeric |
519
|
|
|
|
|
|
|
values) is supplied, only its string value will be used. |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
=over |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
=item shash_getd(SHASH, KEY) |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
Returns a truth value indicating whether the specified key currently |
526
|
|
|
|
|
|
|
references a defined value in the shared hash. |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
=item shash_get(SHASH, KEY) |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
Returns the value currently referenced by the specified key in the |
531
|
|
|
|
|
|
|
shared hash. |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
=item shash_set(SHASH, KEY, NEWVALUE) |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
Modifies the shared hash so that the specified key henceforth references |
536
|
|
|
|
|
|
|
the specified value. |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
=item shash_gset(SHASH, KEY, NEWVALUE) |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
Modifies the shared hash so that the specified key henceforth references |
541
|
|
|
|
|
|
|
the value I, and returns the value that the key previously |
542
|
|
|
|
|
|
|
referenced. This swap is performed atomically. |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
=item shash_cset(SHASH, KEY, CHKVALUE, NEWVALUE) |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
Examines the value currently referenced by the specified key in the |
547
|
|
|
|
|
|
|
shared hash. If it is identical to I, the function modifies |
548
|
|
|
|
|
|
|
the shared hash so that the specified key henceforth references the value |
549
|
|
|
|
|
|
|
I, and returns true. If the current value is not identical |
550
|
|
|
|
|
|
|
to I, the function leaves it unmodified and returns false. |
551
|
|
|
|
|
|
|
This conditional modification is performed atomically. |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
This function can be used as a core on which to build arbitrarily |
554
|
|
|
|
|
|
|
complex kinds of atomic operation (on a single key). For example, |
555
|
|
|
|
|
|
|
an atomic increment can be implemented as |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
do { |
558
|
|
|
|
|
|
|
$ov = shash_get($shash, $key); |
559
|
|
|
|
|
|
|
$nv = $ov + 1; |
560
|
|
|
|
|
|
|
} until shash_cset($shash, $key, $ov, $nv); |
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
=back |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
=head2 Snapshots |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
=over |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
=item shash_snapshot(SHASH) |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
Returns a shared hash handle that encapsulates the current content of the |
571
|
|
|
|
|
|
|
shared hash. The entire state of the shared hash is captured atomically, |
572
|
|
|
|
|
|
|
and the returned handle can be used to perform arbitrarily many read |
573
|
|
|
|
|
|
|
operations on that state: it will never reflect later modifications to |
574
|
|
|
|
|
|
|
the shared hash. The snapshot handle cannot be used for writing. |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
=item shash_is_snapshot(SHASH) |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
Returns a truth value indicating whether this handle refers to a snapshot |
579
|
|
|
|
|
|
|
(as opposed to a live shared hash). |
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
=back |
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
=head2 Maintenance |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
=over |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
=item shash_idle(SHASH) |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
Puts the shared hash handle into a state where it occupies less |
590
|
|
|
|
|
|
|
resources, at the expense of making the next operation through the |
591
|
|
|
|
|
|
|
handle more expensive. This doesn't change the visible behaviour of the |
592
|
|
|
|
|
|
|
handle, and doesn't affect the state of the shared hash itself at all. |
593
|
|
|
|
|
|
|
The invisible operations performed by this function may vary between |
594
|
|
|
|
|
|
|
versions of this module. |
595
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
This function should be called when the handle is going to be unused for |
597
|
|
|
|
|
|
|
a lengthy period. For example, if a long-running daemon uses a shared |
598
|
|
|
|
|
|
|
hash in brief bursts once an hour, it should idle its handle at the end |
599
|
|
|
|
|
|
|
of each burst of activity. |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
Currently the effect of this operation is to discard the handle's |
602
|
|
|
|
|
|
|
memory mapping of the shared hash data file. The next operation has to |
603
|
|
|
|
|
|
|
reestablish the mapping. The benefit of discarding the mapping is that |
604
|
|
|
|
|
|
|
periodically the data file has to be replaced with a new one, but the |
605
|
|
|
|
|
|
|
old data file continues to exist as long as some process has it mapped. |
606
|
|
|
|
|
|
|
A process that is actively using the shared hash will quickly notice that |
607
|
|
|
|
|
|
|
the data file has been replaced and will unmap the old one. A process |
608
|
|
|
|
|
|
|
with a handle that it's not using, however, could keep the old data |
609
|
|
|
|
|
|
|
file in existence, occupying storage, long after it has no further use. |
610
|
|
|
|
|
|
|
A handle that has been put into the idle state won't perpetuate the |
611
|
|
|
|
|
|
|
existence of an obsolete data file. |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
=item shash_tidy(SHASH) |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
Rearranges the storage of the shared hash if it seems useful to do |
616
|
|
|
|
|
|
|
so, to avoid tidying work having to be performed by other processes. |
617
|
|
|
|
|
|
|
This doesn't change the visible content of the shared hash, but the |
618
|
|
|
|
|
|
|
handle must be open for writing. The invisible operations performed by |
619
|
|
|
|
|
|
|
this function may vary between versions of this module. |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
This function should be called in circumstances where it is acceptable |
622
|
|
|
|
|
|
|
to incur some delay for this maintenance work to complete. For example, |
623
|
|
|
|
|
|
|
it could be called periodically by a cron job. Essentially, calling this |
624
|
|
|
|
|
|
|
function signals that this is a convenient time at which (and process |
625
|
|
|
|
|
|
|
in which) to perform maintenance. |
626
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
If this maintenance work is not carried out by means of this function, |
628
|
|
|
|
|
|
|
then ultimately it will be performed anyway, but less predictably and |
629
|
|
|
|
|
|
|
possibly less conveniently. Eventually it will become necessary to |
630
|
|
|
|
|
|
|
perform maintenance in order to continue using the shared hash, at which |
631
|
|
|
|
|
|
|
point the next process that attempts to write to it will carry out the |
632
|
|
|
|
|
|
|
work and incur the cost. The shared hash will still work properly in |
633
|
|
|
|
|
|
|
that case, but the unlucky writer will experience a disproportionately |
634
|
|
|
|
|
|
|
large delay in the completion of its write operation. This could well |
635
|
|
|
|
|
|
|
be a problem if the shared hash is large. |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
=back |
638
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
=head2 Event counters |
640
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
=over |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
=item shash_tally_get(SHASH) |
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
Returns a reference to a hash of counts of events that have occurred with |
646
|
|
|
|
|
|
|
this shared hash handle. These counts may be of interest for profiling |
647
|
|
|
|
|
|
|
and debugging purposes, but should not be relied upon for semantic |
648
|
|
|
|
|
|
|
purposes. The event types may vary between versions of this module. |
649
|
|
|
|
|
|
|
Few of the event types make sense in terms of the API supplied by this |
650
|
|
|
|
|
|
|
module: most of them are internal implementation details. |
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
Events are counted separately for each handle. The events counted are |
653
|
|
|
|
|
|
|
associated specifically with the handle, rather than with the shared hash |
654
|
|
|
|
|
|
|
as a whole. Generally, an idle handle will accumulate no events, even |
655
|
|
|
|
|
|
|
if the shared hash to which it refers is active. The event counters |
656
|
|
|
|
|
|
|
start at zero when a handle is opened, and can be reset to zero by |
657
|
|
|
|
|
|
|
L or L. |
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
In the returned hash, each key identifies a type of event, and the |
660
|
|
|
|
|
|
|
corresponding value is (unless wrapped) the number of times events of that |
661
|
|
|
|
|
|
|
type have occurred on the handle since the counters were last zeroed. |
662
|
|
|
|
|
|
|
Currently the event counters are held in fixed-size variables and can |
663
|
|
|
|
|
|
|
wrap, so if event counts might get as high as 2^64 then they can't be |
664
|
|
|
|
|
|
|
relied upon to be accurate. Wrapping will not occur at less than 2^64; |
665
|
|
|
|
|
|
|
in other respects, wrapping behaviour may change in the future. |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
The event types that are currently counted are: |
668
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
=over |
670
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
=item B |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
Parse an octet string representation in a shared hash data file. |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
=item B |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
Write an octet string representation into a shared hash data file. |
678
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
=item B |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
Parse a B-tree node representation in a shared hash data file. |
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
=item B |
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
Write a B-tree node representation into a shared hash data file. |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
=item B |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
Compare two strings as shared hash keys. |
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
=item B |
692
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
Attempt to replace the root pointer in a shared hash data file. This may |
694
|
|
|
|
|
|
|
be done to change the content of the shared hash, or as part of the |
695
|
|
|
|
|
|
|
process of switching to a new data file. |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
=item B |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
Succeed in replacing the root pointer in a shared hash data file. |
700
|
|
|
|
|
|
|
An attempt will fail if another process changed the root pointer during |
701
|
|
|
|
|
|
|
the operation that required this process to change the root pointer. |
702
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
=item B |
704
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
Attempt to replace the data file in a shared hash. This is necessary |
706
|
|
|
|
|
|
|
from time to time as data files fill up. |
707
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
=item B |
709
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
Succeed in replacing the data file in a shared hash. An attempt will |
711
|
|
|
|
|
|
|
fail if another process replaced the data file while this process was |
712
|
|
|
|
|
|
|
initialising its new one. |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
=item B |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
Perform a high-level data operation that purely reads from the shared |
717
|
|
|
|
|
|
|
hash: L or L. |
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
=item B |
720
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
Perform a high-level data operation that writes, or at least may write, |
722
|
|
|
|
|
|
|
to the shared hash: L, L, or L. |
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
=back |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
=item shash_tally_zero(SHASH) |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
Zero the event counters that can be read by L. |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
=item shash_tally_gzero(SHASH) |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
Zero the event counters that can be read by L, and |
733
|
|
|
|
|
|
|
return the values the event counters previously had, in the same form |
734
|
|
|
|
|
|
|
as L. This swap is performed atomically. |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
=back |
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
=head1 BUGS |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
As explained for L, creation of a shared hash is not atomic. |
741
|
|
|
|
|
|
|
This is an unavoidable consequence of the need for the shared hash to |
742
|
|
|
|
|
|
|
consist of multiple files in a directory. Multi-party creation can result |
743
|
|
|
|
|
|
|
in the files having different permission bits; to avoid this, all creators |
744
|
|
|
|
|
|
|
should use the same umask. Multiple users writing to a shared hash can |
745
|
|
|
|
|
|
|
result in the files having different ownerships, so the permission bits |
746
|
|
|
|
|
|
|
must be chosen to work appropriately with the chimeric ownership. |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
When calls to the functions supplied by this module are compiled down to |
749
|
|
|
|
|
|
|
custom ops (which is attempted for performance reasons), the ability to |
750
|
|
|
|
|
|
|
deparse the resulting code with L is limited. Prior to Perl |
751
|
|
|
|
|
|
|
5.13.7, deparsing will generate very incorrect code. From Perl 5.13.7 |
752
|
|
|
|
|
|
|
onwards, deparsing should normally work, but will break if another module |
753
|
|
|
|
|
|
|
defines a separate type of custom op that happens to have the same short |
754
|
|
|
|
|
|
|
name (though these ops do not clash in other respects). |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
=head1 SEE ALSO |
757
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
L, |
759
|
|
|
|
|
|
|
L |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
=head1 AUTHOR |
762
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
Andrew Main (Zefram) |
764
|
|
|
|
|
|
|
|
765
|
|
|
|
|
|
|
=head1 COPYRIGHT |
766
|
|
|
|
|
|
|
|
767
|
|
|
|
|
|
|
Copyright (C) 2014 PhotoBox Ltd |
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
Copyright (C) 2014 Andrew Main (Zefram) |
770
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
=head1 LICENSE |
772
|
|
|
|
|
|
|
|
773
|
|
|
|
|
|
|
This module is free software; you can redistribute it and/or modify it |
774
|
|
|
|
|
|
|
under the same terms as Perl itself. |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
=cut |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
1; |