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 00020 #include <Basics.H> 00021 #include <BitVector.H> 00022 #include <Debug.H> 00023 00024 #include "Leases.H" 00025 00026 using std::ostream; 00027 using OS::cio; 00028 using std::endl; 00029 00030 void* Leases_TimeoutProc(void *arg) throw () 00031 /* REQUIRES Sup(LL) < mu[SELF] */ 00032 /* Repeatedly expire leases every "timeout" seconds. */ 00033 { 00034 Leases *leases = (Leases *)arg; 00035 00036 while (true) { 00037 // block 00038 Basics::thread::pause(leases->timeout, 0); 00039 00040 // expire leases 00041 leases->Expire(); 00042 } 00043 00044 //assert(false); // not reached 00045 //return (void *)NULL; 00046 } 00047 00048 Leases::Leases(Basics::mutex *mu, int timeout, bool debug) throw () 00049 /* REQUIRES *mu IN LL */ 00050 : timeout(timeout), debug(debug), mu(mu), expiring(true) 00051 { 00052 // set object state 00053 this->oldLs = NEW(BitVector); 00054 this->newLs = NEW(BitVector); 00055 00056 // fork and detach background thread 00057 Basics::thread th; 00058 th.fork_and_detach(Leases_TimeoutProc, (void *)this); 00059 } 00060 00061 BitVector *Leases::LeaseSet() const throw () 00062 /* REQUIRES mu[SELF] IN LL */ 00063 { 00064 BitVector *res; 00065 // initialize "res" to copy of "oldLs" 00066 res = NEW_CONSTR(BitVector, (this->oldLs)); 00067 *res |= *(this->newLs); // OR in "newLs" 00068 return res; 00069 } 00070 00071 void Leases::Debug(ostream &os) const throw () 00072 { 00073 os << " new = " << *(this->newLs) << endl; 00074 os << " old = " << *(this->oldLs) << endl; 00075 } 00076 00077 void Leases::Expire() throw () 00078 /* REQUIRES Sup(LL) < mu[SELF] */ 00079 { 00080 BitVector *tempLs; 00081 00082 this->mu->lock(); 00083 if (this->expiring) { 00084 // debugging 00085 if (this->debug) { 00086 ostream& out_stream = cio().start_out(); 00087 out_stream << Debug::Timestamp() << "Expiring leases:" << endl; 00088 this->Debug(out_stream); 00089 out_stream << endl; 00090 cio().end_out(); 00091 } 00092 00093 // Swap old and new, then reset new. This technique 00094 // saves an allocation 00095 tempLs = this->oldLs; 00096 this->oldLs = this->newLs; 00097 this->newLs = tempLs; 00098 this->newLs->ResetAll(); 00099 } 00100 this->mu->unlock(); 00101 }
1.5.1