|
reSIProcate/DialogUsageManager
9694
|
00001 #include <ctime> 00002 00003 #include "resip/dum/InMemoryRegistrationDatabase.hxx" 00004 #include "rutil/Timer.hxx" 00005 #include "rutil/Logger.hxx" 00006 #include "rutil/WinLeakCheck.hxx" 00007 00008 using namespace resip; 00009 00010 #define RESIPROCATE_SUBSYSTEM Subsystem::DUM 00011 00012 InMemoryRegistrationDatabase::InMemoryRegistrationDatabase(bool checkExpiry) : 00013 mCheckExpiry(checkExpiry) 00014 { 00015 } 00016 00017 InMemoryRegistrationDatabase::~InMemoryRegistrationDatabase() 00018 { 00019 for( database_map_t::const_iterator it = mDatabase.begin(); 00020 it != mDatabase.end(); it++) 00021 { 00022 delete it->second; 00023 } 00024 mDatabase.clear(); 00025 } 00026 00027 void 00028 InMemoryRegistrationDatabase::addAor(const Uri& aor, 00029 const ContactList& contacts) 00030 { 00031 Lock g(mDatabaseMutex); 00032 mDatabase[aor] = new ContactList(contacts); 00033 } 00034 00035 void 00036 InMemoryRegistrationDatabase::removeAor(const Uri& aor) 00037 { 00038 database_map_t::iterator i; 00039 00040 Lock g(mDatabaseMutex); 00041 i = mDatabase.find(aor); 00042 //DebugLog (<< "Removing registration bindings " << aor); 00043 if (i != mDatabase.end()) 00044 { 00045 if (i->second) 00046 { 00047 DebugLog (<< "Removed " << i->second->size() << " entries"); 00048 delete i->second; 00049 // Setting this to 0 causes it to be removed when we unlock the AOR. 00050 i->second = 0; 00051 } 00052 } 00053 } 00054 00055 void 00056 InMemoryRegistrationDatabase::getAors(InMemoryRegistrationDatabase::UriList& container) 00057 { 00058 container.clear(); 00059 Lock g(mDatabaseMutex); 00060 for( database_map_t::const_iterator it = mDatabase.begin(); 00061 it != mDatabase.end(); it++) 00062 { 00063 container.push_back(it->first); 00064 } 00065 } 00066 00067 bool 00068 InMemoryRegistrationDatabase::aorIsRegistered(const Uri& aor) 00069 { 00070 Lock g(mDatabaseMutex); 00071 database_map_t::iterator i = findNotExpired(aor); 00072 if (i == mDatabase.end() || i->second == 0) 00073 { 00074 return false; 00075 } 00076 return true; 00077 } 00078 00079 void 00080 InMemoryRegistrationDatabase::lockRecord(const Uri& aor) 00081 { 00082 Lock g2(mLockedRecordsMutex); 00083 00084 { 00085 Lock g1(mDatabaseMutex); 00086 // This forces insertion if the record does not yet exist. 00087 mDatabase[aor]; 00088 } 00089 00090 while (mLockedRecords.count(aor)) 00091 { 00092 mRecordUnlocked.wait(mLockedRecordsMutex); 00093 } 00094 00095 mLockedRecords.insert(aor); 00096 } 00097 00098 void 00099 InMemoryRegistrationDatabase::unlockRecord(const Uri& aor) 00100 { 00101 Lock g2(mLockedRecordsMutex); 00102 00103 { 00104 Lock g1(mDatabaseMutex); 00105 // If the pointer is null, we remove the record from the map. 00106 database_map_t::iterator i = mDatabase.find(aor); 00107 00108 // The record must have been inserted when we locked it in the first place 00109 assert (i != mDatabase.end()); 00110 00111 if (i->second == 0) 00112 { 00113 mDatabase.erase(i); 00114 } 00115 } 00116 00117 mLockedRecords.erase(aor); 00118 mRecordUnlocked.broadcast(); 00119 } 00120 00121 RegistrationPersistenceManager::update_status_t 00122 InMemoryRegistrationDatabase::updateContact(const resip::Uri& aor, 00123 const ContactInstanceRecord& rec) 00124 { 00125 ContactList *contactList = 0; 00126 00127 { 00128 Lock g(mDatabaseMutex); 00129 00130 database_map_t::iterator i; 00131 i = mDatabase.find(aor); 00132 if (i == mDatabase.end() || i->second == 0) 00133 { 00134 contactList = new ContactList(); 00135 mDatabase[aor] = contactList; 00136 } 00137 else 00138 { 00139 contactList = i->second; 00140 } 00141 00142 } 00143 00144 assert(contactList); 00145 00146 ContactList::iterator j; 00147 00148 // See if the contact is already present. We use URI matching rules here. 00149 for (j = contactList->begin(); j != contactList->end(); j++) 00150 { 00151 if (*j == rec) 00152 { 00153 *j=rec; 00154 return CONTACT_UPDATED; 00155 } 00156 } 00157 00158 // This is a new contact, so we add it to the list. 00159 contactList->push_back(rec); 00160 return CONTACT_CREATED; 00161 } 00162 00163 void 00164 InMemoryRegistrationDatabase::removeContact(const Uri& aor, 00165 const ContactInstanceRecord& rec) 00166 { 00167 ContactList *contactList = 0; 00168 00169 { 00170 Lock g(mDatabaseMutex); 00171 00172 database_map_t::iterator i; 00173 i = mDatabase.find(aor); 00174 if (i == mDatabase.end() || i->second == 0) 00175 { 00176 return; 00177 } 00178 contactList = i->second; 00179 } 00180 00181 ContactList::iterator j; 00182 00183 // See if the contact is present. We use URI matching rules here. 00184 for (j = contactList->begin(); j != contactList->end(); j++) 00185 { 00186 if (*j == rec) 00187 { 00188 contactList->erase(j); 00189 if (contactList->empty()) 00190 { 00191 removeAor(aor); 00192 } 00193 return; 00194 } 00195 } 00196 } 00197 00198 void 00199 InMemoryRegistrationDatabase::getContacts(const Uri& aor, ContactList& container) 00200 { 00201 Lock g(mDatabaseMutex); 00202 database_map_t::iterator i = findNotExpired(aor); 00203 if (i == mDatabase.end() || i->second == 0) 00204 { 00205 container.clear(); 00206 return; 00207 } 00208 container = *(i->second); 00209 } 00210 00211 class RemoveIfExpired 00212 { 00213 protected: 00214 UInt64 now; 00215 public: 00216 RemoveIfExpired() 00217 { 00218 now = Timer::getTimeSecs(); 00219 } 00220 bool operator () (const ContactInstanceRecord& rec) 00221 { 00222 return expired(rec); 00223 } 00224 bool expired(const ContactInstanceRecord& rec) 00225 { 00226 if(rec.mRegExpires <= now) 00227 { 00228 DebugLog(<< "ContactInstanceRecord expired: " << rec.mContact); 00229 return true; 00230 } 00231 return false; 00232 } 00233 }; 00234 00235 bool expired(const ContactInstanceRecord& rec) 00236 { 00237 RemoveIfExpired rei; 00238 return rei.expired(rec); 00239 } 00240 00241 InMemoryRegistrationDatabase::database_map_t::iterator 00242 InMemoryRegistrationDatabase::findNotExpired(const Uri& aor) 00243 { 00244 database_map_t::iterator i; 00245 i = mDatabase.find(aor); 00246 if (i == mDatabase.end() || i->second == 0) 00247 { 00248 return i; 00249 } 00250 if(mCheckExpiry) 00251 { 00252 ContactList *contacts = i->second; 00253 #ifdef __SUNPRO_CC 00254 contacts->remove_if(expired); 00255 #else 00256 contacts->remove_if(RemoveIfExpired()); 00257 #endif 00258 } 00259 return i; 00260 } 00261 00262 /* ==================================================================== 00263 * The Vovida Software License, Version 1.0 00264 * 00265 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00266 * 00267 * Redistribution and use in source and binary forms, with or without 00268 * modification, are permitted provided that the following conditions 00269 * are met: 00270 * 00271 * 1. Redistributions of source code must retain the above copyright 00272 * notice, this list of conditions and the following disclaimer. 00273 * 00274 * 2. Redistributions in binary form must reproduce the above copyright 00275 * notice, this list of conditions and the following disclaimer in 00276 * the documentation and/or other materials provided with the 00277 * distribution. 00278 * 00279 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00280 * and "Vovida Open Communication Application Library (VOCAL)" must 00281 * not be used to endorse or promote products derived from this 00282 * software without prior written permission. For written 00283 * permission, please contact vocal@vovida.org. 00284 * 00285 * 4. Products derived from this software may not be called "VOCAL", nor 00286 * may "VOCAL" appear in their name, without prior written 00287 * permission of Vovida Networks, Inc. 00288 * 00289 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00290 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00291 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00292 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00293 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00294 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00295 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00296 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00297 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00298 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00299 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00300 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00301 * DAMAGE. 00302 * 00303 * ==================================================================== 00304 * 00305 * This software consists of voluntary contributions made by Vovida 00306 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00307 * Inc. For more information on Vovida Networks, Inc., please see 00308 * <http://www.vovida.org/>. 00309 * 00310 */
1.7.5.1