File Coverage

blib/lib/Object/ForkAware.pm
Criterion Covered Total %
statement 40 40 100.0
branch 23 24 95.8
condition 8 14 57.1
subroutine 10 11 90.9
pod 1 4 25.0
total 82 93 88.1


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