[LON-CAPA-cvs] cvs: loncom(version_2_1_X) / lond
albertel
lon-capa-cvs@mail.lon-capa.org
Thu, 02 Feb 2006 10:32:32 -0000
This is a MIME encoded message
--albertel1138876352
Content-Type: text/plain
albertel Thu Feb 2 05:32:32 2006 EDT
Modified files: (Branch: version_2_1_X)
/loncom lond
Log:
- backport 1.309,310,311,312,313,314,315,316
--albertel1138876352
Content-Type: text/plain
Content-Disposition: attachment; filename="albertel-20060202053232.txt"
Index: loncom/lond
diff -u loncom/lond:1.305.2.1 loncom/lond:1.305.2.2
--- loncom/lond:1.305.2.1 Fri Jan 27 18:05:30 2006
+++ loncom/lond Thu Feb 2 05:32:31 2006
@@ -2,7 +2,7 @@
# The LearningOnline Network
# lond "LON Daemon" Server (port "LOND" 5663)
#
-# $Id: lond,v 1.305.2.1 2006/01/27 23:05:30 albertel Exp $
+# $Id: lond,v 1.305.2.2 2006/02/02 10:32:31 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.305.2.1 $'; #' stupid emacs
+my $VERSION='$Revision: 1.305.2.2 $'; #' stupid emacs
my $remoteVERSION;
my $currenthostid="default";
my $currentdomainid;
@@ -970,23 +972,13 @@
my $user_top_dir = $perlvar{'lonUsersDir'};
my $domain_dir = $user_top_dir."/$domain";
- my $resource_file = $domain_dir."/$namespace.db";
- my %hash;
- if(tie(%hash, 'GDBM_File', $resource_file, $how, 0640)) {
- if (defined($loghead)) { # Need to log the operation.
- my $logFh = IO::File->new(">>$domain_dir/$namespace.hist");
- if($logFh) {
- my $timestamp = time;
- print $logFh "$loghead:$timestamp:$logtail\n";
- }
- $logFh->close;
- }
- return \%hash; # Return the tied hash.
- } else {
- return undef; # Tie failed.
- }
+ my $resource_file = $domain_dir."/$namespace";
+ return &_locking_hash_tie($resource_file,$namespace,$how,$loghead,$logtail);
}
+sub untie_domain_hash {
+ return &_locking_hash_untie(@_);
+}
#
# Ties a user's resource file to a hash.
# If necessary, an appropriate history
@@ -1012,18 +1004,27 @@
$namespace=~s/\//\_/g; # / -> _
$namespace=~s/\W//g; # whitespace eliminated.
my $proname = propath($domain, $user);
-
- # Tie the database.
-
+
+ my $file_prefix="$proname/$namespace";
+ return &_locking_hash_tie($file_prefix,$namespace,$how,$loghead,$what);
+}
+
+sub untie_user_hash {
+ return &_locking_hash_untie(@_);
+}
+
+# internal routines that handle the actual tieing and untieing process
+
+sub _do_hash_tie {
+ my ($file_prefix,$namespace,$how,$loghead,$what) = @_;
my %hash;
- if(tie(%hash, 'GDBM_File', "$proname/$namespace.db",
- $how, 0640)) {
+ if(tie(%hash, 'GDBM_File', "$file_prefix.db", $how, 0640)) {
# If this is a namespace for which a history is kept,
# make the history log entry:
if (($namespace !~/^nohist\_/) && (defined($loghead))) {
my $args = scalar @_;
- Debug(" Opening history: $namespace $args");
- my $hfh = IO::File->new(">>$proname/$namespace.hist");
+ Debug(" Opening history: $file_prefix $args");
+ my $hfh = IO::File->new(">>$file_prefix.hist");
if($hfh) {
my $now = time;
print $hfh "$loghead:$now:$what\n";
@@ -1034,7 +1035,72 @@
} else {
return undef;
}
+}
+
+sub _do_hash_untie {
+ my ($hashref) = @_;
+ 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();
+ }
+ $sym=&Symbol::gensym();
+ open($sym,"$file_prefix.db");
+ 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) {
+ $! = 100; # throwing error # 100
+ return undef;
+ }
+ 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
@@ -1067,7 +1133,7 @@
$qresult.="$hashref->{$queries[$i]}&"; # Presumably failure gives empty string.
}
$qresult=~s/\&$//; # Remove trailing & from last lookup.
- if (untie %$hashref) {
+ if (&untie_user_hash($hashref)) {
return $qresult;
} else {
return "error: ".($!+0)." untie (GDBM) Failed";
@@ -2376,7 +2442,7 @@
my ($key,$value)=split(/=/,$pair);
$hashref->{$key}=$value;
}
- if (untie(%$hashref)) {
+ if (&untie_user_hash($hashref)) {
&Reply( $client, "ok\n", $userinput);
} else {
&Failure($client, "error: ".($!+0)." untie(GDBM) failed ".
@@ -2384,7 +2450,7 @@
$userinput);
}
} else {
- &Failure( $client, "error: ".($!)." tie(GDBM) Failed ".
+ &Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ".
"while attempting put\n", $userinput);
}
} else {
@@ -2420,7 +2486,7 @@
my $hashref = &tie_user_hash($udom, $uname, $namespace,
&GDBM_WRCREAT(),"N",$what);
if(!$hashref) {
- &Failure( $client, "error: ".($!)." tie(GDBM) Failed ".
+ &Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ".
"while attempting put\n", $userinput);
return 1;
}
@@ -2439,7 +2505,7 @@
$hashref->{$key}=$value;
}
- if (untie(%$hashref)) {
+ if (&untie_user_hash($hashref)) {
&Reply( $client, "ok\n", $userinput);
} else {
&Failure($client, "error: ".($!+0)." untie(GDBM) failed ".
@@ -2492,7 +2558,7 @@
}
}
}
- if (untie(%$hashref)) {
+ if (&untie_user_hash($hashref)) {
&Reply( $client, "ok\n", $userinput);
} else {
&Failure($client, "error: ".($!+0)." untie(GDBM) failed ".
@@ -2559,7 +2625,7 @@
$auth_type);
$hashref->{$key}=$value;
}
- if (untie($hashref)) {
+ if (&untie_user_hash($hashref)) {
&Reply($client, "ok\n", $userinput);
} else {
&Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ".
@@ -2610,7 +2676,7 @@
foreach my $key (@rolekeys) {
delete $hashref->{$key};
}
- if (untie(%$hashref)) {
+ if (&untie_user_hash($hashref)) {
&Reply($client, "ok\n", $userinput);
} else {
&Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ".
@@ -2751,7 +2817,7 @@
foreach my $key (@keys) {
delete($hashref->{$key});
}
- if (untie(%$hashref)) {
+ if (&untie_user_hash($hashref)) {
&Reply($client, "ok\n", $userinput);
} else {
&Failure($client, "error: ".($!+0)." untie(GDBM) Failed ".
@@ -2793,7 +2859,7 @@
foreach my $key (keys %$hashref) {
$qresult.="$key&";
}
- if (untie(%$hashref)) {
+ if (&untie_user_hash($hashref)) {
$qresult=~s/\&$//;
&Reply($client, "$qresult\n", $userinput);
} else {
@@ -2854,7 +2920,7 @@
$data{$symb}->{$param}=$value;
$data{$symb}->{'v.'.$param}=$v;
}
- if (untie(%$hashref)) {
+ if (&untie_user_hash($hashref)) {
while (my ($symb,$param_hash) = each(%data)) {
while(my ($param,$value) = each (%$param_hash)){
next if ($param =~ /^v\./); # Ignore versions...
@@ -2929,7 +2995,7 @@
}
}
}
- if (untie(%$hashref)) {
+ if (&untie_user_hash($hashref)) {
chop($qresult);
&Reply($client, "$qresult\n", $userinput);
} else {
@@ -2991,7 +3057,7 @@
$hashref->{"$version:$rid:timestamp"}=$now;
$allkeys.='timestamp';
$hashref->{"$version:keys:$rid"}=$allkeys;
- if (untie($hashref)) {
+ if (&untie_user_hash($hashref)) {
&Reply($client, "ok\n", $userinput);
} else {
&Failure($client, "error: ".($!+0)." untie(GDBM) Failed ".
@@ -3043,24 +3109,22 @@
$namespace=~s/\//\_/g;
$namespace=~s/\W//g;
chomp($rid);
- my $proname=&propath($udom,$uname);
my $qresult='';
- my %hash;
- if (tie(%hash,'GDBM_File',"$proname/$namespace.db",
- &GDBM_READER(),0640)) {
- my $version=$hash{"version:$rid"};
+ my $hashref = &tie_user_hash($udom, $uname, $namespace, &GDBM_READER());
+ if ($hashref) {
+ my $version=$hashref->{"version:$rid"};
$qresult.="version=$version&";
my $scope;
for ($scope=1;$scope<=$version;$scope++) {
- my $vkeys=$hash{"$scope:keys:$rid"};
+ my $vkeys=$hashref->{"$scope:keys:$rid"};
my @keys=split(/:/,$vkeys);
my $key;
$qresult.="$scope:keys=$vkeys&";
foreach $key (@keys) {
- $qresult.="$scope:$key=".$hash{"$scope:$rid:$key"}."&";
+ $qresult.="$scope:$key=".$hashref->{"$scope:$rid:$key"}."&";
}
}
- if (untie(%hash)) {
+ if (&untie_user_hash($hashref)) {
$qresult=~s/\&$//;
&Reply( $client, "$qresult\n", $userinput);
} else {
@@ -3293,7 +3357,7 @@
}
$hashref->{$key}=$courseinfo.':'.$now;
}
- if (untie(%$hashref)) {
+ if (&untie_domain_hash($hashref)) {
&Reply( $client, "ok\n", $userinput);
} else {
&Failure($client, "error: ".($!+0)
@@ -3409,7 +3473,7 @@
$qresult.=$key.'='.$descr.':'.$inst_code.':'.$owner.'&';
}
}
- if (untie(%$hashref)) {
+ if (&untie_domain_hash($hashref)) {
chop($qresult);
&Reply($client, "$qresult\n", $userinput);
} else {
@@ -3458,7 +3522,7 @@
my ($key,$value)=split(/=/,$pair);
$hashref->{$key}=$value;
}
- if (untie(%$hashref)) {
+ if (&untie_domain_hash($hashref)) {
&Reply($client, "ok\n", $userinput);
} else {
&Failure($client, "error: ".($!+0)." untie(GDBM) Failed ".
@@ -3507,7 +3571,7 @@
for (my $i=0;$i<=$#queries;$i++) {
$qresult.="$hashref->{$queries[$i]}&";
}
- if (untie(%$hashref)) {
+ if (&untie_domain_hash($hashref)) {
$qresult=~s/\&$//;
&Reply($client, "$qresult\n", $userinput);
} else {
@@ -3551,7 +3615,7 @@
my ($key,$value)=split(/=/,$what);
$hashref->{$key}=$value;
}
- if (untie(%$hashref)) {
+ if (&untie_domain_hash($hashref)) {
&Reply($client, "ok\n", $userinput);
} else {
&Failure($client, "error: ".($!+0)." untie(GDBM) Failed ".
@@ -3631,7 +3695,7 @@
$qresult.=$key.'='.$value.'&';
}
}
- if (untie(%$hashref)) {
+ if (&untie_domain_hash($hashref)) {
chop($qresult);
&Reply($client, "$qresult\n", $userinput);
} else {
@@ -3678,7 +3742,7 @@
my ($key,$value)=split(/=/,$pair);
$hashref->{$key}=$value;
}
- if (untie(%$hashref)) {
+ if (&untie_domain_hash($hashref)) {
&Reply($client, "ok\n", $userinput);
} else {
&Failure($client, "error: ".($!+0)." untie(GDBM) Failed ".
@@ -3759,7 +3823,7 @@
$qresult.=$key.'='.$value.'&';
}
}
- if (untie(%$hashref)) {
+ if (&untie_domain_hash($hashref)) {
chop($qresult);
&Reply($client, "$qresult\n", $userinput);
} else {
@@ -5606,38 +5670,38 @@
sub get_chat {
my ($cdom,$cname,$udom,$uname)=@_;
- my %hash;
- my $proname=&propath($cdom,$cname);
+
my @entries=();
- if (tie(%hash,'GDBM_File',"$proname/nohist_chatroom.db",
- &GDBM_READER(),0640)) {
- @entries=map { $_.':'.$hash{$_} } sort keys %hash;
- untie %hash;
+ my $hashref = &tie_user_hash($cdom, $cname, 'nohist_chatroom',
+ &GDBM_READER());
+ if ($hashref) {
+ @entries=map { $_.':'.$hashref->{$_} } sort(keys(%$hashref));
+ &untie_user_hash($hashref);
}
my @participants=();
my $cutoff=time-60;
- if (tie(%hash,'GDBM_File',"$proname/nohist_inchatroom.db",
- &GDBM_WRCREAT(),0640)) {
- $hash{$uname.':'.$udom}=time;
- foreach (sort keys %hash) {
- if ($hash{$_}>$cutoff) {
- $participants[$#participants+1]='active_participant:'.$_;
+ $hashref = &tie_user_hash($cdom, $cname, 'nohist_inchatroom',
+ &GDBM_WRCREAT());
+ if ($hashref) {
+ $hashref->{$uname.':'.$udom}=time;
+ foreach my $user (sort(keys(%$hashref))) {
+ if ($hashref->{$user}>$cutoff) {
+ push(@participants, 'active_participant:'.$user);
}
}
- untie %hash;
+ &untie_user_hash($hashref);
}
return (@participants,@entries);
}
sub chat_add {
my ($cdom,$cname,$newchat)=@_;
- my %hash;
- my $proname=&propath($cdom,$cname);
my @entries=();
my $time=time;
- if (tie(%hash,'GDBM_File',"$proname/nohist_chatroom.db",
- &GDBM_WRCREAT(),0640)) {
- @entries=map { $_.':'.$hash{$_} } sort keys %hash;
+ my $hashref = &tie_user_hash($cdom, $cname, 'nohist_chatroom',
+ &GDBM_WRCREAT());
+ if ($hashref) {
+ @entries=map { $_.':'.$hashref->{$_} } sort(keys(%$hashref));
my ($lastid)=($entries[$#entries]=~/^(\w+)\:/);
my ($thentime,$idnum)=split(/\_/,$lastid);
my $newid=$time.'_000000';
@@ -5647,21 +5711,22 @@
$idnum=substr('000000'.$idnum,-6,6);
$newid=$time.'_'.$idnum;
}
- $hash{$newid}=$newchat;
+ $hashref->{$newid}=$newchat;
my $expired=$time-3600;
- foreach (keys %hash) {
- my ($thistime)=($_=~/(\d+)\_/);
+ foreach my $comment (keys(%$hashref)) {
+ my ($thistime) = ($comment=~/(\d+)\_/);
if ($thistime<$expired) {
- delete $hash{$_};
+ delete $hashref->{$comment};
}
}
- untie %hash;
- }
- {
- my $hfh;
- if ($hfh=IO::File->new(">>$proname/chatroom.log")) {
- print $hfh "$time:".&unescape($newchat)."\n";
+ {
+ my $proname=&propath($cdom,$cname);
+ if (open(CHATLOG,">>$proname/chatroom.log")) {
+ print CHATLOG ("$time:".&unescape($newchat)."\n");
+ }
+ close(CHATLOG);
}
+ &untie_user_hash($hashref);
}
}
--albertel1138876352--