Keef emailed me and I sent him this, if any one else has this probs heres the solution.
I used this piece of code below to create
a lockfile, when the lockfile exists no other routine can open the data file
(or whatever file you are opening) until the lock is released. Requests will
que and be dealt with in turn.
To create the lockfile use-
$lock_file = "path to a directory for lock files/lock.file";
at the top of your script where the globals are and create the directory-
then-
&GetFileLock ("$lock_file");
before the part of your routine that opens the file, and release the lock
file with-
&ReleaseFileLock ("$lock_file");
after the the file has been closed.
You will need to paste the following two
subroutines as is into the file where this is taking place, they can go at
the end.
# SUB GETFILELOCK #
# This subroutine gets a lock file so that a file can only be modified
# by one user at a time. This is to prevent data mixing. If you want
# to use flock, uncomment that line. We only wait for 60 seconds if
# there is a lock file already in place, at which point we take over,
# assuming the old lock file is from a previous hang.
sub GetFileLock {
my ($lock_file) = $_[0];
my ($endtime) = 60;
$endtime = time + $endtime;
while (-e $lock_file && time < $endtime) { sleep( 2 ); }
open(LOCK_FILE, ">$lock_file");
# flock(LOCK_FILE, 2);
}
# SUB RELEASEFILELOCK #
# This subroutine removes the passed lock file to free up a file
# for further editing. If you want to use flock, uncomment that line.
sub ReleaseFileLock {
my ($lock_file) = $_[0];
# flock(LOCK_FILE, 8);
close(LOCK_FILE);
unlink($lock_file);
}
P.S.
With the two subroutines it should be possible for
you to ensure corruption does not occur with any programme you
use by including them in the script if flock is not available, as on network
file systems where the cgi server is a different machine to the webserver.
Hope that helps.
chmod
>> instruct for dbman,
nice and easy, here`s how you implement it.
Copy both the sub routines to the bottom of db.cgi.
Then in default.cfg , below-
# Full path and file name of the html routines.
require $db_script_path . "/html.pl";
place-
# Full path to a lockfile.
$lock_file = $db_script_path . "/lock/lock.file";
and create a directory called lock with read and write permissions alongside
where your script is.
This directory is where your lockfiles will be created, then deleted.
Then for example in db.cgi in sub add_record where it says-
if ($status eq "ok") {
open (DB, ">>$db_file_name") or &cgierr("error in add_record. unable to
open database: $db_file_name.\nReason: $!");
if ($db_use_flock) {
flock(DB, 2) or &cgierr("unable to get exclusive lock on
$db_file_name.\nReason: $!");
}
print DB &join_encode(%in);
close DB; # automatically removes file lock
Place-
&GetFileLock ("$lock_file");
before it-
and-
&ReleaseFileLock ("$lock_file");
after it-
You will need to do this for every instance of a file being opened and
written to, like the counter file, log file if u are using it, and within
the modify and delete sub routines in db.cgi (for testing just put it in the
sub add_record as above)
The lockfile will not allow another operation until it is deleted by
&ReleaseFileLock, which should be real quick (less than a second), but if
there is a hang the lockfile will be ignored after 60 seconds, you can
change this timeout in the sub GetFileLock
You can test it by not including the &ReleaseFileLock ("$lock_file"); above
then adding a record and trying to add another record straight away, the
programme will wait for 60 seconds before going ahead.
chmod
I used this piece of code below to create
a lockfile, when the lockfile exists no other routine can open the data file
(or whatever file you are opening) until the lock is released. Requests will
que and be dealt with in turn.
To create the lockfile use-
$lock_file = "path to a directory for lock files/lock.file";
at the top of your script where the globals are and create the directory-
then-
&GetFileLock ("$lock_file");
before the part of your routine that opens the file, and release the lock
file with-
&ReleaseFileLock ("$lock_file");
after the the file has been closed.
You will need to paste the following two
subroutines as is into the file where this is taking place, they can go at
the end.
# SUB GETFILELOCK #
# This subroutine gets a lock file so that a file can only be modified
# by one user at a time. This is to prevent data mixing. If you want
# to use flock, uncomment that line. We only wait for 60 seconds if
# there is a lock file already in place, at which point we take over,
# assuming the old lock file is from a previous hang.
sub GetFileLock {
my ($lock_file) = $_[0];
my ($endtime) = 60;
$endtime = time + $endtime;
while (-e $lock_file && time < $endtime) { sleep( 2 ); }
open(LOCK_FILE, ">$lock_file");
# flock(LOCK_FILE, 2);
}
# SUB RELEASEFILELOCK #
# This subroutine removes the passed lock file to free up a file
# for further editing. If you want to use flock, uncomment that line.
sub ReleaseFileLock {
my ($lock_file) = $_[0];
# flock(LOCK_FILE, 8);
close(LOCK_FILE);
unlink($lock_file);
}
P.S.
With the two subroutines it should be possible for
you to ensure corruption does not occur with any programme you
use by including them in the script if flock is not available, as on network
file systems where the cgi server is a different machine to the webserver.
Hope that helps.
chmod
>> instruct for dbman,
nice and easy, here`s how you implement it.
Copy both the sub routines to the bottom of db.cgi.
Then in default.cfg , below-
# Full path and file name of the html routines.
require $db_script_path . "/html.pl";
place-
# Full path to a lockfile.
$lock_file = $db_script_path . "/lock/lock.file";
and create a directory called lock with read and write permissions alongside
where your script is.
This directory is where your lockfiles will be created, then deleted.
Then for example in db.cgi in sub add_record where it says-
if ($status eq "ok") {
open (DB, ">>$db_file_name") or &cgierr("error in add_record. unable to
open database: $db_file_name.\nReason: $!");
if ($db_use_flock) {
flock(DB, 2) or &cgierr("unable to get exclusive lock on
$db_file_name.\nReason: $!");
}
print DB &join_encode(%in);
close DB; # automatically removes file lock
Place-
&GetFileLock ("$lock_file");
before it-
and-
&ReleaseFileLock ("$lock_file");
after it-
You will need to do this for every instance of a file being opened and
written to, like the counter file, log file if u are using it, and within
the modify and delete sub routines in db.cgi (for testing just put it in the
sub add_record as above)
The lockfile will not allow another operation until it is deleted by
&ReleaseFileLock, which should be real quick (less than a second), but if
there is a hang the lockfile will be ignored after 60 seconds, you can
change this timeout in the sub GetFileLock
You can test it by not including the &ReleaseFileLock ("$lock_file"); above
then adding a record and trying to add another record straight away, the
programme will wait for 60 seconds before going ahead.
chmod