Here is an example of a call to OpenFile(). You will notice that I'm
additionally locking the file itself as well as the lock file (I figured
it would not hurt to have both methods):
my $LockFileHandle = authlib::FileLock("udata_" . $strRespNum .
"_lck.cgi", 1);
#Read restart question name
my ($DataFileHandle, $blnError) = authlib::OpenFile($strDataFileName,
"update", 1, 1);
authlib::LockMe($DataFileHandle, 1);
authlib::RestartQNameWrite($DataFileHandle, $strRestartQName);
close $DataFileHandle;
close authlib::FileUnLock($LockFileHandle);
And here are the supporting functions:
sub OpenFile
{
my ($strFileName, $strMode, $blnWriteLog, $blnShowError) = @_;
my $FileHandle = Symbol::gensym();
my $strOpenChar = "";
if ($strMode eq "write")
{
$strOpenChar = ">";
}
elsif ($strMode eq "read")
{
$strOpenChar = "<";
}
elsif ($strMode eq "update")
{
$strOpenChar = "+<";
}
elsif ($strMode eq "create_update")
{
$strOpenChar = "+>";
}
elsif ($strMode eq "append")
{
$strOpenChar = ">>";
}
else
{
authlib::ssiDie ("Unrecognized parameter in OpenFile()
with: " . $strFileName, 0, 1);
}
my $blnError = 0;
open $FileHandle, $strOpenChar . $strFileName or eval{$blnError =
1};
if ($blnError)
{
if ($blnShowError)
{
authlib::ssiDie ("Can't open file " .
$strFileName, $!, $blnWriteLog);
}
}
return ($FileHandle, $blnError);
}
#--------------------------------------------------------------
# Marks a file as locked, will not hand out another lock to the same
file until their are no locks on it (unless it is a shared lock in which
case it can hand out multiple shared locks but not an exclusive lock)
#--------------------------------------------------------------
sub LockMe
{
my ($FileHandle, $blnExclusive) = @_;
my $blnFlockSupported = 1;
eval
{
if ($blnExclusive)
{
#Lock for exclusive write access.
flock $FileHandle, 2;
}
else
{
#Lock it as a shared for multiple readers, but
it will not let a writer in.
flock $FileHandle, 1;
}
};
if ($@)
{
$blnFlockSupported = 0;
$authlib::blnGlobalFlockSupported = 0;
}
#Another process might have changed the file position.
seek $FileHandle, 0, 0;
return $blnFlockSupported;
}
#-----------------------------------------------
#
#-----------------------------------------------
sub FileLock
{
my($strFileName, $blnExclusive) = @_;
my $FileHandle = 0;
my $strLockDir = $authlib::GlobalPaths[0] .
$authlib::strGlobalStudyName . "_lockfiles/";
eval
{
$FileHandle = CreateLockFile($strLockDir . $strFileName,
$blnExclusive, 0);
};
if ($@)
{
#If the lock folder has not been created, create it.
my $blnOpenDir = opendir(LOCKDIR, $strLockDir);
closedir TESTDIR;
#If you cannot open the directory (or it does not exist)
if (!$blnOpenDir)
{
$blnOpenDir = mkdir($strLockDir, 0707);
if (!$blnOpenDir)
{
authlib::ssiDie("Can't create lock
directory <i>" . $strLockDir . "</i>", $!, 1);
}
}
$FileHandle = CreateLockFile($strLockDir . $strFileName,
$blnExclusive, 1);
}
return $FileHandle;
}
#-----------------------------------------------
#
#-----------------------------------------------
sub FileUnLock
{
my($LockFileHandle) = @_;
close $LockFileHandle;
#If flock is not supported delete lock file
if ($authlib::blnGlobalFlockSupported == 0)
{
NoFlockUnLock($LockFileHandle);
}
}
#-----------------------------------------------
#
#-----------------------------------------------
sub CreateLockFile
{
my($strLockFile, $blnExclusive, $blnDisplayError) = @_;
my $LockFileHandle = 0;
my $blnError = 0;
if ($blnDisplayError)
{
($LockFileHandle, $blnError) = OpenFile($strLockFile,
"write", 1, 1);
}
else
{
($LockFileHandle, $blnError) = OpenFile($strLockFile,
"write", 0, 0);
if ($blnError)
{
die();
}
}
my $blnFlockSupported = authlib::LockMe($LockFileHandle,
$blnExclusive);
if ($blnFlockSupported == 0)
{
if ($authlib::strGlobalEXT eq ".pl")
{
print authlib::PrintHeader();
print "<h4><u>Error</u>: This system does not
support flock() for file locking. Please call Sawtooth Software.</h4>";
exit();
}
NoFlockLock($LockFileHandle);
}
return($LockFileHandle);
}
-----Original Message-----
From: Dondi M. Stroma [mailto:suppressed
Sent: Friday, April 13, 2007 1:27 PM
To: Justin Luster
Subject: Re: Lock Files - File is permanently locked
What does your call to your OpenFile() sub look like? Since OpenFile
returns a copy of the file handle, the caller of that function will also
need to store it in a lexical variable, too, but you didn't include that
part of your program.
Also, where and how did you declare and define variables such as
"$strOpenChar" and "$strFileName" used in OpenFile()?
----- Original Message -----
From: Justin Luster
To: suppressed
Sent: Friday, April 13, 2007 1:50 PM
Subject: Lock Files - File is permanently locked
Hi,
I've read through some of the documentation on perl.apache.org about
file
locking and mod_perl. I believe that I'm following the advice there but
I'm
still having problems.
...
Does anyone know what might be happening? We are only using
Apache::Registry in this instance. I can't see how a lexically scoped
file
handle that is being locked is not being unlocked once the process ends.
Mail converted by mhonarc 2.6.15
This archive provided courtesy of JSW4.NET, Internet Hosting Services for Small Business.