File Coverage

blib/lib/MCE/Mutex/Channel2.pm
Criterion Covered Total %
statement 45 69 65.2
branch 10 48 20.8
condition 2 9 22.2
subroutine 12 16 75.0
pod 5 5 100.0
total 74 147 50.3


line stmt bran cond sub pod time code
1             ###############################################################################
2             ## ----------------------------------------------------------------------------
3             ## MCE::Mutex::Channel2 - Provides two mutexes using a single channel.
4             ##
5             ###############################################################################
6              
7             package MCE::Mutex::Channel2;
8              
9 17     17   90 use strict;
  17         42  
  17         415  
10 17     17   67 use warnings;
  17         33  
  17         442  
11              
12 17     17   70 no warnings qw( threads recursion uninitialized once );
  17         34  
  17         1100  
13              
14             our $VERSION = '1.887';
15              
16 17     17   878 use if $^O eq 'MSWin32', 'threads';
  17         41  
  17         125  
17 17     17   1277 use if $^O eq 'MSWin32', 'threads::shared';
  17         24  
  17         93  
18              
19 17     17   516 use base 'MCE::Mutex::Channel';
  17         32  
  17         11244  
20 17     17   98 use MCE::Util ();
  17         34  
  17         242  
21 17     17   66 use Scalar::Util 'looks_like_number';
  17         30  
  17         598  
22 17     17   68 use Time::HiRes 'alarm';
  17         23  
  17         65  
