[LON-CAPA-cvs] cvs: loncom / lond
albertel
lon-capa-cvs@mail.lon-capa.org
Tue, 31 Jan 2006 16:12:15 -0000
albertel Tue Jan 31 11:12:15 2006 EDT
Modified files:
/loncom lond
Log:
- BUG#4608 & BUG#4476, lond now should block for up to 13 seconds waiting for lock on a db file
Index: loncom/lond
diff -u loncom/lond:1.312 loncom/lond:1.313
--- loncom/lond:1.312 Tue Jan 31 10:56:46 2006
+++ loncom/lond Tue Jan 31 11:12:12 2006
@@ -2,7 +2,7 @@
# The LearningOnline Network
# lond "LON Daemon" Server (port "LOND" 5663)
#
-# $Id: lond,v 1.312 2006/01/31 15:56:46 albertel Exp $
+# $Id: lond,v 1.313 2006/01/31 16:12:12 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -53,13 +53,15 @@
use LONCAPA::lonlocal;
use LONCAPA::lonssl;
use Fcntl qw(:flock);
+use Symbol;
my $DEBUG = 0; # Non zero to enable debug log entries.
my $status='';
my $lastlog='';
+my $lond_max_wait_time = 13;
-my $VERSION='$Revision: 1.312 $'; #' stupid emacs
+my $VERSION='$Revision: 1.313 $'; #' stupid emacs
my $remoteVERSION;
my $currenthostid="default";
my $currentdomainid;
@@ -972,11 +974,11 @@
my $user_top_dir = $perlvar{'lonUsersDir'};
my $domain_dir = $user_top_dir."/$domain";
my $resource_file = $domain_dir."/$namespace";
- return &_do_hash_tie($resource_file,$namespace,$how,$loghead,$logtail);
+ return &_locking_hash_tie($resource_file,$namespace,$how,$loghead,$logtail);
}
sub untie_domain_hash {
- return &_do_hash_untie(@_);
+ return &_locking_hash_untie(@_);
}
#
# Ties a user's resource file to a hash.
@@ -1005,11 +1007,11 @@
my $proname = propath($domain, $user);
my $file_prefix="$proname/$namespace";
- return &_do_hash_tie($file_prefix,$namespace,$how,$loghead,$what);
+ return &_locking_hash_tie($file_prefix,$namespace,$how,$loghead,$what);
}
sub untie_user_hash {
- return &_do_hash_untie(@_);
+ return &_locking_hash_untie(@_);
}
# internal routines that handle the actual tieing and untieing process
@@ -1041,6 +1043,71 @@
my $result = untie(%$hashref);
return $result;
}
+
+{
+ my $sym;
+
+ sub _locking_hash_tie {
+ my ($file_prefix,$namespace,$how,$loghead,$what) = @_;
+
+ my ($lock);
+
+ if ($how eq &GDBM_READER()) {
+ $lock=LOCK_SH;
+ $how=$how|&GDBM_NOLOCK();
+ #if the db doesn't exist we can't read from it
+ if (! -e "$file_prefix.db") {
+ $! = 2;
+ return undef;
+ }
+ } elsif ($how eq &GDBM_WRCREAT()) {
+ $lock=LOCK_EX;
+ $how=$how|&GDBM_NOLOCK();
+ if (! -e "$file_prefix.db") {
+ # doesn't exist but we need it to in order to successfully
+ # lock it so bring it into existance
+ open(TOUCH,">>$file_prefix.db");
+ close(TOUCH);
+ }
+ } else {
+ &logthis("Unknown method $how for $file_prefix");
+ die();
+ }
+
+ &logthis("$$ for $namespace");
+ $sym=&Symbol::gensym();
+ open($sym,"$file_prefix.db");
+ &logthis("$$ for $namespace attempt lock");
+ my $failed=0;
+ eval {
+ local $SIG{__DIE__}='DEFAULT';
+ local $SIG{ALRM}=sub {
+ $failed=1;
+ die("failed lock");
+ };
+ alarm($lond_max_wait_time);
+ flock($sym,$lock);
+ alarm(0);
+ };
+ if ($failed) {
+ &logthis("$$ for $namespace got failed lock");
+ $! = 100; # throwing error # 100
+ return undef;
+ }
+ &logthis("$$ for $file_prefix.db got lock");
+ return &_do_hash_tie($file_prefix,$namespace,$how,$loghead,$what);
+ }
+
+ sub _locking_hash_untie {
+ my ($hashref) = @_;
+ my $result = untie(%$hashref);
+ flock($sym,LOCK_UN);
+ close($sym);
+ undef($sym);
+ return $result;
+ }
+}
+
# read_profile
#
# Returns a set of specific entries from a user's profile file.