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   516570 use strict;
  10         62  
  10         229  
2 10     10   44 use warnings;
  10         19  
  10         361  
3             package Object::ForkAware; # git description: v0.004-4-g2bf9955
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.005';
9              
10 10     10   49 use Scalar::Util ();
  10         19  
  10         3827  
11              
12             sub new
13             {
14 13     13 1 1028609 my ($class, %opts) = @_;
15              
16 13         47 my $self = {};
17 13 100       105 $self->{_create} = $opts{create} or die 'missing required option: create';
18 12 100       54 $self->{_on_fork} = $opts{on_fork} if exists $opts{on_fork};
19              
20 12         48 $self = bless($self, $class);
21              
22 12 100       79 $self->_create_obj($self->{_create}) if not $opts{lazy};
23              
24 12         39 return $self;
25             }
26              
27             sub _create_obj
28             {
29 15     15   43 my ($self, $sub) = @_;
30              
31 15 100       90 my $obj = $sub->( defined $self->{_obj} ? $self->{_obj} : () );
32 14         257 $self->{_pid} = $$;
33 14 50       51 $self->{_tid} = threads->tid if $INC{'threads.pm'};
34 14         61 $self->{_obj} = $obj;
35             }
36              
37             sub _get_obj
38             {
39 54     54   108 my $self = shift;
40              
41 54 100       252 return if not Scalar::Util::blessed($self);
42 49 100 100     462 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     135 $self->_create_obj($self->{_on_fork} || $self->{_create});
47             }
48              
49 48         222 return $self->{_obj};
50             }
51              
52             sub isa
53             {
54 13     13 0 14887 my ($self, $class) = @_;
55 13 100       394 $self->SUPER::isa($class) || do {
56 9         73 my $obj = $self->_get_obj;
57 9 100       109 $obj && $obj->isa($class);
58             };
59             }
60              
61             sub can
62             {
63 8     8 0 1590 my ($self, $method) = @_;
64 8 100       76 $self->SUPER::can($method) || do {
65 7         42 my $obj = $self->_get_obj;
66 7 100       66 $obj && $obj->can($method);
67             };
68             }
69              
70             sub VERSION
71             {
72 8     8 0 2693 my ($self, @args) = @_;
73              
74 8         41 my $obj = $self->_get_obj;
75 8 100       206 return $obj
76             ? $obj->VERSION(@args)
77             : $self->SUPER::VERSION(@args);
78             }
79              
80             our $AUTOLOAD;
81             sub AUTOLOAD
82             {
83 30     30   12689 my $self = shift;
84              
85             # Remove qualifier from original method name...
86 30         279 (my $called = $AUTOLOAD) =~ s/.*:://;
87 30         104 return $self->_get_obj->$called(@_);
88             }
89              
90       0     sub DESTROY {} # avoid calling AUTOLOAD at destruction time
91              
92             1;
93              
94             __END__