23              
24             my $is_MSWin32 = ($^O eq 'MSWin32') ? 1 : 0;
25             my $tid = $INC{'threads.pm'} ? threads->tid() : 0;
26              
27             sub CLONE {
28 0 0   0   0 $tid = threads->tid() if $INC{'threads.pm'};
29             }
30              
31             ###############################################################################
32             ## ----------------------------------------------------------------------------
33             ## Public methods.
34             ##
35             ###############################################################################
36              
37             sub new {
38 30     30 1 109 my ($class, %obj) = (@_, impl => 'Channel2');
39 30 50       115 $obj{_init_pid} = $tid ? $$ .'.'. $tid : $$;
40 30 50       65 $obj{_t_lock} = threads::shared::share( my $t_lock ) if $is_MSWin32;
41 30 50       72 $obj{_t_lock2} = threads::shared::share( my $t_lock2 ) if $is_MSWin32;
42              
43 30         92 MCE::Util::_sock_pair(\%obj, qw(_r_sock _w_sock), undef, 1);
44              
45 30         528 CORE::syswrite($obj{_w_sock}, '0');
46 30         270 CORE::syswrite($obj{_r_sock}, '0');
47 30         123 bless \%obj, $class;
48              
49 30 100 66     277 if ( caller !~ /^MCE:?/ || caller(1) !~ /^MCE:?/ ) {
50 1         4 MCE::Mutex::Channel::_save_for_global_cleanup(\%obj);
51             }
52              
53 30         140 return \%obj;
54             }
55              
56             sub lock2 {
57 94 50   94 1 470 my ($pid, $obj) = ($tid ? $$ .'.'. $tid : $$, shift);
58              
59             CORE::lock($obj->{_t_lock2}), MCE::Util::_sock_ready($obj->{_w_sock})
60 94 50       422 if $is_MSWin32;
61             MCE::Util::_sysread($obj->{_w_sock}, my($b), 1), $obj->{ $pid.'b' } = 1
62 94 50       997 unless $obj->{ $pid.'b' };
63              
64 94         282 return;
65             }
66              
67             *lock_exclusive2 = \&lock2;
68             *lock_shared2 = \&lock2;
69              
70             sub unlock2 {
71 94 50   94 1 558 my ($pid, $obj) = ($tid ? $$ .'.'. $tid : $$, shift);
72              
73             CORE::syswrite($obj->{_r_sock}, '0'), $obj->{ $pid.'b' } = 0
74 94 50       966 if $obj->{ $pid.'b' };
75              
76 94         308 return;
77             }
78              
79             sub synchronize2 {
80 0 0   0 1   my ($pid, $obj, $code) = ($tid ? $$ .'.'. $tid : $$, shift, shift);
81 0           my (@ret, $b);
82              
83 0 0         return unless ref($code) eq 'CODE';
84              
85             # lock, run, unlock - inlined for performance
86             CORE::lock($obj->{_t_lock2}), MCE::Util::_sock_ready($obj->{_w_sock})
87 0 0         if $is_MSWin32;
88             MCE::Util::_sysread($obj->{_w_sock}, $b, 1), $obj->{ $pid.'b' } = 1
89 0 0         unless $obj->{ $pid.'b' };
90              
91             (defined wantarray)
92 0 0         ? @ret = wantarray ? $code->(@_) : scalar $code->(@_)
    0          
93             : $code->(@_);
94              
95 0           CORE::syswrite($obj->{_r_sock}, '0'), $obj->{ $pid.'b' } = 0;
96              
97 0 0         return wantarray ? @ret : $ret[-1];
98             }
99              
100             *enter2 = \&synchronize2;
101              
102             sub timedwait2 {
103 0     0 1   my ($obj, $timeout) = @_;
104              
105 0 0         $timeout = 1 unless defined $timeout;
106 0 0 0       Carp::croak('MCE::Mutex::Channel2: timedwait2 (timeout) is not valid')
107             if (!looks_like_number($timeout) || $timeout < 0);
108              
109 0 0         $timeout = 0.0003 if $timeout < 0.0003;
110 0           local $@; my $ret = '';
  0            
111              
112 0           eval {
113 0     0     local $SIG{ALRM} = sub { alarm 0; die "alarm clock restart\n" };
  0            
  0            
114 0 0         alarm $timeout unless $is_MSWin32;
115              
116             die "alarm clock restart\n"
117 0 0 0       if $is_MSWin32 && MCE::Util::_sock_ready($obj->{_w_sock}, $timeout);
118              
119 0 0         (!$is_MSWin32)
120             ? ($obj->lock_exclusive2, $ret = 1, alarm(0))
121             : ($obj->lock_exclusive2, $ret = 1);
122             };
123              
124 0 0         alarm 0 unless $is_MSWin32;
125              
126 0           $ret;
127             }
128              
129             1;
130              
131             __END__
132              
133             ###############################################################################
134             ## ----------------------------------------------------------------------------
135             ## Module usage.
136             ##
137             ###############################################################################
138              
139             =head1 NAME
140              
141             MCE::Mutex::Channel2 - Provides two mutexes using a single channel
142              
143             =head1 VERSION
144              
145             This document describes MCE::Mutex::Channel2 version 1.887
146              
147             =head1 DESCRIPTION
148              
149             A socket implementation based on C<MCE::Mutex>. The secondary lock is accessed
150             by calling methods with the C<2> suffix.
151              
152             The API is described in L<MCE::Mutex>.
153              
154             =head2 construction
155              
156             =over 3
157              
158             =item new
159              
160             my $mutex = MCE::Mutex->new( impl => 'Channel2' );
161              
162             =back
163              
164             =head2 primary lock
165              
166             =over 3
167              
168             =item lock
169              
170             =item lock_exclusive
171              
172             =item lock_shared
173              
174             =item unlock
175              
176             =item synchronize
177              
178             =item enter
179              
180             =item timedwait
181              
182             =back
183              
184             =head2 secondary lock
185              
186             =over 3
187              
188             =item lock2
189              
190             =item lock_exclusive2
191              
192             =item lock_shared2
193              
194             =item unlock2
195              
196             =item synchronize2
197              
198             =item enter2
199              
200             =item timedwait2
201              
202             =back
203              
204             =head1 AUTHOR
205              
206             Mario E. Roy, S<E<lt>marioeroy AT gmail DOT comE<gt>>
207              
208             =cut
209