00001 // Copyright (C) 2001, Compaq Computer Corporation 00002 // 00003 // This file is part of Vesta. 00004 // 00005 // Vesta is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // Vesta is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with Vesta; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 // Last modified on Mon May 23 22:33:27 EDT 2005 by ken@xorian.net 00020 // modified on Thu Feb 24 19:21:56 PST 2000 by mann 00021 // modified on Fri Feb 27 18:44:50 PST 1998 by heydon 00022 00023 #include <Basics.H> 00024 #include <BitVector.H> 00025 #include <Debug.H> 00026 00027 #include "Leases.H" 00028 00029 using std::ostream; 00030 using std::cout; 00031 using std::endl; 00032 00033 void* Leases_TimeoutProc(void *arg) throw () 00034 /* REQUIRES Sup(LL) < mu[SELF] */ 00035 /* Repeatedly expire leases every "timeout" seconds. */ 00036 { 00037 Leases *leases = (Leases *)arg; 00038 00039 while (true) { 00040 // block 00041 Basics::thread::pause(leases->timeout, 0); 00042 00043 // expire leases 00044 leases->Expire(); 00045 } 00046 00047 //assert(false); // not reached 00048 //return (void *)NULL; 00049 } 00050 00051 Leases::Leases(Basics::mutex *mu, int timeout, bool debug) throw () 00052 /* REQUIRES *mu IN LL */ 00053 : timeout(timeout), debug(debug), mu(mu), expiring(true) 00054 { 00055 // set object state 00056 this->oldLs = NEW(BitVector); 00057 this->newLs = NEW(BitVector); 00058 00059 // fork and detach background thread 00060 Basics::thread th; 00061 th.fork_and_detach(Leases_TimeoutProc, (void *)this); 00062 } 00063 00064 BitVector *Leases::LeaseSet() const throw () 00065 /* REQUIRES mu[SELF] IN LL */ 00066 { 00067 BitVector *res; 00068 // initialize "res" to copy of "oldLs" 00069 res = NEW_CONSTR(BitVector, (this->oldLs)); 00070 *res |= *(this->newLs); // OR in "newLs" 00071 return res; 00072 } 00073 00074 void Leases::Debug(ostream &os) const throw () 00075 { 00076 os << " new = " << *(this->newLs) << endl; 00077 os << " old = " << *(this->oldLs) << endl; 00078 } 00079 00080 void Leases::Expire() throw () 00081 /* REQUIRES Sup(LL) < mu[SELF] */ 00082 { 00083 BitVector *tempLs; 00084 00085 this->mu->lock(); 00086 if (this->expiring) { 00087 // debugging 00088 if (this->debug) { 00089 Debug::Lock(); 00090 cout << Debug::Timestamp() << "Expiring leases:" << endl; 00091 this->Debug(cout); 00092 cout << endl; 00093 Debug::Unlock(); 00094 } 00095 00096 // Swap old and new, then reset new. This technique 00097 // saves an allocation 00098 tempLs = this->oldLs; 00099 this->oldLs = this->newLs; 00100 this->newLs = tempLs; 00101 this->newLs->ResetAll(); 00102 } 00103 this->mu->unlock(); 00104 }