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:[EMAIL PROTECTED] 
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: [EMAIL PROTECTED]
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.




Reply via email to