# ロック関連の設定値
$RetryNum = 100; # リトライ回数
$Interval = 0.1; # リトライのインターバル
$EX_LOCK = 2; # 排他ロック
$UN_LOCK = 8; # ロック解除
$LOCKTYPE = $EX_LOCK; # ロックタイプは排他ロック
$useflock = 0; # flock()を使う場合は1にする
$LPrefix = 'L-'; # ロックファイルのプリフィクス
#
# lock(lfh, lockfile)
# <IN> lfh: ロックファイルのハンドル(openLockで指定されたファイル名
# に等しい。
# lockfile: ロックファイル名
# <OUT> true: 成功 false: 失敗
#
sub lock($$)
{
my($lfh, $lockfile) = @_;
if ($useflock) { # flock()を使う
flock($lfh, $LOCKTYPE);
return 1;
}
else {
my($retry) = $RetryNum;
while (-f $lockfile) {
select(undef, undef, undef, $Interval);
return undef if (--$retry <= 0);
}
return open($lfh, ">$lockfile");
}
}
#
# unlock(lfh, lockfile)
# <IN> lfh: ロックファイルのハンドル(openLockで指定されたファイル名
# に等しい。
# lockfile: ロックファイル名
# <OUT> なし
#
sub unlock ($$)
{
my($lfh, $lockfile) = @_;
if ($useflock) { # flock()を使う
flock($lfh, $UN_LOCK);
}
else {
close($lfh);
unlink($lockfile);
}
}
#
# openLock(fh, modefile)
# <IN> fh: ハンドル
# modefile: モードを含むファイル名
# <OUT> true or false
#
sub openLock(*$)
{
my($fh, $modefile) = @_;
my($lockf);
($mode, $file) = ($modefile =~ /^(\+?(?:<|>>?)\s*?)(.+)$/);
if ($file =~ /(\/|\\)/) {
($path, $filename) = ($file =~ /^(.*[\/|\\])(.+)$/);
}
else {
$path = '';
$filename = $file;
}
return undef unless $filename;
$lockf = $path.$LPrefix."$filename"; # ロックファイル名
lock($filename, $lockf) or return undef;
open($fh, $modefile)
or unlock($filename, $lockf), return undef;
return 1;
}
#
# closeUnlock
# <IN> fh: ハンドル
# modefile: モードを含むファイル名
# <OUT> なし
#
sub closeUnlock(*$)
{
my($fh, $file) = @_;
if ($file =~ /(\/|\\)/) {
($path, $filename) = ($file =~ /^(.*[\/|\\])(.+)$/);
}
else {
$path = '';
$filename = $file;
}
my($lockfile) = $path.'L-'."$filename"; # ロックファイル名
unlock($filename, $lockfile);
close($fh);
}
|