File Coverage

blib/lib/MCE/Mutex.pm
Criterion Covered Total %
statement 22 22 100.0
branch 5 6 83.3
condition 1 2 50.0
subroutine 7 7 100.0
pod 2 2 100.0
total 37 39 94.8


line stmt bran cond sub pod time code
1             ###############################################################################
2             ## ----------------------------------------------------------------------------
3             ## Locking for Many-Core Engine.
4             ##
5             ###############################################################################
6              
7             package MCE::Mutex;
8              
9 106     106   266695 use strict;
  106         203  
  106         2743  
10 106     106   427 use warnings;
  106         169  
  106         2603  
11              
12 106     106   450 no warnings qw( threads recursion uninitialized );
  106         179  
  106         4165  
13              
14             our $VERSION = '1.887';
15              
16             ## no critic (BuiltinFunctions::ProhibitStringyEval)
17             ## no critic (TestingAndDebugging::ProhibitNoStrict)
18              
19 106     106   707 use Carp ();
  106         319  
  106         19181  
20              
21             ## global Mutex used by MCE, MCE::Child, and MCE::Hobo inside threads
22             ## on UNIX platforms
23              
24             if ( $INC{'threads.pm'} && $^O !~ /mswin|mingw|msys|cygwin/i ) {
25             $MCE::_GMUTEX = MCE::Mutex->new( impl => 'Channel' );
26             MCE::Mutex::Channel::_save_for_global_cleanup($MCE::_GMUTEX);
27             }
28              
29             sub new {
30 463     463 1 2573 my ($class, %argv) = @_;
31             my $impl = defined($argv{impl})
32 463 100       1437 ? $argv{impl} : defined($argv{path}) ? 'Flock' : 'Channel';
    100          
33              
34 463         1349 $impl = ucfirst( lc $impl );
35              
36 463 50       22829 eval "require MCE::Mutex::$impl; 1;" ||
37             Carp::croak("Could not load Mutex implementation '$impl': $@");
38              
39 463         1566 my $pkg = 'MCE::Mutex::'.$impl;
40 106     106   637 no strict 'refs';
  106         245  
  106         9774  
41              
42 463         2001 return $pkg->new( %argv );
43             }
44              
45             ## base class method
46              
47             sub impl {
48 5   50 5 1 67 return $_[0]->{impl} || 'Not defined';
49             }
50              
51             1;
52              
53             __END__
54              
55             ###############################################################################
56             ## ----------------------------------------------------------------------------
57             ## Module usage.
58             ##
59             ###############################################################################
60              
61             =head1 NAME
62              
63             MCE::Mutex - Locking for Many-Core Engine
64              
65             =head1 VERSION
66              
67             This document describes MCE::Mutex version 1.887
68              
69             =head1 SYNOPSIS
70              
71             use MCE::Mutex;
72              
73             my $mutex = MCE::Mutex->new;
74              
75             {
76             use MCE::Flow max_workers => 4;
77              
78             mce_flow sub {
79             $mutex->lock;
80              
81             # access shared resource
82             my $wid = MCE->wid; MCE->say($wid); sleep 1;
83              
84             $mutex->unlock;
85             };
86             }
87              
88             {
89             use MCE::Hobo;
90              
91             MCE::Hobo->create('work', $_) for 1..4;
92             MCE::Hobo->waitall;
93             }
94              
95             {
96             use threads;
97              
98             threads->create('work', $_) for 5..8;
99             $_->join for ( threads->list );
100             }
101              
102             sub work {
103             my ($id) = @_;
104             $mutex->lock;
105              
106             # access shared resource
107             print $id, "\n";
108             sleep 1;
109              
110             $mutex->unlock;
111             }
112              
113             =head1 DESCRIPTION
114              
115             This module implements locking methods that can be used to coordinate access
116             to shared data from multiple workers spawned as processes or threads.
117              
118             The inspiration for this module came from reading Mutex for Ruby.
119              
120             =head1 API DOCUMENTATION
121              
122             =head2 MCE::Mutex->new ( )
123              
124             =head2 MCE::Mutex->new ( impl => "Channel" )
125              
126             =head2 MCE::Mutex->new ( impl => "Flock", [ path => "/tmp/file.lock" ] )
127              
128             =head2 MCE::Mutex->new ( path => "/tmp/file.lock" )
129              
130             Creates a new mutex.
131              
132             Channel locking (the default), unless C<path> is given, is through a pipe
133             or socket depending on the platform. The advantage of channel locking is
134             not having to re-establish handles inside new processes and threads.
135              
136             For Fcntl-based locking, it is the responsibility of the caller to remove
137             the C<tempfile>, associated with the mutex, when path is given. Otherwise,
138             it establishes a C<tempfile> internally including removal on scope exit.
139              
140             =head2 $mutex->impl ( void )
141              
142             Returns the implementation used for the mutex.
143              
144             $m1 = MCE::Mutex->new( );
145             $m1->impl(); # Channel
146              
147             $m2 = MCE::Mutex->new( path => /tmp/my.lock );
148             $m2->impl(); # Flock
149              
150             $m3 = MCE::Mutex->new( impl => "Channel" );
151             $m3->impl(); # Channel
152              
153             $m4 = MCE::Mutex->new( impl => "Flock" );
154             $m4->impl(); # Flock
155              
156             Current API available since 1.822.
157              
158             =head2 $mutex->lock ( void )
159              
160             =head2 $mutex->lock_exclusive ( void )
161              
162             Attempts to grab an exclusive lock and waits if not available. Multiple calls
163             to mutex->lock by the same process or thread is safe. The mutex will remain
164             locked until mutex->unlock is called.
165              
166             The method C<lock_exclusive> is an alias for C<lock>, available since 1.822.
167              
168             ( my $mutex = MCE::Mutex->new( path => $0 ) )->lock_exclusive;
169              
170             =head2 $mutex->lock_shared ( void )
171              
172             Like C<lock_exclusive>, but attempts to grab a shared lock instead.
173             The C<lock_shared> method is an alias to C<lock> otherwise for non-Fcntl
174             implementations.
175              
176             Current API available since 1.822.
177              
178             =head2 $mutex->unlock ( void )
179              
180             Releases the lock. A held lock by an exiting process or thread is released
181             automatically.
182              
183             =head2 $mutex->synchronize ( sub { ... }, @_ )
184              
185             =head2 $mutex->enter ( sub { ... }, @_ )
186              
187             Obtains a lock, runs the code block, and releases the lock after the block
188             completes. Optionally, the method is C<wantarray> aware.
189              
190             my $val = $mutex->synchronize( sub {
191             # access shared resource
192             return 'scalar';
193             });
194              
195             my @ret = $mutex->enter( sub {
196             # access shared resource
197             return @list;
198             });
199              
200             The method C<enter> is an alias for C<synchronize>, available since 1.822.
201              
202             =head2 $mutex->timedwait ( floating_seconds )
203              
204             Blocks until obtaining an exclusive lock. A false value is returned
205             if the timeout is reached, and a true value otherwise. The default is
206             1 second.
207              
208             my $mutex = MCE::Mutex->new( path => $0 );
209              
210             # terminate script if a previous instance is still running
211              
212             exit unless $mutex->timedwait( 2 );
213              
214             ...
215              
216             Current API available since 1.822.
217              
218             =head1 INDEX
219              
220             L<MCE|MCE>, L<MCE::Core>
221              
222             =head1 AUTHOR
223              
224             Mario E. Roy, S<E<lt>marioeroy AT gmail DOT comE<gt>>
225              
226             =cut
227