use strict; package Mail::Box::Locker::Multi; use base 'Mail::Box::Locker'; use IO::File; use Carp; =head1 NAME Mail::Box::Locker::Multi - lock a folder in all ways which work =head1 CLASS HIERARCHY Mail::Box::Locker::Multi is a Mail::Box::Locker is a Mail::Reporter =head1 SYNOPSIS See Mail::Box::Locker =head1 DESCRIPTION The C<::Multi> locker locks a folder in each way it can. This way, the chance is highest that any other program will leave the folder alone during our access to it. NFS-lock and Flock are tried. More may be added when the ways to lock are extended. DotLock overlaps with NFS-lock, but NFS-lock is safer, so that version is prefered. =head1 METHOD INDEX Methods prefixed with an abbreviation are described in L<Mail::Reporter> (MR), L<Mail::Box::Locker> (MBL). The general methods for C<Mail::Box::Locker::Multi> objects: MBL DESTROY MBL name MR errors new OPTIONS MBL filename MR report [LEVEL] MBL hasLock MR reportAll [LEVEL] MBL isLocked MR trace [LEVEL] MBL lock FOLDER MBL unlock MR log [LEVEL [,STRINGS]] MR warnings The extra methods for extension writers: MR AUTOLOAD MR logPriority LEVEL MR DESTROY MR logSettings MR inGlobalDestruction MR notImplemented =head1 METHODS =over 4 =cut #------------------------------------------- sub name() {'MULTI'} #------------------------------------------- =item new OPTIONS OPTIONS DESCRIBED IN DEFAULT file Mail::Box::Locker undef log Mail::Reporter 'WARNINGS' method Mail::Box::Locker <not used> timeout Mail::Box::Locker 1 hour trace Mail::Reporter 'WARNINGS' wait Mail::Box::Locker 10 seconds use Mail::Box::Locker::Multi [ 'NFS', 'POSIX', 'Flock' ] =over 4 =item * use =E<gt> ARRAY Array of locker types and locker objects to be used. All types are converted into objects. =over =cut sub init($) { my ($self, $args) = @_; $self->SUPER::init($args); my @use = exists $args->{use} ? @{$args->{use}} : qw/NFS POSIX Flock/; my (@lockers, @used); foreach my $method (@use) { my $locker = eval { Mail::Box::Locker->new ( %$args , method => $method , wait => 1 ) }; next unless defined $locker; push @lockers, $locker; push @used, $method; } $self->{MBLM_lockers} = \@lockers; $self->log(PROGRESS => "Multi-locking via @used."); $self; } #------------------------------------------- =item lockers Returns a list with all locker objects used by this object. =cut sub lockers() { @{shift->{MBLM_lockers}} } #------------------------------------------- sub _try_lock($) { my $self = shift; my @successes; foreach my $locker ($self->lockers) { unless($locker->lock) { $_->unlock foreach @successes; return 0; } push @successes, $locker; } 1; } #------------------------------------------- sub unlock() { my $self = shift; return $self unless $self->{MBL_has_lock}; $_->unlock foreach $self->lockers; delete $self->{MBL_has_lock}; $self; } #------------------------------------------- sub lock() { my $self = shift; return 1 if $self->hasLock; my $end = $self->{MBL_timeout} eq 'NOTIMEOUT' ? -1 : $self->{MBL_timeout}; my $timer = 0; while($timer < $end) { return $self->{MBL_has_lock} = 1 if $self->_try_lock; $timer++; } return 0; } #------------------------------------------- sub isLocked() { my $self = shift; $self->_try_lock($self->filename) or return 0; $self->unlock; 1; } #------------------------------------------- =back =head1 SEE ALSO L<Mail::Box-Overview> =head1 AUTHOR Mark Overmeer (F<mailbox@overmeer.net>). All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 VERSION This code is beta, version 2.010. Copyright (c) 2001 Mark Overmeer. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;