diff options
Diffstat (limited to 'cpp/demo')
-rw-r--r-- | cpp/demo/Freeze/phonebook/Collocated.cpp | 21 | ||||
-rw-r--r-- | cpp/demo/Freeze/phonebook/Parser.cpp | 21 | ||||
-rw-r--r-- | cpp/demo/Freeze/phonebook/PhoneBook.ice | 28 | ||||
-rw-r--r-- | cpp/demo/Freeze/phonebook/PhoneBookI.cpp | 313 | ||||
-rw-r--r-- | cpp/demo/Freeze/phonebook/PhoneBookI.h | 6 |
5 files changed, 237 insertions, 152 deletions
diff --git a/cpp/demo/Freeze/phonebook/Collocated.cpp b/cpp/demo/Freeze/phonebook/Collocated.cpp index ca23cc5bcc1..72f36506f57 100644 --- a/cpp/demo/Freeze/phonebook/Collocated.cpp +++ b/cpp/demo/Freeze/phonebook/Collocated.cpp @@ -14,11 +14,6 @@ using namespace std; using namespace Ice; -using namespace Freeze; - -using namespace std; -using namespace Ice; -using namespace Freeze; class PhoneBookCollocated : public Freeze::Application { @@ -29,7 +24,7 @@ public: { } - virtual int runFreeze(int argc, char* argv[], const DBEnvironmentPtr&); + virtual int runFreeze(int argc, char* argv[], const Freeze::DBEnvironmentPtr&); }; int @@ -40,26 +35,26 @@ main(int argc, char* argv[]) } int -PhoneBookCollocated::runFreeze(int argc, char* argv[], const DBEnvironmentPtr& dbEnv) +PhoneBookCollocated::runFreeze(int argc, char* argv[], const Freeze::DBEnvironmentPtr& dbEnv) { PropertiesPtr properties = communicator()->getProperties(); string value; - DBPtr dbPhoneBook = dbEnv->openDB("phonebook", true); - DBPtr dbContacts = dbEnv->openDB("contacts", true); + Freeze::DBPtr dbPhoneBook = dbEnv->openDB("phonebook", true); + Freeze::DBPtr dbContacts = dbEnv->openDB("contacts", true); // // Create an Evictor for contacts. // - EvictorPtr evictor; + Freeze::EvictorPtr evictor; value = properties->getProperty("PhoneBook.SaveAfterMutatingOperation"); if(!value.empty() && atoi(value.c_str()) > 0) { - evictor = dbContacts->createEvictor(SaveAfterMutatingOperation); + evictor = dbContacts->createEvictor(Freeze::SaveAfterMutatingOperation); } else { - evictor = dbContacts->createEvictor(SaveUponEviction); + evictor = dbContacts->createEvictor(Freeze::SaveUponEviction); } value = properties->getProperty("PhoneBook.EvictorSize"); if(!value.empty()) @@ -83,7 +78,7 @@ PhoneBookCollocated::runFreeze(int argc, char* argv[], const DBEnvironmentPtr& d // Create and install a factory and initializer for contacts. // ObjectFactoryPtr contactFactory = new ContactFactory(phoneBook, evictor); - ServantInitializerPtr contactInitializer = ServantInitializerPtr::dynamicCast(contactFactory); + Freeze::ServantInitializerPtr contactInitializer = Freeze::ServantInitializerPtr::dynamicCast(contactFactory); communicator()->addObjectFactory(contactFactory, "::Contact"); evictor->installServantInitializer(contactInitializer); diff --git a/cpp/demo/Freeze/phonebook/Parser.cpp b/cpp/demo/Freeze/phonebook/Parser.cpp index 86da2f6ad6c..ef22b5b665c 100644 --- a/cpp/demo/Freeze/phonebook/Parser.cpp +++ b/cpp/demo/Freeze/phonebook/Parser.cpp @@ -18,7 +18,6 @@ using namespace std; using namespace Ice; -using namespace Freeze; extern FILE* yyin; @@ -67,7 +66,7 @@ Parser::addContacts(const list<string>& args) cout << "added new contact for `" << *p << "'" << endl; } } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -95,7 +94,7 @@ Parser::findContacts(const list<string>& args) cout << "number of contacts found: " << _foundContacts.size() << endl; printCurrent(); } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -134,7 +133,7 @@ Parser::printCurrent() cout << "no current contact" << endl; } } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -167,7 +166,7 @@ Parser::setCurrentName(const list<string>& args) cout << "no current contact" << endl; } } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -200,7 +199,7 @@ Parser::setCurrentAddress(const list<string>& args) cout << "no current contact" << endl; } } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -233,7 +232,7 @@ Parser::setCurrentPhone(const list<string>& args) cout << "no current contact" << endl; } } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -260,7 +259,7 @@ Parser::removeCurrent() cout << "no current contact" << endl; } } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -285,7 +284,7 @@ Parser::setEvictorSize(const list<string>& args) { _phoneBook->setEvictorSize(atoi(args.front().c_str())); } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -304,10 +303,6 @@ Parser::shutdown() { _phoneBook->shutdown(); } - catch(const DBException& ex) - { - error(ex.message); - } catch(const Exception& ex) { ostringstream s; diff --git a/cpp/demo/Freeze/phonebook/PhoneBook.ice b/cpp/demo/Freeze/phonebook/PhoneBook.ice index 68709b12f5e..9b21a47cee5 100644 --- a/cpp/demo/Freeze/phonebook/PhoneBook.ice +++ b/cpp/demo/Freeze/phonebook/PhoneBook.ice @@ -12,25 +12,29 @@ #define PHONE_BOOK_ICE #include <Ice/Identity.ice> -#include <Freeze/DBException.ice> + +exception DatabaseException +{ + string message; +}; class Contact { - ["nonmutating"] string getName() throws Freeze::DBException; - void setName(string name) throws Freeze::DBException; + ["nonmutating"] string getName(); + void setName(string name) throws DatabaseException; - ["nonmutating"] string getAddress() throws Freeze::DBException; - void setAddress(string address) throws Freeze::DBException; + ["nonmutating"] string getAddress(); + void setAddress(string address); - ["nonmutating"] string getPhone() throws Freeze::DBException; - void setPhone(string phone) throws Freeze::DBException; + ["nonmutating"] string getPhone(); + void setPhone(string phone); // // Yes, destroy() is nonmutating. It doesn't change the state of // the Contact. It removes the Contact completely, but doesn't // touch state. // - ["nonmutating"] void destroy(); + ["nonmutating"] void destroy() throws DatabaseException; string _name; string _address; @@ -42,10 +46,10 @@ sequence<Ice::Identity> Identities; // Needed for slice2freeze interface PhoneBook { - Contact* createContact() throws Freeze::DBException; - ["nonmutating"] Contacts findContacts(string name) throws Freeze::DBException; - void setEvictorSize(int size) throws Freeze::DBException; - ["nonmutating"] void shutdown() throws Freeze::DBException; + Contact* createContact() throws DatabaseException; + ["nonmutating"] Contacts findContacts(string name) throws DatabaseException; + void setEvictorSize(int size) throws DatabaseException; + ["nonmutating"] void shutdown(); }; #endif diff --git a/cpp/demo/Freeze/phonebook/PhoneBookI.cpp b/cpp/demo/Freeze/phonebook/PhoneBookI.cpp index 67bb4dfe3ad..23c67d3f509 100644 --- a/cpp/demo/Freeze/phonebook/PhoneBookI.cpp +++ b/cpp/demo/Freeze/phonebook/PhoneBookI.cpp @@ -29,14 +29,15 @@ ContactI::setIdentity(const Identity& ident) string ContactI::getName(const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::RLock sync(*this); return _name; } void ContactI::setName(const string& name, const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::WLock sync(*this); + assert(!_identity.name.empty()); _phoneBook->move(_identity, _name, name); _name = name; @@ -45,38 +46,59 @@ ContactI::setName(const string& name, const Ice::Current&) string ContactI::getAddress(const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::RLock sync(*this); return _address; } void ContactI::setAddress(const string& address, const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::WLock sync(*this); _address = address; } string ContactI::getPhone(const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::RLock sync(*this); return _phone; } void ContactI::setPhone(const string& phone, const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::WLock sync(*this); _phone = phone; } void ContactI::destroy(const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock - assert(!_identity.name.empty()); - _phoneBook->remove(_identity, _name); - _evictor->destroyObject(_identity); + IceUtil::RWRecMutex::RLock sync(*this); + + try + { + assert(!_identity.name.empty()); + _phoneBook->remove(_identity, _name); + + // + // This can throw EvictorDeactivatedException (which indicates + // an internal error). The exception is currently ignored. + // + _evictor->destroyObject(_identity); + } + catch(const Freeze::DBNotFoundException& ex) + { + // + // Raised by remove. Ignore. + // + } + catch(const Freeze::DBException& ex) + { + DatabaseException e; + e.message = ex.message; + throw e; + } } PhoneBookI::PhoneBookI(const ObjectAdapterPtr& adapter, const DBPtr& db, const EvictorPtr& evictor) : @@ -109,7 +131,7 @@ private: ContactPrx PhoneBookI::createContact(const Ice::Current&) { - IceUtil::RecMutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::WLock sync(*this); // // Get a new unique identity. @@ -126,6 +148,9 @@ PhoneBookI::createContact(const Ice::Current&) // Create a new Ice Object in the evictor, using the new identity // and the new Servant. // + // This can throw EvictorDeactivatedException (which indicates + // an internal error). The exception is currently ignored. + // _evictor->createObject(ident, contact); // @@ -133,44 +158,63 @@ PhoneBookI::createContact(const Ice::Current&) // is the empty string. See the comment in getNewIdentity why the // prefix "N" is needed. // - NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N"); - Identities identities; - if (p != _nameIdentitiesDict.end()) + try { - identities = p->second; + NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N"); + Identities identities; + if (p != _nameIdentitiesDict.end()) + { + identities = p->second; + } + + identities.push_back(ident); + _nameIdentitiesDict.insert(make_pair(string("N"), identities)); + + // + // Turn the identity into a Proxy and return the Proxy to the + // caller. + // + return IdentityToContact(_adapter)(ident); + } + catch(const Freeze::DBException& ex) + { + DatabaseException e; + e.message = ex.message; + throw e; } - - identities.push_back(ident); - _nameIdentitiesDict.insert(make_pair(string("N"), identities)); - - // - // Turn the identity into a Proxy and return the Proxy to the - // caller. - // - return IdentityToContact(_adapter)(ident); } Contacts PhoneBookI::findContacts(const string& name, const Ice::Current&) { - IceUtil::RecMutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::RLock sync(*this); - // - // Lookup all phone book contacts that match a name, and return - // them to the caller. See the comment in getNewIdentity why the - // prefix "N" is needed. - // - NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + name); - Identities identities; - if (p != _nameIdentitiesDict.end()) + try + { + // + // Lookup all phone book contacts that match a name, and + // return them to the caller. See the comment in + // getNewIdentity why the prefix "N" is needed. + // + NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + name); + Identities identities; + if (p != _nameIdentitiesDict.end()) + { + identities = p->second; + } + + Contacts contacts; + contacts.reserve(identities.size()); + transform(identities.begin(), identities.end(), back_inserter(contacts), IdentityToContact(_adapter)); + + return contacts; + } + catch(const Freeze::DBException& ex) { - identities = p->second; + DatabaseException e; + e.message = ex.message; + throw e; } - - Contacts contacts; - contacts.reserve(identities.size()); - transform(identities.begin(), identities.end(), back_inserter(contacts), IdentityToContact(_adapter)); - return contacts; } void @@ -179,7 +223,6 @@ PhoneBookI::setEvictorSize(Int size, const Ice::Current&) // // No synchronization necessary, _evictor is immutable. // - _evictor->setSize(size); } @@ -189,112 +232,158 @@ PhoneBookI::shutdown(const Ice::Current&) // // No synchronization necessary, _adapter is immutable. // - _adapter->getCommunicator()->shutdown(); } void PhoneBookI::remove(const Identity& ident, const string& name) { - IceUtil::RecMutex::Lock sync(*this); // TODO: Reader/Writer lock - - // - // See the comment in getNewIdentity why the prefix "N" is needed. - // - NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + name); - - // - // If the name isn't found then this is an application - // error. Throw a DBNotFoundException. - // - if (p == _nameIdentitiesDict.end()) - { - throw DBNotFoundException(); - } + IceUtil::RWRecMutex::WLock sync(*this); - Identities identities = p->second; - identities.erase(remove_if(identities.begin(), identities.end(), bind2nd(equal_to<Ice::Identity>(), ident)), - identities.end()); - - if (identities.empty()) + try { - _nameIdentitiesDict.erase(p); + removeI(ident, name); } - else + catch(const Freeze::DBException& ex) { - // - // See the comment in getNewIdentity why the prefix "N" is - // needed. - // - _nameIdentitiesDict.insert(make_pair("N" + name, identities)); + DatabaseException e; + e.message = ex.message; + throw e; } } void PhoneBookI::move(const Identity& ident, const string& oldName, const string& newName) { - IceUtil::RecMutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::WLock sync(*this); - // - // Called by ContactI in case the name has been changed. See the - // comment in getNewIdentity why the prefix "N" is needed. - // - remove(ident, oldName); - NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + newName); - Identities identities; - if (p != _nameIdentitiesDict.end()) + try + { + // + // Called by ContactI in case the name has been changed. See + // the comment in getNewIdentity why the prefix "N" is needed. + // + removeI(ident, oldName); + NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + newName); + Identities identities; + if (p != _nameIdentitiesDict.end()) + { + identities = p->second; + } + identities.push_back(ident); + _nameIdentitiesDict.insert(make_pair("N" + newName, identities)); + } + catch(const Freeze::DBNotFoundException& ex) + { + // + // Raised by remove. This should only happen under very rare + // circumstances if destroy() had gotten to the object prior + // to the setName() operation being dispatched. Ignore the + // exception. + // + } + catch(const Freeze::DBException& ex) { - identities = p->second; + DatabaseException e; + e.message = ex.message; + throw e; } - identities.push_back(ident); - _nameIdentitiesDict.insert(make_pair("N" + newName, identities)); } Identity PhoneBookI::getNewIdentity() { - // - // This code is a bit of a hack. It stores the last identity that - // has been used (or the name component thereof, to be more - // precise) in the _nameIdentitiesDict, with the special prefix - // "ID". Because of this, all "real" names need to be prefixed - // with "N", so that there is no potential for a name clash. - // - - Ice::Long n; - Identities ids; - NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("ID"); - if (p == _nameIdentitiesDict.end()) + try { - n = 0; - } - else - { - ids = p->second; - assert(ids.size() == 1); + // + // This code is a bit of a hack. It stores the last identity + // that has been used (or the name component thereof, to be + // more precise) in the _nameIdentitiesDict, with the special + // prefix "ID". Because of this, all "real" names need to be + // prefixed with "N", so that there is no potential for a name + // clash. + // + + Ice::Long n; + Identities ids; + NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("ID"); + if (p == _nameIdentitiesDict.end()) + { + n = 0; + } + else + { + ids = p->second; + assert(ids.size() == 1); #ifdef WIN32 - n = _atoi64(ids.front().name.c_str()) + 1; + n = _atoi64(ids.front().name.c_str()) + 1; #else - n = atoll(ids.front().name.c_str()) + 1; + n = atoll(ids.front().name.c_str()) + 1; #endif - } + } - char s[20]; + char s[20]; #ifdef WIN32 - sprintf(s, "%I64d", n); + sprintf(s, "%I64d", n); #else - sprintf(s, "%lld", n); + sprintf(s, "%lld", n); #endif - Identity id; + Identity id; + + id.name = s; + ids.clear(); + ids.push_back(id); + + _nameIdentitiesDict.insert(make_pair(string("ID"), ids)); + + id.name = s; + id.category = "contact"; + return id; + } + catch(const Freeze::DBException& ex) + { + DatabaseException e; + e.message = ex.message; + throw e; + } +} - id.name = s; - ids.clear(); - ids.push_back(id); +// +// Called with the RWRecMutex already acquired. +// +void +PhoneBookI::removeI(const Identity& ident, const string& name) +{ + // + // See the comment in getNewIdentity why the prefix "N" is + // needed. + // + NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + name); - _nameIdentitiesDict.insert(make_pair(string("ID"), ids)); + // + // If the name isn't found then raise a record not found + // exception. + // + if (p == _nameIdentitiesDict.end()) + { + throw Freeze::DBNotFoundException(__FILE__, __LINE__); + } + + Identities identities = p->second; + identities.erase(remove_if(identities.begin(), identities.end(), bind2nd(equal_to<Ice::Identity>(), ident)), + identities.end()); - id.name = s; - id.category = "contact"; - return id; + if (identities.empty()) + { + _nameIdentitiesDict.erase(p); + } + else + { + // + // See the comment in getNewIdentity why the prefix "N" is + // needed. + // + _nameIdentitiesDict.insert(make_pair("N" + name, identities)); + } } diff --git a/cpp/demo/Freeze/phonebook/PhoneBookI.h b/cpp/demo/Freeze/phonebook/PhoneBookI.h index 09e5c84d8c4..bb341a7b94a 100644 --- a/cpp/demo/Freeze/phonebook/PhoneBookI.h +++ b/cpp/demo/Freeze/phonebook/PhoneBookI.h @@ -23,7 +23,7 @@ typedef IceUtil::Handle<PhoneBookI> PhoneBookIPtr; class ContactI; typedef IceUtil::Handle<ContactI> ContactIPtr; -class ContactI : public Contact, public IceUtil::Mutex +class ContactI : public Contact, public IceUtil::RWRecMutex { public: @@ -49,7 +49,7 @@ private: Ice::Identity _identity; }; -class PhoneBookI : public PhoneBook, public IceUtil::RecMutex +class PhoneBookI : public PhoneBook, public IceUtil::RWRecMutex { public: @@ -66,6 +66,8 @@ public: private: + void removeI(const Ice::Identity&, const std::string&); + Ice::ObjectAdapterPtr _adapter; Freeze::DBPtr _db; Freeze::EvictorPtr _evictor; |