File Coverage

blib/lib/Object/ForkAware.pm
Criterion Covered Total %
statement 43 44 97.7
branch 23 24 95.8
condition 8 14 57.1
subroutine 11 12 91.6
pod 1 4 25.0
total 86 98 87.7


line stmt bran cond sub pod time code
1 10     10   307007 use strict;
  10         29  
  10         323  
2 10     10   49 use warnings;
  10         20  
  10         449  
3             package Object::ForkAware;
4             # git description: v0.002-13-gf7cb9f7
5             $Object::ForkAware::VERSION = '0.003';
6             # ABSTRACT: Make an object aware of process forks and threads, recreating itself as needed
7             # KEYWORDS: process thread fork multiprocessing multithreading clone
8             # vim: set ts=8 sw=4 tw=78 et :
9              
10 10     10   50 use Scalar::Util 'blessed';
  10         19  
  10         1126  
11 10     10   8109 use namespace::autoclean;
  10         213086  
  10         74  
12              
13             sub new
14             {
15 13     13 1 1831442 my ($class, %opts) = @_;
16              
17 13         97 my $self = {};
18 13 100       155 $self->{_create} = $opts{create} or die 'missing required option: create';
19 12 100       80 $self->{_on_fork} = $opts{on_fork} if exists $opts{on_fork};
20              
21 12         71 $self = bless($self, $class);
22              
23 12 100       134 $self->_create_obj($self->{_create}) if not $opts{lazy};
24              
25 12         50 return $self;
26             }
27              
28             sub _create_obj
29             {
30 15     15   53 my ($self, $sub) = @_;
31              
32 15 100       170 my $obj = $sub->( defined $self->{_obj} ? $self->{_obj} : () );
33 14         650 $self->{_pid} = $$;
34 14 50       85 $self->{_tid} = threads->tid if $INC{'threads.pm'};
35 14         67 $self->{_obj} = $obj;
36             }
37              
38             sub _get_obj
39             {
40 74     74   145 my $self = shift;
41              
42 74 100       593 return if not blessed $self;
43 49 100 100     959 if (not defined $self->{_pid}
      0        
      33        
      66        
44             or $$ != $self->{_pid}
45             or $INC{'threads.pm'} and ($self->{_tid} || 0) != threads->tid)
46             {
47 8   66     218 $self->_create_obj($self->{_on_fork} || $self->{_create});
48             }
49              
50 48         364 return $self->{_obj};
51             }
52              
53             sub isa
54             {
55 23     23 0 45773 my ($self, $class) = @_;
56 23 100       547 $self->SUPER::isa($class) || do {
57 19         76 my $obj = $self->_get_obj;
58 19 100       222 $obj && $obj->isa($class);
59             };
60             }
61              
62             sub can
63             {
64 28     28 0 9086 my ($self, $method) = @_;
65 28 100       439 $self->SUPER::can($method) || do {
66 17         51 my $obj = $self->_get_obj;
67 17 100       226 $obj && $obj->can($method);
68             };
69             }
70              
71             sub VERSION
72             {
73 8     8 0 1748 my ($self, @args) = @_;
74              
75 8         54 my $obj = $self->_get_obj;
76 8 100       275 return $obj
77             ? $obj->VERSION(@args)
78             : $self->SUPER::VERSION(@args);
79             }
80              
81             our $AUTOLOAD;
82             sub AUTOLOAD
83             {
84 30     30   21477 my $self = shift;
85              
86             # Remove qualifier from original method name...
87 30         330 (my $called = $AUTOLOAD) =~ s/.*:://;
88 30         108 return $self->_get_obj->$called(@_);
89             }
90              
91 0     0     sub DESTROY {} # avoid calling AUTOLOAD at destruction time
92              
93             1;
94              
95             __END__