blib/lib/Devel/RingBuffer/Ring.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 94 | 117 | 80.3 |
branch | 10 | 24 | 41.6 |
condition | 4 | 9 | 44.4 |
subroutine | 38 | 47 | 80.8 |
pod | 0 | 25 | 0.0 |
total | 146 | 222 | 65.7 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | #/** | ||||||
2 | # A single shared memory ring buffer for diagnosis/debug of Perl scripts. | ||||||
3 | # Uses IPC::Mmap to create/access/manage a memory mapped file (or namespace | ||||||
4 | # on Win32) as a ring buffer structure that can be used by "applications | ||||||
5 | # under test" that use an appropriate debug module (e.g., Devel::STrace) | ||||||
6 | # along with an external monitoring application | ||||||
7 | # (e.g., Devel::STrace::Monitor). | ||||||
8 | #
|
||||||
9 | # Note that significant functionality is written in XS/C in order to minimize | ||||||
10 | # tracing/debugging overhead. | ||||||
11 | #
|
||||||
12 | # Permission is granted to use this software under the same terms as Perl itself. | ||||||
13 | # Refer to the Perl Artistic License | ||||||
14 | # for details. | ||||||
15 | # | ||||||
16 | # @author D. Arnold | ||||||
17 | # @since 2006-05-01 | ||||||
18 | # @self $self | ||||||
19 | #*/ | ||||||
20 | package Devel::RingBuffer::Ring; | ||||||
21 | |||||||
22 | #use threads; | ||||||
23 | 7 | 7 | 42 | use Time::HiRes qw(time); | |||
7 | 15 | ||||||
7 | 69 | ||||||
24 | 7 | 7 | 1041 | use Exporter; | |||
7 | 15 | ||||||
7 | 527 | ||||||
25 | |||||||
26 | BEGIN { | ||||||
27 | 7 | 7 | 169 | our @ISA = qw(Exporter); | |||
28 | # | ||||||
29 | # consts for member indexes | ||||||
30 | # | ||||||
31 | 7 | 7 | 42 | use constant RINGBUF_RING_BUFFER => 0; | |||
7 | 20 | ||||||
7 | 453 | ||||||
32 | 7 | 7 | 41 | use constant RINGBUF_RING_SLOTS => 1; | |||
7 | 8 | ||||||
7 | 347 | ||||||
33 | # | ||||||
34 | # !!!+++!+!+!+!+!+!+!+!+!+!+!+ | ||||||
35 | # !!!DON'T CHANGE THIS INDEX UNLESS YOU CHANGE THE XS CODE TOO!!!! | ||||||
36 | # !!!+++!+!+!+!+!+!+!+!+!+!+!+ | ||||||
37 | # | ||||||
38 | 7 | 7 | 36 | use constant RINGBUF_RING_ADDR => 2; | |||
7 | 21 | ||||||
7 | 297 | ||||||
39 | |||||||
40 | 7 | 7 | 41 | use constant RINGBUF_RING_PID => 3; | |||
7 | 56 | ||||||
7 | 334 | ||||||
41 | 7 | 7 | 47 | use constant RINGBUF_RING_TID => 4; | |||
7 | 20 | ||||||
7 | 339 | ||||||
42 | 7 | 7 | 36 | use constant RINGBUF_RING_SLOT => 5; | |||
7 | 14 | ||||||
7 | 367 | ||||||
43 | 7 | 7 | 43 | use constant RINGBUF_RING_DEPTH => 6; | |||
7 | 8 | ||||||
7 | 375 | ||||||
44 | 7 | 7 | 44 | use constant RINGBUF_RING_INDEX => 7; | |||
7 | 14 | ||||||
7 | 538 | ||||||
45 | 7 | 7 | 42 | use constant RINGBUF_RING_MSGSZ => 8; | |||
7 | 8 | ||||||
7 | 271 | ||||||
46 | 7 | 7 | 36 | use constant RINGBUF_RING_HDRSZ => 9; | |||
7 | 14 | ||||||
7 | 345 | ||||||
47 | 7 | 7 | 31 | use constant RINGBUF_BASE_ADDR => 10; | |||
7 | 14 | ||||||
7 | 356 | ||||||
48 | |||||||
49 | 7 | 7 | 36 | use constant RINGBUF_RING_WAIT => 0.3; | |||
7 | 15 | ||||||
7 | 864 | ||||||
50 | |||||||
51 | 7 | 21 | our @EXPORT = (); | ||||
52 | 7 | 13 | our @EXPORT_OK = (); | ||||
53 | 7 | 29 | our %EXPORT_TAGS = ( | ||||
54 | ring_members => [ | ||||||
55 | qw/RINGBUF_RING_BUFFER RINGBUF_RING_SLOTS RINGBUF_RING_ADDR | ||||||
56 | RINGBUF_RING_PID RINGBUF_RING_TID RINGBUF_RING_SLOT RINGBUF_RING_DEPTH | ||||||
57 | RINGBUF_RING_INDEX RINGBUF_RING_MSGSZ RINGBUF_RING_HDRSZ | ||||||
58 | RINGBUF_BASE_ADDR/ | ||||||
59 | ], | ||||||
60 | ); | ||||||
61 | |||||||
62 | 7 | 426 | Exporter::export_tags(keys %EXPORT_TAGS); | ||||
63 | |||||||
64 | }; | ||||||
65 | |||||||
66 | 7 | 7 | 45 | use Config; | |||
7 | 14 | ||||||
7 | 297 | ||||||
67 | 7 | 7 | 36 | use Devel::RingBuffer; # to bootstrap | |||
7 | 14 | ||||||
7 | 1576 | ||||||
68 | 7 | 7 | 37 | use Devel::RingBuffer qw(:ringbuffer_consts); | |||
7 | 14 | ||||||
7 | 4849 | ||||||
69 | |||||||
70 | our $hasThreads; | ||||||
71 | |||||||
72 | BEGIN { | ||||||
73 | 7 | 50 | 33 | 7 | 258 | if ($Config{useithreads} && (!$ENV{DEVEL_RINGBUF_NOTHREADS})) { | |
74 | 0 | 0 | require Devel::RingBuffer::ThreadFacade; | ||||
75 | 0 | 0 | $hasThreads = 1; | ||||
76 | } | ||||||
77 | } | ||||||
78 | |||||||
79 | 7 | 7 | 49 | use strict; | |||
7 | 14 | ||||||
7 | 279 | ||||||
80 | 7 | 7 | 42 | use warnings; | |||
7 | 20 | ||||||
7 | 21456 | ||||||
81 | |||||||
82 | our $VERSION = '0.31'; | ||||||
83 | #/** | ||||||
84 | # Constructor. Allocates a ring buffer, and initializes its header | ||||||
85 | # and control variables. | ||||||
86 | # | ||||||
87 | # @param $ringbuffer the Devel::RingBuffer object | ||||||
88 | # @param $ringaddr the base address of this ring | ||||||
89 | # @param $baseaddr base address of the complete ring buffer structure | ||||||
90 | # @param $ringnum the number (i.e., positional index) of this ring | ||||||
91 | # @param $slots number of slots per ring | ||||||
92 | # @param $msgareasz size of the per-thread message area | ||||||
93 | # | ||||||
94 | # @return Devel::RingBuffer::Ring object on success; undef on failure | ||||||
95 | #*/ | ||||||
96 | sub new { | ||||||
97 | 24 | 24 | 0 | 132 | my ($class, $ringbuffer, $ringaddr, $baseaddr, $ringnum, $slots, $msgareasz) = @_; | ||
98 | |||||||
99 | 24 | 50 | 69 | my $tid = ($hasThreads ? Devel::RingBuffer::ThreadFacade->tid() : 0); | |||
100 | 24 | 433 | _init_ring($ringaddr, $$, $tid, $baseaddr); | ||||
101 | |||||||
102 | 24 | 365 | return bless [ | ||||
103 | $ringbuffer, | ||||||
104 | $slots, | ||||||
105 | $ringaddr, | ||||||
106 | $$, | ||||||
107 | $tid, | ||||||
108 | -1, | ||||||
109 | 0, | ||||||
110 | $ringnum, | ||||||
111 | $msgareasz, | ||||||
112 | RINGBUF_BUFHDR_SZ + $msgareasz, | ||||||
113 | $baseaddr | ||||||
114 | ], $class; | ||||||
115 | } | ||||||
116 | #/** | ||||||
117 | # Constructor. Allocates a ring buffer, and initializes its header | ||||||
118 | # and control variables. Called when the AUT object (e.g., DB) | ||||||
119 | # is CLONE'd, so that a new ring can be assigned to the new thread | ||||||
120 | # | ||||||
121 | # @return the Devel::RingBuffer::Ring object | ||||||
122 | #*/ | ||||||
123 | sub clone { | ||||||
124 | 0 | 0 | 0 | 0 | my $self = shift; | ||
125 | |||||||
126 | 0 | 0 | 0 | my $tid = ($hasThreads ? Devel::RingBuffer::ThreadFacade->tid() : 0); | |||
127 | 0 | 0 | my ($ringnum, $ringaddr) = $self->[RINGBUF_RING_BUFFER]->reallocate(); | ||||
128 | 0 | 0 | 0 | return undef unless defined($ringnum); | |||
129 | 0 | 0 | $self->[RINGBUF_RING_ADDR] = $ringaddr; | ||||
130 | 0 | 0 | $self->[RINGBUF_RING_INDEX] = $ringnum; | ||||
131 | 0 | 0 | _init_ring($ringaddr, $$, $tid, $self->[RINGBUF_BASE_ADDR]); | ||||
132 | 0 | 0 | return $self; | ||||
133 | } | ||||||
134 | #/** | ||||||
135 | # Constructor. Opens an existing ring buffer for read-only access. | ||||||
136 | # | ||||||
137 | # @param $ringbuffer the Devel::RingBuffer object | ||||||
138 | # @param $ringaddr the base address of this ring | ||||||
139 | # @param $baseaddr base address of the complete ring buffer structure | ||||||
140 | # @param $ringnum the number (i.e., positional index) of this ring | ||||||
141 | # @param $slots number of slots per ring | ||||||
142 | # @param $msgareasz size of the per-thread message area | ||||||
143 | # | ||||||
144 | # @return Devel::RingBuffer::Ring object on success; undef on failure | ||||||
145 | #*/ | ||||||
146 | sub open { | ||||||
147 | 19 | 19 | 0 | 62 | my ($class, $ringbuffer, $ringaddr, $baseaddr, $ringnum, $slots, $msgareasz) = @_; | ||
148 | |||||||
149 | 19 | 88 | my ($pid, $tid, $slot, $depth) = _get_header($ringaddr); | ||||
150 | |||||||
151 | 19 | 174 | return bless [ | ||||
152 | $ringbuffer, | ||||||
153 | $slots, | ||||||
154 | $ringaddr, | ||||||
155 | $pid, | ||||||
156 | $tid, | ||||||
157 | $slot, | ||||||
158 | $depth, | ||||||
159 | $ringnum, | ||||||
160 | $msgareasz, | ||||||
161 | RINGBUF_BUFHDR_SZ + $msgareasz, | ||||||
162 | $baseaddr | ||||||
163 | ], $class; | ||||||
164 | } | ||||||
165 | #/** | ||||||
166 | # Update the current slot. Only updates linenumber and timestamp. | ||||||
167 | # May be called as either object or class method; in the latter case, | ||||||
168 | # caller must supply the ring's base address (used within DB::DB() | ||||||
169 | # to optimize access speed) | ||||||
170 | # | ||||||
171 | # @param $address class method calls only: base address of the ring | ||||||
172 | # @param $linenumber linenumber of current statement | ||||||
173 | # | ||||||
174 | # @return the Devel::RingBuffer::Ring object | ||||||
175 | #*/ | ||||||
176 | # @xs updateSlot | ||||||
177 | |||||||
178 | #/** | ||||||
179 | # @xs nextSlot | ||||||
180 | # Allocate and initialize the next slot. If the stack depth is | ||||||
181 | # greater than the configured number of slots, the oldest | ||||||
182 | # in-use slot is used, overwriting its current contents. | ||||||
183 | # May be called as either object or class method; in the latter case, | ||||||
184 | # caller must supply the ring's base address (used within DB::sub() | ||||||
185 | # to optimize access speed) | ||||||
186 | #
|
||||||
187 | # Note: In future, this should return prior contents so we can restore | ||||||
188 | # on de-wrapping. | ||||||
189 | # | ||||||
190 | # @param $address class method calls only: base address of the ring | ||||||
191 | # @param $entry subroutine name (from $DB::sub) | ||||||
192 | # | ||||||
193 | # @return the stack depth after the slot is allocated. | ||||||
194 | #*/ | ||||||
195 | # @xs nextSlot | ||||||
196 | |||||||
197 | #/** | ||||||
198 | # @xs freeSlot | ||||||
199 | # Free the current slot and invalidates its contents. | ||||||
200 | # May be called as either object or class method; in the latter case, | ||||||
201 | # caller must supply the ring's base address (used within DB::sub() | ||||||
202 | # to optimize access speed) | ||||||
203 | # | ||||||
204 | # @param $address class method calls only: base address of the ring | ||||||
205 | # | ||||||
206 | # @return the stack depth after the slot is freed. | ||||||
207 | #*/ | ||||||
208 | # @xs freeSlot | ||||||
209 | |||||||
210 | #/** | ||||||
211 | # Get the ring header values. Header fields returned are | ||||||
212 | #
|
||||||
213 | # |
||||||
214 | # |
||||||
215 | # |
||||||
216 | # |
||||||
217 | # |
||||||
218 | # | ||||||
219 | # | ||||||
220 | # @return list of header values | ||||||
221 | #*/ | ||||||
222 | sub getHeader { | ||||||
223 | 18 | 18 | 0 | 794 | return _get_header($_[0]->[RINGBUF_RING_ADDR]); | ||
224 | } | ||||||
225 | |||||||
226 | #/** | ||||||
227 | # Get the ring number (i.e., positional index) | ||||||
228 | # | ||||||
229 | # @return the ring number | ||||||
230 | #*/ | ||||||
231 | 86 | 86 | 0 | 1387 | sub getIndex { return $_[0]->[RINGBUF_RING_INDEX]; } | ||
232 | |||||||
233 | #/** | ||||||
234 | # Get the ring base address | ||||||
235 | # | ||||||
236 | # @return the ring base address | ||||||
237 | #*/ | ||||||
238 | 0 | 0 | 0 | 0 | sub getAddress { return $_[0]->[RINGBUF_RING_ADDR]; } | ||
239 | |||||||
240 | #/** | ||||||
241 | # Get the contents of the specified slot. | ||||||
242 | # | ||||||
243 | # @param $slot the number of the slot to return | ||||||
244 | # | ||||||
245 | # @return the line number, timestamp, and subroutine name from the slot | ||||||
246 | #*/ | ||||||
247 | sub getSlot { | ||||||
248 | 26 | 26 | 0 | 782 | my ($self, $slot) = @_; | ||
249 | |||||||
250 | 26 | 50 | 33 | 217 | return (-1, 0, '(Invalid slot; ring has been wrapped)') | ||
251 | if ($slot < 0) || ($slot > $self->[RINGBUF_RING_SLOTS]); | ||||||
252 | |||||||
253 | 26 | 139 | return _get_slot($self->[RINGBUF_RING_ADDR], $slot); | ||||
254 | } | ||||||
255 | #/** | ||||||
256 | # Get the ring's trace flag | ||||||
257 | # | ||||||
258 | # @return the ring's trace flag | ||||||
259 | #*/ | ||||||
260 | sub getTrace { | ||||||
261 | 0 | 0 | 0 | 0 | return _get_trace($_[0]->[RINGBUF_RING_ADDR]); | ||
262 | } | ||||||
263 | |||||||
264 | #/** | ||||||
265 | # Set the ring's trace flag | ||||||
266 | # | ||||||
267 | # @param $trace the value to set | ||||||
268 | # | ||||||
269 | # @return the prior value of the ring's trace flag | ||||||
270 | #*/ | ||||||
271 | sub setTrace { | ||||||
272 | 0 | 0 | 0 | 0 | return _set_trace($_[0]->[RINGBUF_RING_ADDR], $_[1]); | ||
273 | } | ||||||
274 | |||||||
275 | #/** | ||||||
276 | # Get the ring's signal flag | ||||||
277 | # | ||||||
278 | # @return the ring's signal flag | ||||||
279 | #*/ | ||||||
280 | sub getSignal { | ||||||
281 | 0 | 0 | 0 | 0 | return _get_single($_[0]->[RINGBUF_RING_ADDR]); | ||
282 | } | ||||||
283 | |||||||
284 | #/** | ||||||
285 | # Set the ring's signal flag | ||||||
286 | # | ||||||
287 | # @param $signal the value to set | ||||||
288 | # | ||||||
289 | # @return the prior value of the ring's signal flag | ||||||
290 | #*/ | ||||||
291 | sub setSignal { | ||||||
292 | 0 | 0 | 0 | 0 | return _set_signal($_[0]->[RINGBUF_RING_ADDR], $_[1]); | ||
293 | } | ||||||
294 | |||||||
295 | #/** | ||||||
296 | # Post a command to the ring's command/message area | ||||||
297 | # | ||||||
298 | # @param $command the command value to set; must be no more than 3 bytes | ||||||
299 | # @param $msg an optional message associated with the command; max length | ||||||
300 | # is determined by configuration settings | ||||||
301 | # | ||||||
302 | # @return the ring object | ||||||
303 | #*/ | ||||||
304 | 4 | 4 | 0 | 49 | sub postCommand { return postCmdEvent(@_, 1); } | ||
305 | |||||||
306 | #/** | ||||||
307 | # Post a response to the ring's command/message area | ||||||
308 | # | ||||||
309 | # @param $response the response value to set; must be no more than 3 bytes | ||||||
310 | # @param $msg an optional message associated with the response; max length | ||||||
311 | # is determined by configuration settings | ||||||
312 | # | ||||||
313 | # @return the ring object | ||||||
314 | #*/ | ||||||
315 | 4 | 4 | 0 | 40 | sub postResponse { return postCmdEvent(@_, 0); } | ||
316 | |||||||
317 | sub postCmdEvent { | ||||||
318 | 8 | 8 | 0 | 13 | my ($self, $cmd, $msg, $state) = @_; | ||
319 | 8 | 29 | _post_cmd_msg($self->[RINGBUF_RING_ADDR], $cmd, $msg, $state); | ||||
320 | |||||||
321 | 8 | 14 | return $self; | ||||
322 | } | ||||||
323 | |||||||
324 | #/** | ||||||
325 | # Wait indefinitely for a command to be posted to the ring's command/message area. | ||||||
326 | # | ||||||
327 | # @return the posted command and message | ||||||
328 | #*/ | ||||||
329 | sub waitForCommand { | ||||||
330 | 0 | 0 | 0 | 0 | return waitForCmdEvent(@_, 1); | ||
331 | } | ||||||
332 | |||||||
333 | #/** | ||||||
334 | # Wait indefinitely for a response to be posted to the ring's command/message area. | ||||||
335 | # | ||||||
336 | # @return the posted response and message | ||||||
337 | #*/ | ||||||
338 | sub waitForResponse { | ||||||
339 | 0 | 0 | 0 | 0 | return waitForCmdEvent(@_, 0); | ||
340 | } | ||||||
341 | |||||||
342 | sub waitForCmdEvent { | ||||||
343 | 0 | 0 | 0 | 0 | my ($cmd, $msg); | ||
344 | 0 | 0 | while (1) { | ||||
345 | 0 | 0 | ($cmd, $msg) = _check_for_cmd_msg($_[0]->[RINGBUF_RING_ADDR], $_[1]); | ||||
346 | 0 | 0 | 0 | last if defined($cmd); | |||
347 | 0 | 0 | sleep RINGBUF_RING_WAIT; | ||||
348 | } | ||||||
349 | 0 | 0 | return ($cmd, $msg); | ||||
350 | } | ||||||
351 | |||||||
352 | #/** | ||||||
353 | # Test if a command is available in the ring's command/message area. | ||||||
354 | # | ||||||
355 | # @return if available, the posted command and message; otherwise an empty list | ||||||
356 | #*/ | ||||||
357 | sub checkCommand { | ||||||
358 | 4 | 4 | 0 | 47 | return checkCmdEvent(@_, 1); | ||
359 | } | ||||||
360 | |||||||
361 | #/** | ||||||
362 | # Test if a response is available in the ring's command/message area. | ||||||
363 | # | ||||||
364 | # @return if available, the posted response and message; otherwise an empty list | ||||||
365 | #*/ | ||||||
366 | sub checkResponse { | ||||||
367 | 4 | 4 | 0 | 41 | return checkCmdEvent(@_, 0); | ||
368 | } | ||||||
369 | |||||||
370 | sub checkCmdEvent { | ||||||
371 | 8 | 8 | 0 | 35 | return _check_for_cmd_msg($_[0]->[RINGBUF_RING_ADDR], $_[1]); | ||
372 | } | ||||||
373 | #/** | ||||||
374 | # Allocate and initialize a watchlist entry. Sets the watch expression. | ||||||
375 | # | ||||||
376 | # @param $expr expression to set | ||||||
377 | # | ||||||
378 | # @return allocated watchlist entry number on success; undef on failure | ||||||
379 | #*/ | ||||||
380 | sub addWatch { | ||||||
381 | 4 | 4 | 0 | 50 | return _add_watch_expr($_[0]->[RINGBUF_RING_ADDR], $_[1]); | ||
382 | } | ||||||
383 | |||||||
384 | #/** | ||||||
385 | # Free a watchlist entry. | ||||||
386 | # | ||||||
387 | # @param $watch the watchlist entry number to free | ||||||
388 | # | ||||||
389 | #*/ | ||||||
390 | sub freeWatch { | ||||||
391 | 4 | 4 | 0 | 40 | return _free_watch_expr($_[0]->[RINGBUF_RING_ADDR], $_[1]); | ||
392 | } | ||||||
393 | |||||||
394 | #/** | ||||||
395 | # Get a watchlist expression entry. | ||||||
396 | # | ||||||
397 | # @param $watch the watchlist entry number to get | ||||||
398 | # | ||||||
399 | # @return the expression in the watchlist entry, if any; undef otherwise | ||||||
400 | #*/ | ||||||
401 | sub getWatchExpr { | ||||||
402 | 4 | 50 | 4 | 0 | 63 | return $_[0]->[RINGBUF_RING_BUFFER] ? | |
403 | _get_watch_expr($_[0]->[RINGBUF_RING_ADDR], $_[1]) : | ||||||
404 | undef; | ||||||
405 | } | ||||||
406 | |||||||
407 | #/** | ||||||
408 | # Set a watchlist result entry. | ||||||
409 | # | ||||||
410 | # @param $watch the watchlist entry number to set | ||||||
411 | # @param $result the result of the expression evaluation | ||||||
412 | # @param $error error string if expression evaluation fails | ||||||
413 | #*/ | ||||||
414 | sub setWatchResult { | ||||||
415 | 4 | 4 | 0 | 46 | my ($self, $watch, $result, $error) = @_; | ||
416 | |||||||
417 | 4 | 50 | 19 | return $self->[RINGBUF_RING_BUFFER] ? | |||
418 | _set_watch_result($self->[RINGBUF_RING_ADDR], $watch, $result, $error) : | ||||||
419 | undef; | ||||||
420 | } | ||||||
421 | #/** | ||||||
422 | # Get a watchlist expression entry. If the length of the result exceeds | ||||||
423 | # the configured message size, the result is truncated. If the result is | ||||||
424 | # undef, the length will zero, and both the result and error will be undef. | ||||||
425 | # If the evaluation caused a failure, the length indicates the length of | ||||||
426 | # the error string, and result will be undef. | ||||||
427 | # | ||||||
428 | # @param $watch the watchlist entry number to get | ||||||
429 | # | ||||||
430 | # @return the complete length of the result, the (possibly truncated) result value, | ||||||
431 | # and the (possibly truncated) error message (if the evaluation failed). | ||||||
432 | #*/ | ||||||
433 | sub getWatchResult { | ||||||
434 | 4 | 50 | 4 | 0 | 61 | return $_[0]->[RINGBUF_RING_BUFFER] ? | |
435 | _get_watch_result($_[0]->[RINGBUF_RING_ADDR], $_[1]) : | ||||||
436 | (undef, undef, undef); | ||||||
437 | } | ||||||
438 | #/** | ||||||
439 | # Destructor. Updates the Devel::RingBuffer container object's free ring map, | ||||||
440 | # but only if executed in the same process/thread that it was allocated'd in. | ||||||
441 | # (Note that due to threads CLONE, a ring object may be cloned with PID/TID | ||||||
442 | # of another thread, and thus DESTROY() could cause an invalid destruction) | ||||||
443 | #
|
||||||
444 | # A future enhancement will add a flag to indicate to preserve | ||||||
445 | # the ring on exit for post-mortem analysis | ||||||
446 | #*/ | ||||||
447 | sub DESTROY { | ||||||
448 | # | ||||||
449 | # for some reason we're getting leakage of ring objects into | ||||||
450 | # the root thread, so only destroy in the thread its created | ||||||
451 | # | ||||||
452 | # return unless defined($_[0]->[RINGBUF_RING_BUFFER]) && | ||||||
453 | # ($_[0]->[RINGBUF_RING_PID] == $$) && | ||||||
454 | # ($_[0]->[RINGBUF_RING_TID] == threads->self()->tid()); | ||||||
455 | 43 | 50 | 43 | 206853 | return unless defined($_[0]->[RINGBUF_RING_BUFFER]); | ||
456 | 43 | 230 | my @hdr = _get_header($_[0]->[RINGBUF_RING_ADDR]); | ||||
457 | 43 | 50 | 204 | my $tid = ($hasThreads ? Devel::RingBuffer::ThreadFacade->tid() : 0); | |||
458 | |||||||
459 | return | ||||||
460 | 43 | 100 | 66 | 821 | unless ($hdr[0] == $$) && ($hdr[1] == $tid); | ||
461 | 23 | 244 | $_[0]->[RINGBUF_RING_BUFFER]->free($_[0]->[RINGBUF_RING_INDEX]); | ||||
462 | } | ||||||
463 | |||||||
464 | 1; |