diff options
author | Bernard Normier <bernard@zeroc.com> | 2003-09-16 01:41:46 +0000 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2003-09-16 01:41:46 +0000 |
commit | 83cb29a8de333646c9b3e7ac6909accce72e6b5f (patch) | |
tree | cc1037886e0d1770d9c1ad412d79c81a5a1d21ad /cpp | |
parent | flex fixes (diff) | |
download | ice-83cb29a8de333646c9b3e7ac6909accce72e6b5f.tar.bz2 ice-83cb29a8de333646c9b3e7ac6909accce72e6b5f.tar.xz ice-83cb29a8de333646c9b3e7ac6909accce72e6b5f.zip |
Added Freeze Connection and Transaction
Diffstat (limited to 'cpp')
42 files changed, 1680 insertions, 474 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES index 894f75fb472..d4dc62218ad 100644 --- a/cpp/CHANGES +++ b/cpp/CHANGES @@ -126,17 +126,24 @@ Changes since version 1.1.1 Freeze Maps are now opened/created directly using their constructor: - C++: DBMap(const Ice::CommunicatorPtr& communicator, - const std::string& envName, + C++: DBMap(const Freeze::ConnectionPtr& connection, const std::string& dbName, bool createDb = true); Java: public - Map(Ice.Communicator communicator, - String envName, + Map(Connection connection, String dbName, boolean createDb); + Connection is a new local interface similar to the DBEnvironment + local interface (which was removed). However, Connection is not + thread-safe: access to a given Connection object must be serialized. + A connection can be used to create a Transaction (similar to the + old DBTransaction); likewise, a Transaction is not thread-safe. + + To access concurrently the "same" map, you should create multiple + connections and associated maps. + In Java, it is necessary to call close() on the Map if you want to close the underlying Berkeley DB database (and indirectly the environment) before the Map is finalized. @@ -150,34 +157,25 @@ Changes since version 1.1.1 have an associated transaction that is committed when the iterator is closed. - Freeze Maps support concurrent access: several threads can use - (read and write) the same Map concurrently without any application - level locking: the locking is handled by Berkeley DB. However - iterators are not thread safe: concurrent access to a given - iterator (which is very unusual) needs to be synchronized by the - application. Concurrent reads and writes to the same Map can + Concurrent reads and writes to the same underlyding Map can generate deadlocks, even with a single writer. Berkeley DB detects such deadlocks and "kills" one locker (iterator or transaction) to resolve it. For non-iterator access, Freeze handles this situation and retries transparently. When using iterators, a DBDeadlockException is raised to the application, which is - responsible for closing the affected iterator(s) and retrying. + responsible for closing the affected iterator(s) or transaction, + and retrying. Serialized access or concurrent reads never produce deadlocks. - In Java, iterators are no longer closed as a side effect of other - write operations. Doing so would require adding synchronization to - all Java iterator methods. - - Currently, Java Freeze Map iterators are closed either through the - proprietary close() method, or when hasNext() returns false (or - next() throws NoSuchElementException, which is equivalent). This - latter behavior may be removed soon. - In C++, the copy constructor and assignment operator of Freeze Map iterators duplicate the source iterator. When the source iterator is non-const, the duplicate iterator will use the same transaction. This transaction is committed only when its last associated iterator is closed (i.e., destroyed or assigned end()). + + In both C++ and Java, write operations that not within a user- + controlled transaction automatically close all open iterators + in the target Map. This reduces the likelyhood of self-deadlocks. - Freeze Evictor update: diff --git a/cpp/demo/Freeze/bench/Client.cpp b/cpp/demo/Freeze/bench/Client.cpp index b654d2dcb86..5eafd95583e 100644 --- a/cpp/demo/Freeze/bench/Client.cpp +++ b/cpp/demo/Freeze/bench/Client.cpp @@ -13,11 +13,15 @@ // ********************************************************************** #include <Ice/Application.h> +#include <Freeze/Freeze.h> #include <BenchTypes.h> #include <cstdlib> +using namespace Freeze; +using namespace Ice; using namespace std; + static void testFailed(const char* expr, const char* file, unsigned int line) { @@ -158,6 +162,7 @@ private: void IntIntMapReadTest(); const string _envName; + ConnectionPtr _connection; StopWatch _watch; int _repetitions; }; @@ -171,16 +176,20 @@ TestApp::TestApp(const string& envName) : void TestApp::IntIntMapTest() { - IntIntMap m(communicator(), _envName, "IntIntMap"); + IntIntMap m(_connection, "IntIntMap"); // // Populate the database. // int i; _watch.start(); - for(i = 0; i < _repetitions; ++i) { - m.put(IntIntMap::value_type(i, i)); + TransactionHolder txHolder(_connection); + for(i = 0; i < _repetitions; ++i) + { + m.put(IntIntMap::value_type(i, i)); + } + txHolder.commit(); } double total = _watch.stop(); double perRecord = total / _repetitions; @@ -208,9 +217,13 @@ TestApp::IntIntMapTest() // Remove each record. // _watch.start(); - for(i = 0; i < _repetitions; ++i) { - m.erase(i); + TransactionHolder txHolder(_connection); + for(i = 0; i < _repetitions; ++i) + { + m.erase(i); + } + txHolder.commit(); } total = _watch.stop(); perRecord = total / _repetitions; @@ -241,16 +254,20 @@ TestApp::generatedRead(IntIntMap& m, int reads , const GeneratorPtr& gen) void TestApp::IntIntMapReadTest() { - IntIntMap m(communicator(), _envName, "IntIntMap"); + IntIntMap m(_connection, "IntIntMap"); // // Populate the database. // int i; _watch.start(); - for(i = 0; i < _repetitions; ++i) { - m.put(IntIntMap::value_type(i, i)); + TransactionHolder txHolder(_connection); + for(i = 0; i < _repetitions; ++i) + { + m.put(IntIntMap::value_type(i, i)); + } + txHolder.commit(); } double total = _watch.stop(); double perRecord = total / _repetitions; @@ -295,7 +312,7 @@ TestApp::IntIntMapReadTest() void TestApp::Struct1Struct2MapTest() { - Struct1Struct2Map m(communicator(), _envName, "Struct1Struct2"); + Struct1Struct2Map m(_connection, "Struct1Struct2"); // // Populate the database. @@ -304,13 +321,17 @@ TestApp::Struct1Struct2MapTest() Struct2 s2; int i; _watch.start(); - for(i = 0; i < _repetitions; ++i) { - s1.l = i; - ostringstream os; - os << i; - s2.s = os.str(); - m.put(Struct1Struct2Map::value_type(s1, s2)); + TransactionHolder txHolder(_connection); + for(i = 0; i < _repetitions; ++i) + { + s1.l = i; + ostringstream os; + os << i; + s2.s = os.str(); + m.put(Struct1Struct2Map::value_type(s1, s2)); + } + txHolder.commit(); } double total = _watch.stop(); double perRecord = total / _repetitions; @@ -341,10 +362,14 @@ TestApp::Struct1Struct2MapTest() // Remove each record. // _watch.start(); - for(i = 0; i < _repetitions; ++i) { - s1.l = i; - m.erase(s1); + TransactionHolder txHolder(_connection); + for(i = 0; i < _repetitions; ++i) + { + s1.l = i; + m.erase(s1); + } + txHolder.commit(); } total = _watch.stop(); perRecord = total / _repetitions; @@ -355,7 +380,7 @@ TestApp::Struct1Struct2MapTest() void TestApp::Struct1Class1MapTest() { - Struct1Class1Map m(communicator(), _envName, "Struct1Class1"); + Struct1Class1Map m(_connection, "Struct1Class1"); // // Populate the database. @@ -364,14 +389,18 @@ TestApp::Struct1Class1MapTest() Class1Ptr c1 = new Class1(); int i; _watch.start(); - for(i = 0; i < _repetitions; ++i) - { - s1.l = i; - ostringstream os; - os << i; - c1->s = os.str(); - m.put(Struct1Class1Map::value_type(s1, c1)); - } + { + TransactionHolder txHolder(_connection); + for(i = 0; i < _repetitions; ++i) + { + s1.l = i; + ostringstream os; + os << i; + c1->s = os.str(); + m.put(Struct1Class1Map::value_type(s1, c1)); + } + txHolder.commit(); + } double total = _watch.stop(); double perRecord = total / _repetitions; @@ -401,10 +430,14 @@ TestApp::Struct1Class1MapTest() // Remove each record. // _watch.start(); - for(i = 0; i < _repetitions; ++i) { - s1.l = i; - m.erase(s1); + TransactionHolder txHolder(_connection); + for(i = 0; i < _repetitions; ++i) + { + s1.l = i; + m.erase(s1); + } + txHolder.commit(); } total = _watch.stop(); perRecord = total / _repetitions; @@ -416,7 +449,7 @@ TestApp::Struct1Class1MapTest() void TestApp::Struct1ObjectMapTest() { - Struct1ObjectMap m(communicator(), _envName, "Struct1Object"); + Struct1ObjectMap m(_connection, "Struct1Object"); // // Populate the database. @@ -428,22 +461,26 @@ TestApp::Struct1ObjectMapTest() c2->obj = c1; int i; _watch.start(); - for(i = 0; i < _repetitions; ++i) { - s1.l = i; - Ice::ObjectPtr o; - if((i % 2) == 0) + TransactionHolder txHolder(_connection); + for(i = 0; i < _repetitions; ++i) { - o = c2; + s1.l = i; + Ice::ObjectPtr o; + if((i % 2) == 0) + { + o = c2; + } + else + { + o = c1; + } + ostringstream os; + os << i; + c1->s = os.str(); + m.put(Struct1ObjectMap::value_type(s1, o)); } - else - { - o = c1; - } - ostringstream os; - os << i; - c1->s = os.str(); - m.put(Struct1ObjectMap::value_type(s1, o)); + txHolder.commit(); } double total = _watch.stop(); double perRecord = total / _repetitions; @@ -488,10 +525,14 @@ TestApp::Struct1ObjectMapTest() // Remove each record. // _watch.start(); - for(i = 0; i < _repetitions; ++i) { - s1.l = i; - m.erase(s1); + TransactionHolder txHolder(_connection); + for(i = 0; i < _repetitions; ++i) + { + s1.l = i; + m.erase(s1); + } + txHolder.commit(); } total = _watch.stop(); perRecord = total / _repetitions; @@ -536,6 +577,8 @@ typedef IceUtil::Handle<MyFactory> MyFactoryPtr; int TestApp::run(int argc, char* argv[]) { + _connection = createConnection(communicator(), _envName); + cout <<"IntIntMap" << endl; IntIntMapTest(); @@ -553,6 +596,8 @@ TestApp::run(int argc, char* argv[]) cout <<"IntIntMap (read test)" << endl; IntIntMapReadTest(); + + _connection->close(); return EXIT_SUCCESS; } diff --git a/cpp/demo/Freeze/library/LibraryI.cpp b/cpp/demo/Freeze/library/LibraryI.cpp index 4a3715237c9..25fe1ab291f 100644 --- a/cpp/demo/Freeze/library/LibraryI.cpp +++ b/cpp/demo/Freeze/library/LibraryI.cpp @@ -161,7 +161,8 @@ LibraryI::LibraryI(const Ice::CommunicatorPtr& communicator, const string& envName, const string& dbName, const Freeze::EvictorPtr& evictor) : _evictor(evictor), - _authors(communicator, envName, dbName) + _connection(Freeze::createConnection(communicator, envName)), + _authors(_connection, dbName) { } diff --git a/cpp/demo/Freeze/library/LibraryI.h b/cpp/demo/Freeze/library/LibraryI.h index 8e49f5d6f93..b3f4c065528 100644 --- a/cpp/demo/Freeze/library/LibraryI.h +++ b/cpp/demo/Freeze/library/LibraryI.h @@ -42,6 +42,7 @@ private: Freeze::EvictorPtr _evictor; + Freeze::ConnectionPtr _connection; // // This is a dictionary of authors to a sequence of isbn numbers // for efficient lookup of books by authors. diff --git a/cpp/demo/Freeze/phonebook/PhoneBookI.cpp b/cpp/demo/Freeze/phonebook/PhoneBookI.cpp index 8b1b4c73faa..e8c905dff35 100644 --- a/cpp/demo/Freeze/phonebook/PhoneBookI.cpp +++ b/cpp/demo/Freeze/phonebook/PhoneBookI.cpp @@ -152,7 +152,8 @@ PhoneBookI::PhoneBookI(const Ice::CommunicatorPtr& communicator, const std::string& envName, const std::string& dbName, const Freeze::EvictorPtr& evictor) : _evictor(evictor), - _nameIdentitiesDict(communicator, envName, dbName) + _connection(createConnection(communicator, envName)), + _nameIdentitiesDict(_connection, dbName) { } diff --git a/cpp/demo/Freeze/phonebook/PhoneBookI.h b/cpp/demo/Freeze/phonebook/PhoneBookI.h index 3ebc830bb85..89d4fac9a80 100644 --- a/cpp/demo/Freeze/phonebook/PhoneBookI.h +++ b/cpp/demo/Freeze/phonebook/PhoneBookI.h @@ -77,6 +77,7 @@ private: void removeI(const Ice::Identity&, const std::string&); Freeze::EvictorPtr _evictor; + Freeze::ConnectionPtr _connection; NameIdentitiesDict _nameIdentitiesDict; }; diff --git a/cpp/include/Freeze/Freeze.h b/cpp/include/Freeze/Freeze.h index 317df6014fd..c373f5371fa 100644 --- a/cpp/include/Freeze/Freeze.h +++ b/cpp/include/Freeze/Freeze.h @@ -18,5 +18,6 @@ #include <Freeze/Initialize.h> #include <Freeze/Evictor.h> #include <Freeze/Map.h> +#include <Freeze/TransactionHolder.h> #endif diff --git a/cpp/include/Freeze/Initialize.h b/cpp/include/Freeze/Initialize.h index e9d1ae9a2b4..96aecb2ea16 100644 --- a/cpp/include/Freeze/Initialize.h +++ b/cpp/include/Freeze/Initialize.h @@ -17,6 +17,7 @@ #include <Ice/Ice.h> #include <Freeze/EvictorF.h> +#include <Freeze/ConnectionF.h> // // Berkeley DB's DbEnv @@ -36,6 +37,13 @@ FREEZE_API EvictorPtr createEvictor(const Ice::CommunicatorPtr& communicator, const std::string& dbName, bool createDb = true); + +FREEZE_API ConnectionPtr createConnection(const Ice::CommunicatorPtr& communicator, + const std::string& envName); + +FREEZE_API ConnectionPtr createConnection(const Ice::CommunicatorPtr& communicator, + DbEnv& dbEnv); + } #endif diff --git a/cpp/include/Freeze/Map.h b/cpp/include/Freeze/Map.h index 8e48f0e966c..709a6b1ebb6 100644 --- a/cpp/include/Freeze/Map.h +++ b/cpp/include/Freeze/Map.h @@ -19,6 +19,7 @@ #include <iterator> #include <Freeze/DB.h> #include <Freeze/DBException.h> +#include <Freeze/Connection.h> // // Berkeley DB's DbEnv @@ -35,14 +36,7 @@ class FREEZE_API DBMapHelper public: static DBMapHelper* - create(const Ice::CommunicatorPtr& communicator, - const std::string& envName, - const std::string& dbName, - bool createDb); - - static DBMapHelper* - create(const Ice::CommunicatorPtr& communicator, - DbEnv& dbEnv, + create(const Freeze::ConnectionPtr& connection, const std::string& dbName, bool createDb); @@ -69,17 +63,9 @@ public: virtual size_t size() const = 0; - const Ice::CommunicatorPtr& - getCommunicator() const - { - return _communicator; - } - -protected: - - DBMapHelper(const Ice::CommunicatorPtr&); + virtual void + closeAllIterators() = 0; - Ice::CommunicatorPtr _communicator; }; @@ -110,9 +96,6 @@ public: virtual bool equals(const DBIteratorHelper&) const = 0; - - virtual const Ice::CommunicatorPtr& - getCommunicator() const = 0; }; @@ -157,14 +140,16 @@ public: typedef value_type& reference; - DBIterator(DBMapHelper& mapHelper) : - _helper(DBIteratorHelper::create(mapHelper, false)), + DBIterator(DBMapHelper& mapHelper, const Ice::CommunicatorPtr& communicator) : + _helper(DBIteratorHelper::create(mapHelper, false)), + _communicator(communicator), _refValid(false) { } - DBIterator(DBIteratorHelper* helper) : - _helper(helper), + DBIterator(DBIteratorHelper* helper, const Ice::CommunicatorPtr& communicator) : + _helper(helper), + _communicator(communicator), _refValid(false) { } @@ -175,6 +160,7 @@ public: } DBIterator(const DBIterator& rhs) : + _communicator(rhs._communicator), _refValid(false) { if(rhs._helper.get() != 0) @@ -195,7 +181,7 @@ public: { _helper.reset(); } - + _communicator = rhs._communicator; _refValid = false; } @@ -274,7 +260,7 @@ public: assert(_helper.get()); Value v; - ValueCodec::write(value, v, _helper->getCommunicator()); + ValueCodec::write(value, v, _communicator); _helper->set(v); _refValid = false; } @@ -305,16 +291,15 @@ private: assert(k != 0); assert(v != 0); - const Ice::CommunicatorPtr& communicator = _helper->getCommunicator(); - KeyCodec::read(key, *k, communicator); - ValueCodec::read(value, *v, communicator); + KeyCodec::read(key, *k, _communicator); + ValueCodec::read(value, *v, _communicator); } friend class ConstDBIterator<key_type, mapped_type, KeyCodec, ValueCodec>; friend class DBMap<key_type, mapped_type, KeyCodec, ValueCodec>; std::auto_ptr<DBIteratorHelper> _helper; - + Ice::CommunicatorPtr _communicator; // // Cached last return value. This is so that operator->() can // actually return a pointer. The cached value is reused across @@ -346,14 +331,16 @@ public: typedef value_type& reference; - ConstDBIterator(DBMapHelper& mapHelper) : + ConstDBIterator(DBMapHelper& mapHelper, const Ice::CommunicatorPtr& communicator) : _helper(DBIteratorHelper::create(mapHelper, true)), + _communicator(_communicator), _refValid(false) { } - ConstDBIterator(DBIteratorHelper* helper) : - _helper(helper), + ConstDBIterator(DBIteratorHelper* helper, const Ice::CommunicatorPtr& communicator) : + _helper(helper), + _communicator(communicator), _refValid(false) { } @@ -364,6 +351,7 @@ public: } ConstDBIterator(const ConstDBIterator& rhs) : + _communicator(rhs._communicator), _refValid(false) { if(rhs._helper.get() != 0) @@ -383,6 +371,7 @@ public: { _helper.reset(rhs._helper->clone()); } + _communicator = rhs._communicator; } ConstDBIterator& operator=(const ConstDBIterator& rhs) @@ -397,7 +386,7 @@ public: { _helper.reset(); } - + _communicator = rhs._communicator; _refValid = false; } @@ -417,7 +406,7 @@ public: { _helper.reset(); } - + _communicator = rhs._communicator; _refValid = false; return *this; @@ -513,14 +502,14 @@ private: assert(k != 0); assert(v != 0); - const Ice::CommunicatorPtr& communicator = _helper->getCommunicator(); - KeyCodec::read(key, *k, communicator); - ValueCodec::read(value, *v, communicator); + KeyCodec::read(key, *k, _communicator); + ValueCodec::read(value, *v, _communicator); } friend class DBMap<key_type, mapped_type, KeyCodec, ValueCodec>; std::auto_ptr<DBIteratorHelper> _helper; + Ice::CommunicatorPtr _communicator; // // Cached last return value. This is so that operator->() can @@ -580,44 +569,21 @@ public: // // Constructors // - DBMap(const Ice::CommunicatorPtr& communicator, - const std::string& envName, - const std::string& dbName, - bool createDb = true) : - _helper(DBMapHelper::create(communicator, envName, dbName, createDb)) - { - } - - DBMap(const Ice::CommunicatorPtr& communicator, - DbEnv& dbEnv, + DBMap(const Freeze::ConnectionPtr& connection, const std::string& dbName, bool createDb = true) : - _helper(DBMapHelper::create(communicator, dbEnv, dbName, createDb)) + _helper(DBMapHelper::create(connection, dbName, createDb)), + _communicator(connection->getCommunicator()) { } template <class _InputDBIterator> - DBMap(const Ice::CommunicatorPtr& communicator, - const std::string& envName, - const std::string& dbName, - bool createDb, - _InputDBIterator first, _InputDBIterator last) : - _helper(new DBMapHelper(communicator, envName, dbName, createDb)) - { - while(first != last) - { - put(*first); - ++first; - } - } - - template <class _InputDBIterator> - DBMap(const Ice::CommunicatorPtr& communicator, - DbEnv& dbEnv, + DBMap(const Freeze::ConnectionPtr& connection, const std::string& dbName, bool createDb, _InputDBIterator first, _InputDBIterator last) : - _helper(new DBMapHelper(communicator, dbEnv, dbName, createDb)) + _helper(new DBMapHelper(connection, dbName, createDb)), + _communicator(connection->getCommunicator()) { while(first != last) { @@ -675,13 +641,17 @@ public: DBMapHelper* tmp = _helper.release(); _helper.reset(rhs._helper.release()); rhs._helper.reset(tmp); + + Ice::CommunicatorPtr tmpCom = _communicator; + _communicator = rhs._communicator; + rhs._communicator = tmpCom; } iterator begin() { try { - return iterator(DBIteratorHelper::create(*_helper.get(), false)); + return iterator(DBIteratorHelper::create(*_helper.get(), false), _communicator); } catch(const DBNotFoundException&) { @@ -692,7 +662,7 @@ public: { try { - return const_iterator(DBIteratorHelper::create(*_helper.get(), true)); + return const_iterator(DBIteratorHelper::create(*_helper.get(), true), _communicator); } catch(const DBNotFoundException&) { @@ -750,20 +720,18 @@ public: // // position is ignored. // - const Ice::CommunicatorPtr& communicator = _helper->getCommunicator(); - Key k; - KeyCodec::write(key.first, k, communicator); + KeyCodec::write(key.first, k, _communicator); - iterator r = iterator(_helper->find(k, false)); + iterator r = iterator(_helper->find(k, false), _communicator); if(r == end()) { Value v; - ValueCodec::write(key.second, v, communicator); + ValueCodec::write(key.second, v, _communicator); _helper->put(k, v); - r = iterator(_helper->find(k, false)); + r = iterator(_helper->find(k, false), _communicator); } return r; @@ -771,22 +739,20 @@ public: std::pair<iterator, bool> insert(const value_type& key) { - const Ice::CommunicatorPtr& communicator = _helper->getCommunicator(); - Key k; - KeyCodec::write(key.first, k, communicator); + KeyCodec::write(key.first, k, _communicator); - iterator r = iterator(_helper->find(k, false)); + iterator r = iterator(_helper->find(k, false), _communicator); bool inserted = false; if(r == end()) { Value v; - ValueCodec::write(key.second, v, communicator); + ValueCodec::write(key.second, v, _communicator); _helper->put(k, v); inserted = true; - r = iterator(_helper->find(k, false)); + r = iterator(_helper->find(k, false), _communicator); } return std::pair<iterator, bool>(r, inserted); @@ -807,12 +773,10 @@ public: // // insert or replace // - const Ice::CommunicatorPtr& communicator = _helper->getCommunicator(); - Key k; Value v; - KeyCodec::write(key.first, k, communicator); - ValueCodec::write(key.second, v, communicator); + KeyCodec::write(key.first, k, _communicator); + ValueCodec::write(key.second, v, _communicator); _helper->put(k, v); } @@ -836,7 +800,7 @@ public: size_type erase(const key_type& key) { Key k; - KeyCodec::write(key, k, _helper->getCommunicator()); + KeyCodec::write(key, k, _communicator); return _helper->erase(k); } @@ -867,23 +831,23 @@ public: iterator find(const key_type& key) { Key k; - KeyCodec::write(key, k, _helper->getCommunicator()); + KeyCodec::write(key, k, _communicator); - return iterator(_helper->find(k, false)); + return iterator(_helper->find(k, false), _communicator); } const_iterator find(const key_type& key) const { Key k; - KeyCodec::write(key, k, _helper->getCommunicator()); + KeyCodec::write(key, k, _communicator); - return const_iterator(_helper->find(k, true)); + return const_iterator(_helper->find(k, true), _communicator); } size_type count(const key_type& key) const { Key k; - KeyCodec::write(key, k, _helper->getCommunicator()); + KeyCodec::write(key, k, _communicator); return _helper->count(k); @@ -901,9 +865,17 @@ public: return std::pair<const_iterator,const_iterator>(p,p); } + const Ice::CommunicatorPtr& + communicator() const + { + return _communicator(); + } + + private: std::auto_ptr<DBMapHelper> _helper; + const Ice::CommunicatorPtr _communicator; }; } diff --git a/cpp/include/Freeze/TransactionHolder.h b/cpp/include/Freeze/TransactionHolder.h new file mode 100644 index 00000000000..78834c7a439 --- /dev/null +++ b/cpp/include/Freeze/TransactionHolder.h @@ -0,0 +1,53 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifndef FREEZE_TRANSACTION_HOLDER_H +#define FREEZE_TRANSACTION_HOLDER_H + +#include <Freeze/Connection.h> +#include <Freeze/Transaction.h> + +namespace Freeze +{ + +class FREEZE_API TransactionHolder +{ +public: + + TransactionHolder(const ConnectionPtr&); + + ~TransactionHolder(); + + void + commit(); + + void + rollback(); + +private: + + // + // Not implemented + // + TransactionHolder(const TransactionHolder&); + + TransactionHolder& + operator=(const TransactionHolder&); + + TransactionPtr _transaction; +}; + +} + +#endif diff --git a/cpp/slice/Freeze/DB.ice b/cpp/slice/Freeze/DB.ice index 199efde93aa..31a651bb525 100644 --- a/cpp/slice/Freeze/DB.ice +++ b/cpp/slice/Freeze/DB.ice @@ -41,7 +41,6 @@ sequence<byte> Key; **/ sequence<byte> Value; - }; #endif diff --git a/cpp/slice/Freeze/DBException.ice b/cpp/slice/Freeze/DBException.ice index a6bf328df4d..0409f9dbc84 100644 --- a/cpp/slice/Freeze/DBException.ice +++ b/cpp/slice/Freeze/DBException.ice @@ -22,10 +22,9 @@ module Freeze * * A Freeze database exception. * - * @see DBEnvironment - * @see DBTransaction * @see DB * @see Evictor + * @see Connection * **/ local exception DBException @@ -64,7 +63,7 @@ local exception DBDeadlockException extends DBException * this position has been erased. * **/ -local exception DBInvalidPositionException extends DBException +local exception DBInvalidPositionException { }; diff --git a/cpp/src/Freeze/.depend b/cpp/src/Freeze/.depend index 4fe4b3ae900..8cf885ce3db 100644 --- a/cpp/src/Freeze/.depend +++ b/cpp/src/Freeze/.depend @@ -1,12 +1,21 @@ -DBException.o: DBException.cpp ../../include/Freeze/DBException.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h -Evictor.o: Evictor.cpp ../../include/Freeze/Evictor.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ServantLocator.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Facet.h ../../include/Freeze/DBException.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/IncomingAsyncF.h -EvictorF.o: EvictorF.cpp ../../include/Freeze/EvictorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h -EvictorStorage.o: EvictorStorage.cpp ../../include/Freeze/EvictorStorage.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/Identity.h ../../include/Ice/Facet.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h -MapI.o: MapI.cpp ../Freeze/MapI.h ../../include/Freeze/Map.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Facet.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../../include/Ice/Properties.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/StatsF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Application.h ../../include/Freeze/DB.h ../../include/Freeze/DBException.h ../Freeze/SharedDbEnv.h -EvictorI.o: EvictorI.cpp ../Freeze/EvictorI.h ../../include/IceUtil/IceUtil.h ../../include/IceUtil/Functional.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Unicode.h ../../include/IceUtil/UUID.h ../../include/IceUtil/AbstractMutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/RWRecMutex.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Base64.h ../../include/IceUtil/InputUtil.h ../../include/IceUtil/OutputUtil.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Facet.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../../include/Ice/Properties.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/StatsF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Application.h ../../include/Freeze/Evictor.h ../../include/Freeze/DBException.h ../Freeze/SharedDbEnv.h ../../include/Freeze/EvictorStorage.h ../../include/Freeze/DB.h ../../include/Freeze/Initialize.h ../../include/Freeze/EvictorF.h -SharedDbEnv.o: SharedDbEnv.cpp ../Freeze/SharedDbEnv.h ../../include/Ice/Config.h ../../include/IceUtil/Config.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Facet.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../../include/Ice/Properties.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/StatsF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Application.h ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Thread.h ../../include/Freeze/DBException.h +DBException.o: DBException.cpp ../../include/Freeze/DBException.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h +Evictor.o: Evictor.cpp ../../include/Freeze/Evictor.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ServantLocator.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Facet.h ../../include/Freeze/DBException.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Stream.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/BuiltinSequences.h +EvictorF.o: EvictorF.cpp ../../include/Freeze/EvictorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h +EvictorStorage.o: EvictorStorage.cpp ../../include/Freeze/EvictorStorage.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Ice/Identity.h ../../include/Ice/Facet.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Stream.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/BuiltinSequences.h +Connection.o: Connection.cpp ../../include/Freeze/Connection.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Freeze/Transaction.h +ConnectionF.o: ConnectionF.cpp ../../include/Freeze/ConnectionF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h +ConnectionI.o: ConnectionI.cpp ../Freeze/ConnectionI.h ../../include/Freeze/Connection.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Freeze/Transaction.h ../../include/Freeze/Initialize.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Facet.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../../include/Ice/Properties.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/StatsF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Application.h ../../include/Freeze/EvictorF.h ../../include/Freeze/ConnectionF.h ../Freeze/TransactionI.h +Transaction.o: Transaction.cpp ../../include/Freeze/Transaction.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h +TransactionI.o: TransactionI.cpp ../Freeze/TransactionI.h ../../include/Freeze/Transaction.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../Freeze/ConnectionI.h ../../include/Freeze/Connection.h ../../include/Freeze/Initialize.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Facet.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../../include/Ice/Properties.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/StatsF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Application.h ../../include/Freeze/EvictorF.h ../../include/Freeze/ConnectionF.h +SharedDb.o: SharedDb.cpp ../Freeze/SharedDb.h ../../include/Ice/Config.h ../../include/IceUtil/Config.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Facet.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../../include/Ice/Properties.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/StatsF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Application.h ../../include/IceUtil/StaticMutex.h ../../include/Freeze/DBException.h +MapI.o: MapI.cpp ../Freeze/MapI.h ../../include/Freeze/Map.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Facet.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../../include/Ice/Properties.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/StatsF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Application.h ../../include/Freeze/DB.h ../../include/Freeze/DBException.h ../Freeze/SharedDbEnv.h ../Freeze/SharedDb.h +EvictorI.o: EvictorI.cpp ../../include/Ice/Object.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/ObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/StreamF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/Identity.h ../../include/Ice/Facet.h ../Freeze/EvictorI.h ../../include/IceUtil/IceUtil.h ../../include/IceUtil/Functional.h ../../include/IceUtil/Unicode.h ../../include/IceUtil/UUID.h ../../include/IceUtil/AbstractMutex.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/RWRecMutex.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Base64.h ../../include/IceUtil/InputUtil.h ../../include/IceUtil/OutputUtil.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../../include/Ice/Properties.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/StatsF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Application.h ../../include/Freeze/Evictor.h ../../include/Freeze/DBException.h ../Freeze/SharedDbEnv.h ../../include/Freeze/EvictorStorage.h ../../include/Freeze/DB.h ../../include/Freeze/Initialize.h ../../include/Freeze/EvictorF.h ../../include/Freeze/ConnectionF.h ../../include/Ice/Stream.h +SharedDbEnv.o: SharedDbEnv.cpp ../Freeze/SharedDbEnv.h ../../include/Ice/Config.h ../../include/IceUtil/Config.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Facet.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../../include/Ice/Properties.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/StatsF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Application.h ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Thread.h ../../include/Freeze/DBException.h DB.cpp: ../../slice/Freeze/DB.ice DBException.cpp: ../../slice/Freeze/DBException.ice +Connection.cpp: ../../slice/Freeze/Connection.ice ../../slice/Freeze/Transaction.ice +ConnectionF.cpp: ../../slice/Freeze/ConnectionF.ice +Transaction.cpp: ../../slice/Freeze/Transaction.ice Evictor.cpp: ../../slice/Freeze/Evictor.ice ../../slice/Ice/ObjectAdapterF.ice ../../slice/Ice/ServantLocator.ice ../../slice/Ice/Current.ice ../../slice/Ice/Identity.ice ../../slice/Ice/Facet.ice ../../slice/Freeze/DBException.ice EvictorF.cpp: ../../slice/Freeze/EvictorF.ice EvictorStorage.cpp: ../../slice/Freeze/EvictorStorage.ice ../../slice/Ice/Identity.ice ../../slice/Ice/Facet.ice diff --git a/cpp/src/Freeze/ConnectionI.cpp b/cpp/src/Freeze/ConnectionI.cpp new file mode 100644 index 00000000000..630c49fd3e6 --- /dev/null +++ b/cpp/src/Freeze/ConnectionI.cpp @@ -0,0 +1,150 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#include <Freeze/ConnectionI.h> +#include <Freeze/MapI.h> +#include <Freeze/Initialize.h> + +using namespace Ice; +using namespace Freeze; +using namespace std; + + +Freeze::TransactionPtr +Freeze::ConnectionI::beginTransaction() +{ + if(_transaction != 0) + { + throw TransactionAlreadyInProgressException(__FILE__, __LINE__); + } + closeAllIterators(); + _transaction = new TransactionI(this); + return _transaction; +} + +Freeze::TransactionPtr +Freeze::ConnectionI::currentTransaction() const +{ + return _transaction; +} + +void +Freeze::ConnectionI::close() +{ + if(_transaction != 0) + { + try + { + _transaction->rollback(); + } + catch(const Freeze::DBException&) + { + // + // Ignored + // + } + } + + while(!_mapList.empty()) + { + (*_mapList.begin())->close(); + } + + if(_dbEnv != 0) + { + _dbEnv = 0; + _dbEnvHolder = 0; + } +} + +Ice::CommunicatorPtr +Freeze::ConnectionI::getCommunicator() const +{ + return _communicator; +} + +string +Freeze::ConnectionI::getName() const +{ + return _envName; +} + + +Freeze::ConnectionI::~ConnectionI() +{ + close(); +} + +Freeze::ConnectionI::ConnectionI(const Ice::CommunicatorPtr& communicator, + const std::string& envName) : + _communicator(communicator), + _dbEnvHolder(SharedDbEnv::get(communicator, envName)), + _envName(envName), + _trace(communicator->getProperties()->getPropertyAsInt("Freeze.Trace.DB")) +{ + _dbEnv = _dbEnvHolder.get(); +} + +Freeze::ConnectionI::ConnectionI(const Ice::CommunicatorPtr& communicator, + DbEnv& dbEnv) : + _communicator(communicator), + _dbEnv(&dbEnv), + _envName("External"), + _trace(communicator->getProperties()->getPropertyAsInt("Freeze.Trace.DB")) +{ +} + +void +Freeze::ConnectionI::closeAllIterators() +{ + for(list<DBMapHelperI*>::iterator p = _mapList.begin(); p != _mapList.end(); + ++p) + { + (*p)->closeAllIterators(); + } +} + +void +Freeze::ConnectionI::registerMap(DBMapHelperI* map) +{ + _mapList.push_back(map); +} + +void +Freeze::ConnectionI::unregisterMap(DBMapHelperI* map) +{ + _mapList.remove(map); +} + +Freeze::ConnectionPtr +Freeze::createConnection(const CommunicatorPtr& communicator, + const string& envName) +{ + + return new ConnectionI(communicator, envName); +} + +Freeze::ConnectionPtr +Freeze::createConnection(const CommunicatorPtr& communicator, + DbEnv& dbEnv) +{ + return new ConnectionI(communicator, dbEnv); +} + +void +Freeze::TransactionAlreadyInProgressException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\ntransaction already in progess"; +} diff --git a/cpp/src/Freeze/ConnectionI.h b/cpp/src/Freeze/ConnectionI.h new file mode 100644 index 00000000000..fddadd33858 --- /dev/null +++ b/cpp/src/Freeze/ConnectionI.h @@ -0,0 +1,139 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifndef FREEZE_CONNECTIONI_H +#define FREEZE_CONNECTIONI_H + +#include <Freeze/Connection.h> +#include <Freeze/Initialize.h> +#include <Freeze/TransactionI.h> +#include <Freeze/SharedDbEnv.h> +#include <list> + +namespace Freeze +{ + +class DBMapHelperI; + +class ConnectionI : public Connection +{ +public: + + virtual TransactionPtr + beginTransaction(); + + virtual TransactionPtr + currentTransaction() const; + + virtual void + close(); + + virtual Ice::CommunicatorPtr + getCommunicator() const; + + virtual std::string + getName() const; + + virtual ~ConnectionI(); + + ConnectionI(const Ice::CommunicatorPtr& communicator, + const std::string& envName); + + ConnectionI(const Ice::CommunicatorPtr& communicator, + DbEnv& dbEnv); + + void + closeAllIterators(); + + void + registerMap(DBMapHelperI*); + + void + unregisterMap(DBMapHelperI*); + + void + clearTransaction(); + + DbTxn* + dbTxn() const; + + DbEnv* + dbEnv() const; + + const Ice::CommunicatorPtr& + communicator() const; + + const std::string& + envName() const; + + int + trace() const; + +private: + + Ice::CommunicatorPtr _communicator; + SharedDbEnvPtr _dbEnvHolder; + DbEnv* _dbEnv; + std::string _envName; + TransactionIPtr _transaction; + std::list<DBMapHelperI*> _mapList; + int _trace; +}; + +inline void +ConnectionI::clearTransaction() +{ + _transaction = 0; +} + +inline DbTxn* +ConnectionI::dbTxn() const +{ + if(_transaction == 0) + { + return 0; + } + else + { + return _transaction->dbTxn(); + } +} + +inline DbEnv* +ConnectionI::dbEnv() const +{ + return _dbEnv; +} + +inline const std::string& +ConnectionI::envName() const +{ + return _envName; +} + +inline const Ice::CommunicatorPtr& +ConnectionI::communicator() const +{ + return _communicator; +} + +inline int +ConnectionI::trace() const +{ + return _trace; +} + +} + +#endif diff --git a/cpp/src/Freeze/EvictorI.cpp b/cpp/src/Freeze/EvictorI.cpp index 715de1f4e0b..3f04b77f788 100644 --- a/cpp/src/Freeze/EvictorI.cpp +++ b/cpp/src/Freeze/EvictorI.cpp @@ -205,7 +205,7 @@ Freeze::EvictorI::EvictorI(const Ice::CommunicatorPtr communicator, _noSyncAllowed(false), _generation(0) { - init("Extern", dbName, createDb); + init("External", dbName, createDb); } void diff --git a/cpp/src/Freeze/Makefile b/cpp/src/Freeze/Makefile index 8b0414c4cbc..70bbe8d04c1 100644 --- a/cpp/src/Freeze/Makefile +++ b/cpp/src/Freeze/Makefile @@ -21,18 +21,29 @@ LIBNAME = $(call mklibname,Freeze) TARGETS = $(libdir)/$(LIBFILENAME) $(libdir)/$(SONAME) $(libdir)/$(LIBNAME) -OBJS = DBException.o \ +OBJS = DB.o \ + DBException.o \ Evictor.o \ EvictorF.o \ EvictorStorage.o \ + Connection.o \ + ConnectionF.o \ + ConnectionI.o \ + Transaction.o \ + TransactionI.o \ + SharedDb.o \ MapI.o \ EvictorI.o \ - SharedDbEnv.o + SharedDbEnv.o \ + TransactionHolder.o SRCS = $(OBJS:.o=.cpp) SLICE_SRCS = $(SDIR)/DB.ice \ $(SDIR)/DBException.ice \ + $(SDIR)/Connection.ice \ + $(SDIR)/ConnectionF.ice \ + $(SDIR)/Transaction.ice \ $(SDIR)/Evictor.ice \ $(SDIR)/EvictorF.ice \ $(SDIR)/EvictorStorage.ice diff --git a/cpp/src/Freeze/MapI.cpp b/cpp/src/Freeze/MapI.cpp index daf9358f493..a473af868bb 100644 --- a/cpp/src/Freeze/MapI.cpp +++ b/cpp/src/Freeze/MapI.cpp @@ -14,20 +14,13 @@ #include <Freeze/MapI.h> #include <Freeze/DBException.h> -#include <sys/stat.h> +#include <Freeze/SharedDb.h> #include <stdlib.h> using namespace std; using namespace Ice; using namespace Freeze; -#ifdef _WIN32 -# define FREEZE_DB_MODE 0 -#else -# define FREEZE_DB_MODE (S_IRUSR | S_IWUSR) -#endif - - namespace { @@ -62,27 +55,12 @@ initializeOutDbt(vector<Ice::Byte>& v, Dbt& dbt) // Freeze::DBMapHelper* -Freeze::DBMapHelper::create(const CommunicatorPtr& communicator, - const string& envName, +Freeze::DBMapHelper::create(const Freeze::ConnectionPtr& connection, const string& dbName, bool createDb) { - return new DBMapHelperI(communicator, envName, dbName, createDb); -} - -Freeze::DBMapHelper* -Freeze::DBMapHelper::create(const CommunicatorPtr& communicator, - DbEnv& dbEnv, - const string& dbName, - bool createDb) -{ - return new DBMapHelperI(communicator, dbEnv, dbName, createDb); -} - - -Freeze::DBMapHelper::DBMapHelper(const Ice::CommunicatorPtr& communicator) : - _communicator(communicator) -{ + Freeze::ConnectionIPtr connectionI = Freeze::ConnectionIPtr::dynamicCast(connection); + return new DBMapHelperI(connectionI, dbName, createDb); } Freeze::DBMapHelper::~DBMapHelper() @@ -127,16 +105,15 @@ Freeze::DBIteratorHelperI::DBIteratorHelperI(const DBMapHelperI& m, bool readOnl _dbc(0), _tx(0) { - if(_map._trace >= 3) { - Trace out(_map._communicator->getLogger(), "DB"); - out << "opening iterator on database \"" << _map._dbName.c_str() << "\""; + Trace out(_map._connection->communicator()->getLogger(), "DB"); + out << "opening iterator on database \"" << _map._dbName << "\""; } - DbTxn* txn = 0; + DbTxn* txn = _map._connection->dbTxn(); - if(!readOnly) + if(txn == 0 && !readOnly) { // // Need to start a transaction @@ -147,7 +124,7 @@ Freeze::DBIteratorHelperI::DBIteratorHelperI(const DBMapHelperI& m, bool readOnl try { - m._db.get()->cursor(txn, &_dbc, 0); + _map._db->cursor(txn, &_dbc, 0); } catch(const ::DbException& dx) { @@ -155,6 +132,7 @@ Freeze::DBIteratorHelperI::DBIteratorHelperI(const DBMapHelperI& m, bool readOnl ex.message = dx.what(); throw ex; } + _map._iteratorList.push_back(this); } Freeze::DBIteratorHelperI::DBIteratorHelperI(const DBIteratorHelperI& it) : @@ -164,8 +142,8 @@ Freeze::DBIteratorHelperI::DBIteratorHelperI(const DBIteratorHelperI& it) : { if(_map._trace >= 3) { - Trace out(_map._communicator->getLogger(), "DB"); - out << "duplicating iterator on database \"" << _map._dbName.c_str() << "\""; + Trace out(_map._connection->communicator()->getLogger(), "DB"); + out << "duplicating iterator on database \"" << _map._dbName << "\""; } try @@ -180,33 +158,12 @@ Freeze::DBIteratorHelperI::DBIteratorHelperI(const DBIteratorHelperI& it) : } _tx = it._tx; + _map._iteratorList.push_back(this); } Freeze::DBIteratorHelperI::~DBIteratorHelperI() { - if(_map._trace >= 3) - { - Trace out(_map._communicator->getLogger(), "DB"); - out << "closing iterator on database \"" << _map._dbName.c_str() << "\""; - } - - try - { - _dbc->close(); - } - catch(const ::DbDeadlockException&) - { - // Ignored - } - catch(const ::DbException& dx) - { - DBException ex(__FILE__, __LINE__); - ex.message = dx.what(); - throw ex; - } - _dbc = 0; - - _tx = 0; + close(); } bool @@ -461,6 +418,11 @@ Freeze::DBIteratorHelperI::set(const Value& value) Dbt dbValue; initializeInDbt(value, dbValue); + if(_tx != 0) + { + _map.closeAllIteratorsExcept(_tx); + } + try { int err = _dbc->put(&dbKey, &dbValue, DB_CURRENT); @@ -488,6 +450,11 @@ Freeze::DBIteratorHelperI::set(const Value& value) void Freeze::DBIteratorHelperI::erase() { + if(_tx != 0) + { + _map.closeAllIteratorsExcept(_tx); + } + try { int err = _dbc->del(0); @@ -581,17 +548,56 @@ Freeze::DBIteratorHelperI::equals(const DBIteratorHelper& rhs) const } } -const Ice::CommunicatorPtr& -Freeze::DBIteratorHelperI::getCommunicator() const +void +Freeze::DBIteratorHelperI::close() +{ + if(_dbc != 0) + { + if(_map._trace >= 3) + { + Trace out(_map._connection->communicator()->getLogger(), "DB"); + out << "closing iterator on database \"" << _map._dbName << "\""; + } + + try + { + _dbc->close(); + } + catch(const ::DbDeadlockException& dx) + { + bool raiseException = (_tx == 0); + cleanup(); + if(raiseException) + { + DBDeadlockException ex(__FILE__, __LINE__); + ex.message = dx.what(); + throw ex; + } + } + catch(const ::DbException& dx) + { + cleanup(); + DBException ex(__FILE__, __LINE__); + ex.message = dx.what(); + throw ex; + } + cleanup(); + } +} + +void +Freeze::DBIteratorHelperI::cleanup() { - return _map._communicator; + _dbc = 0; + _map._iteratorList.remove(this); + _tx = 0; } + // // DBIteratorHelperI::Tx // - Freeze::DBIteratorHelperI::Tx::Tx(const DBMapHelperI& m) : _map(m), _txn(0), @@ -599,13 +605,13 @@ Freeze::DBIteratorHelperI::Tx::Tx(const DBMapHelperI& m) : { if(_map._trace >= 3) { - Trace out(_map._communicator->getLogger(), "DB"); - out << "starting transaction for database \"" << _map._dbName.c_str() << "\""; + Trace out(_map._connection->communicator()->getLogger(), "DB"); + out << "starting transaction for database \"" << _map._dbName << "\""; } try { - _map._dbEnv->txn_begin(0, &_txn, 0); + _map._connection->dbEnv()->txn_begin(0, &_txn, 0); } catch(const ::DbException& dx) { @@ -622,8 +628,8 @@ Freeze::DBIteratorHelperI::Tx::~Tx() { if(_map._trace >= 3) { - Trace out(_map._communicator->getLogger(), "DB"); - out << "aborting transaction for database \"" << _map._dbName.c_str() << "\""; + Trace out(_map._connection->communicator()->getLogger(), "DB"); + out << "aborting transaction for database \"" << _map._dbName << "\""; } try @@ -641,7 +647,7 @@ Freeze::DBIteratorHelperI::Tx::~Tx() { if(_map._trace >= 3) { - Trace out(_map._communicator->getLogger(), "DB"); + Trace out(_map._connection->communicator()->getLogger(), "DB"); out << "committing transaction for database \"" << _map._dbName.c_str() << "\""; } @@ -667,11 +673,6 @@ Freeze::DBIteratorHelperI::Tx::~Tx() void Freeze::DBIteratorHelperI::Tx::dead() { - // - // No need for synchronization since DBIteratorHelperI is not - // thread-safe (see Berkeley DB doc) - // - _dead = true; } @@ -682,87 +683,20 @@ Freeze::DBIteratorHelperI::Tx::dead() // -Freeze::DBMapHelperI::DBMapHelperI(const CommunicatorPtr& communicator, - const string& envName, - const string& dbName, +Freeze::DBMapHelperI::DBMapHelperI(const ConnectionIPtr& connection, + const std::string& dbName, bool createDb) : - DBMapHelper(communicator), - _trace(0), - _dbEnv(0), - _dbEnvHolder(SharedDbEnv::get(communicator, envName)), - _dbName(dbName) -{ - _dbEnv = _dbEnvHolder.get(); - openDb(createDb); -} - -Freeze::DBMapHelperI::DBMapHelperI(const CommunicatorPtr& communicator, - DbEnv& dbEnv, - const string& dbName, - bool createDb) : - DBMapHelper(communicator), - _trace(0), - _dbEnv(&dbEnv), - _dbName(dbName) -{ - openDb(createDb); -} - -void -Freeze::DBMapHelperI::openDb(bool createDb) -{ - _trace = _communicator->getProperties()->getPropertyAsInt("Freeze.Trace.DB"); - - try - { - _db.reset(new Db(_dbEnv, 0)); - u_int32_t flags = DB_AUTO_COMMIT | DB_THREAD; - - if(createDb) - { - flags |= DB_CREATE; - } - - if(_trace >= 2) - { - Trace out(_communicator->getLogger(), "DB"); - out << "opening database \"" << _dbName.c_str() << "\""; - } - - _db->open(0, _dbName.c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE); - } - catch(const ::DbException& dx) - { - DBException ex(__FILE__, __LINE__); - ex.message = dx.what(); - throw ex; - } + _connection(connection), + _db(SharedDb::get(connection, dbName, createDb)), + _dbName(dbName), + _trace(connection->trace()) +{ + _connection->registerMap(this); } - Freeze::DBMapHelperI::~DBMapHelperI() { - if(_db.get() != 0) - { - try - { - if(_trace >= 2) - { - Trace out(_communicator->getLogger(), "DB"); - out << "closing database \"" << _dbName.c_str() << "\""; - } - - _db->close(0); - } - catch(const ::DbException& dx) - { - DBException ex(__FILE__, __LINE__); - ex.message = dx.what(); - throw ex; - } - _db.reset(); - } - _dbEnvHolder = 0; + close(); } Freeze::DBIteratorHelper* @@ -784,9 +718,16 @@ Freeze::DBMapHelperI::find(const Key& k, bool readOnly) const } catch(const DBDeadlockException&) { - // - // Ignored, try again - // + if(_connection->dbTxn() != 0) + { + throw; + } + else + { + // + // Ignored, try again + // + } } } } @@ -799,11 +740,18 @@ Freeze::DBMapHelperI::put(const Key& key, const Value& value) initializeInDbt(key, dbKey); initializeInDbt(value, dbValue); + DbTxn* txn = _connection->dbTxn(); + if(txn == 0) + { + closeAllIterators(); + } + for(;;) { try { - int err = _db->put(0, &dbKey, &dbValue, DB_AUTO_COMMIT); + int err = _db->put(txn, &dbKey, &dbValue, + txn != 0 ? 0 : DB_AUTO_COMMIT); if(err == 0) { @@ -817,11 +765,20 @@ Freeze::DBMapHelperI::put(const Key& key, const Value& value) throw DBException(__FILE__, __LINE__); } } - catch(const ::DbDeadlockException&) + catch(const ::DbDeadlockException& dx) { - // - // Ignored, try again - // + if(txn != 0) + { + DBDeadlockException ex(__FILE__, __LINE__); + ex.message = dx.what(); + throw ex; + } + else + { + // + // Ignored, try again + // + } } catch(const ::DbException& dx) { @@ -838,11 +795,17 @@ Freeze::DBMapHelperI::erase(const Key& key) Dbt dbKey; initializeInDbt(key, dbKey); + DbTxn* txn = _connection->dbTxn(); + if(txn == 0) + { + closeAllIterators(); + } + for(;;) { try { - int err = _db->del(0, &dbKey, DB_AUTO_COMMIT); + int err = _db->del(txn, &dbKey, txn != 0 ? 0 : DB_AUTO_COMMIT); if(err == 0) { @@ -858,11 +821,20 @@ Freeze::DBMapHelperI::erase(const Key& key) throw DBException(__FILE__, __LINE__); } } - catch(const ::DbDeadlockException&) + catch(const ::DbDeadlockException& dx) { - // - // Ignored, try again - // + if(txn != 0) + { + DBDeadlockException ex(__FILE__, __LINE__); + ex.message = dx.what(); + throw ex; + } + else + { + // + // Ignored, try again + // + } } catch(const ::DbException& dx) { @@ -889,7 +861,7 @@ Freeze::DBMapHelperI::count(const Key& key) const { try { - int err = _db->get(0, &dbKey, &dbValue, 0); + int err = _db->get(_connection->dbTxn(), &dbKey, &dbValue, 0); if(err == 0) { @@ -905,11 +877,20 @@ Freeze::DBMapHelperI::count(const Key& key) const throw DBException(__FILE__, __LINE__); } } - catch(const ::DbDeadlockException&) + catch(const ::DbDeadlockException& dx) { - // - // Ignored, try again - // + if(_connection->dbTxn() != 0) + { + DBDeadlockException ex(__FILE__, __LINE__); + ex.message = dx.what(); + throw ex; + } + else + { + // + // Ignored, try again + // + } } catch(const ::DbException& dx) { @@ -923,20 +904,35 @@ Freeze::DBMapHelperI::count(const Key& key) const void Freeze::DBMapHelperI::clear() { + DbTxn* txn = _connection->dbTxn(); + if(txn == 0) + { + closeAllIterators(); + } + for(;;) { try { u_int32_t count; - int err = _db->truncate(0, &count, DB_AUTO_COMMIT); + int err = _db->truncate(txn, &count, txn != 0 ? 0 : DB_AUTO_COMMIT); assert(err == 0); break; } - catch(const ::DbDeadlockException&) + catch(const ::DbDeadlockException& dx) { - // - // Ignored, try again - // + if(txn != 0) + { + DBDeadlockException ex(__FILE__, __LINE__); + ex.message = dx.what(); + throw ex; + } + else + { + // + // Ignored, try again + // + } } catch(const ::DbException& dx) { @@ -950,13 +946,16 @@ Freeze::DBMapHelperI::clear() void Freeze::DBMapHelperI::destroy() { - try + DbTxn* txn = _connection->dbTxn(); + if(txn == 0) { - _db->close(0); - _db.reset(); + closeAllIterators(); + } - Db db(_dbEnv, 0); - db.remove(_dbName.c_str(), 0, 0); + try + { + close(); + _connection->dbEnv()->dbremove(txn, _dbName.c_str(), 0, txn != 0 ? 0 : DB_AUTO_COMMIT); } catch(const ::DbException& dx) { @@ -967,7 +966,6 @@ Freeze::DBMapHelperI::destroy() } - size_t Freeze::DBMapHelperI::size() const { @@ -983,6 +981,45 @@ Freeze::DBMapHelperI::size() const } +void +Freeze::DBMapHelperI::closeAllIterators() +{ + while(!_iteratorList.empty()) + { + (*_iteratorList.begin())->close(); + } +} + +void +Freeze::DBMapHelperI::close() +{ + if(_db != 0) + { + _connection->unregisterMap(this); + } + _db = 0; +} + +void +Freeze::DBMapHelperI::closeAllIteratorsExcept(const DBIteratorHelperI::TxPtr& tx) const +{ + assert(tx != 0); + + list<DBIteratorHelperI*>::iterator q = _iteratorList.begin(); + + while(q != _iteratorList.end()) + { + if((*q)->tx().get() == tx.get()) + { + ++q; + } + else + { + (*q)->close(); + q = _iteratorList.begin(); + } + } +} // // Print for the various exception types. diff --git a/cpp/src/Freeze/MapI.h b/cpp/src/Freeze/MapI.h index 0e3054751e8..2d3898dec0b 100644 --- a/cpp/src/Freeze/MapI.h +++ b/cpp/src/Freeze/MapI.h @@ -16,7 +16,7 @@ #define FREEZE_MAP_I_H #include <Freeze/Map.h> -#include <Freeze/SharedDbEnv.h> +#include <Freeze/SharedDb.h> namespace Freeze { @@ -62,9 +62,8 @@ public: virtual bool equals(const DBIteratorHelper&) const; - virtual const Ice::CommunicatorPtr& - getCommunicator() const; - + void + close(); class Tx : public IceUtil::SimpleShared { @@ -88,8 +87,15 @@ public: typedef IceUtil::Handle<Tx> TxPtr; + const TxPtr& + tx() const; + private: + void + cleanup(); + + const DBMapHelperI& _map; Dbc* _dbc; TxPtr _tx; @@ -99,17 +105,11 @@ private: }; - class DBMapHelperI : public DBMapHelper { public: - DBMapHelperI(const Ice::CommunicatorPtr& communicator, - const std::string& envName, const std::string& dbName, - bool createDb); - - DBMapHelperI(const Ice::CommunicatorPtr& communicator, - DbEnv& dbEnv, const std::string& dbName, + DBMapHelperI(const ConnectionIPtr& connection, const std::string& dbName, bool createDb); virtual ~DBMapHelperI(); @@ -135,22 +135,33 @@ public: virtual size_t size() const; + virtual void + closeAllIterators(); + + void + close(); + private: - void - openDb(bool); + virtual void + closeAllIteratorsExcept(const DBIteratorHelperI::TxPtr&) const; + friend class DBIteratorHelperI; friend class DBIteratorHelperI::Tx; - int _trace; - DbEnv* _dbEnv; - SharedDbEnvPtr _dbEnvHolder; - std::auto_ptr<Db> _db; + const ConnectionIPtr _connection; + mutable std::list<DBIteratorHelperI*> _iteratorList; + SharedDbPtr _db; const std::string _dbName; + int _trace; }; - +inline const DBIteratorHelperI::TxPtr& +DBIteratorHelperI::tx() const +{ + return _tx; +} } diff --git a/cpp/src/Freeze/SharedDb.cpp b/cpp/src/Freeze/SharedDb.cpp new file mode 100644 index 00000000000..8185669e2f4 --- /dev/null +++ b/cpp/src/Freeze/SharedDb.cpp @@ -0,0 +1,170 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#include <Freeze/SharedDb.h> +#include <IceUtil/StaticMutex.h> +#include <Freeze/DBException.h> +#include <sys/stat.h> + +using namespace std; +using namespace IceUtil; +using namespace Ice; + +#ifdef _WIN32 +# define FREEZE_DB_MODE 0 +#else +# define FREEZE_DB_MODE (S_IRUSR | S_IWUSR) +#endif + +namespace +{ + +StaticMutex _mapMutex = ICE_STATIC_MUTEX_INITIALIZER; +StaticMutex _refCountMutex = ICE_STATIC_MUTEX_INITIALIZER; + +} + +Freeze::SharedDb::Map* Freeze::SharedDb::sharedDbMap = 0; + +Freeze::SharedDbPtr +Freeze::SharedDb::get(const ConnectionIPtr& connection, + const string& dbName, bool createDb) +{ + StaticMutex::Lock lock(_mapMutex); + + if(sharedDbMap == 0) + { + sharedDbMap = new Map; + } + + MapKey key; + key.envName = connection->envName(); + key.communicator = connection->communicator(); + key.dbName = dbName; + + { + Map::iterator p = sharedDbMap->find(key); + if(p != sharedDbMap->end()) + { + return p->second; + } + } + + // + // MapKey not found, let's create and open a new Db + // + auto_ptr<SharedDb> result(new SharedDb(key, connection, createDb)); + + // + // Insert it into the map + // + pair<Map::iterator, bool> insertResult = sharedDbMap->insert(Map::value_type(key, result.get())); + assert(insertResult.second); + + return result.release(); +} + +Freeze::SharedDb::~SharedDb() +{ + if(_trace >= 1) + { + Trace out(_key.communicator->getLogger(), "DB"); + out << "closing database \"" << _key.dbName << "\""; + } + + try + { + close(0); + } + catch(const ::DbException& dx) + { + DBException ex(__FILE__, __LINE__); + ex.message = dx.what(); + throw ex; + } + +} + +void Freeze::SharedDb::__incRef() +{ + IceUtil::StaticMutex::Lock lock(_refCountMutex); + _refCount++; +} + +void Freeze::SharedDb::__decRef() +{ + IceUtil::StaticMutex::Lock lock(_refCountMutex); + if(--_refCount == 0) + { + IceUtil::StaticMutex::TryLock mapLock(_mapMutex); + if(!mapLock.acquired()) + { + // + // Reacquire mutex in proper order and check again + // + lock.release(); + mapLock.acquire(); + lock.acquire(); + if(_refCount > 0) + { + return; + } + } + + // + // Remove from map + // + size_t one = sharedDbMap->erase(_key); + assert(one == 1); + + if(sharedDbMap->size() == 0) + { + delete sharedDbMap; + sharedDbMap = 0; + } + + // + // Keep lock to prevent somebody else to re-open this Db + // before it's closed. + // + delete this; + } +} + + + +Freeze::SharedDb::SharedDb(const MapKey& key, + const ConnectionIPtr& connection, + bool createDb) : + Db(connection->dbEnv(), 0), + _key(key), + _refCount(0), + _trace(connection->trace()) +{ + try + { + u_int32_t flags = DB_AUTO_COMMIT | DB_THREAD; + if(createDb) + { + flags |= DB_CREATE; + } + open(0, key.dbName.c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE); + } + catch(const ::DbException& dx) + { + DBException ex(__FILE__, __LINE__); + ex.message = dx.what(); + throw ex; + } +} diff --git a/cpp/src/Freeze/SharedDb.h b/cpp/src/Freeze/SharedDb.h new file mode 100644 index 00000000000..52da8e4010c --- /dev/null +++ b/cpp/src/Freeze/SharedDb.h @@ -0,0 +1,83 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifndef FREEZE_SHARED_DB_H +#define FREEZE_SHARED_DB_H + +#include <Freeze/ConnectionI.h> +#include <IceUtil/Handle.h> +#include <db_cxx.h> +#include <map> + +namespace Freeze +{ + +class SharedDb; +typedef IceUtil::Handle<SharedDb> SharedDbPtr; + +class SharedDb : public ::Db +{ +public: + + using ::Db::get; + + static SharedDbPtr get(const ConnectionIPtr&, const std::string&, bool); + + ~SharedDb(); + + void __incRef(); + void __decRef(); + + const std::string& + dbName() const; + +private: + + struct MapKey + { + std::string envName; + Ice::CommunicatorPtr communicator; + std::string dbName; + + inline bool + operator<(const MapKey& rhs) const; + }; + + typedef std::map<MapKey, Freeze::SharedDb*> Map; + + SharedDb(const MapKey&, const ConnectionIPtr&, bool); + + MapKey _key; + int _refCount; + int _trace; + + static Map* sharedDbMap; +}; + +inline const std::string& +SharedDb::dbName() const +{ + return _key.dbName; +} + +inline bool +SharedDb::MapKey::operator<(const MapKey& rhs) const +{ + return (communicator < rhs.communicator) || + ((communicator == rhs.communicator) && (dbName < rhs.dbName)) || + ((communicator == rhs.communicator) && (dbName == rhs.dbName) && (envName < rhs.envName)); +} + +} +#endif diff --git a/cpp/src/Freeze/SharedDbEnv.h b/cpp/src/Freeze/SharedDbEnv.h index 152985c7a7e..20874777d71 100644 --- a/cpp/src/Freeze/SharedDbEnv.h +++ b/cpp/src/Freeze/SharedDbEnv.h @@ -12,8 +12,8 @@ // // ********************************************************************** -#ifndef FREEZE_DB_ENV_MAP_H -#define FREEZE_DB_ENV_MAP_H +#ifndef FREEZE_SHARED_DB_ENV_H +#define FREEZE_SHARED_DB_ENV_H #include <Ice/Config.h> #include <Ice/Ice.h> diff --git a/cpp/src/Freeze/TransactionHolder.cpp b/cpp/src/Freeze/TransactionHolder.cpp new file mode 100644 index 00000000000..8b758624467 --- /dev/null +++ b/cpp/src/Freeze/TransactionHolder.cpp @@ -0,0 +1,76 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#include <Freeze/TransactionHolder.h> + +using namespace Freeze; + +Freeze::TransactionHolder::TransactionHolder(const ConnectionPtr& connection) + : _transaction(0) +{ + if(connection->currentTransaction() == 0) + { + _transaction = connection->beginTransaction(); + } +} + +Freeze::TransactionHolder::~TransactionHolder() +{ + try + { + rollback(); + } + catch(...) + { + // + // Ignored to avoid crash during stack unwinding + // + } +} + +void +Freeze::TransactionHolder::commit() +{ + if(_transaction != 0) + { + try + { + _transaction->commit(); + _transaction = 0; + } + catch(...) + { + _transaction = 0; + throw; + } + } +} + +void +Freeze::TransactionHolder::rollback() +{ + if(_transaction != 0) + { + try + { + _transaction->rollback(); + _transaction = 0; + } + catch(...) + { + _transaction = 0; + throw; + } + } +} diff --git a/cpp/src/Freeze/TransactionI.cpp b/cpp/src/Freeze/TransactionI.cpp new file mode 100644 index 00000000000..0e28f9c9acf --- /dev/null +++ b/cpp/src/Freeze/TransactionI.cpp @@ -0,0 +1,103 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#include <Freeze/TransactionI.h> +#include <Freeze/ConnectionI.h> +#include <Freeze/DBException.h> + + +void +Freeze::TransactionI::commit() +{ + assert(_txn != 0); + try + { + _connection->closeAllIterators(); + _txn->commit(0); + } + catch(const ::DbDeadlockException& dx) + { + cleanup(); + DBDeadlockException ex(__FILE__, __LINE__); + ex.message = dx.what(); + throw ex; + } + catch(const ::DbException& dx) + { + cleanup(); + DBException ex(__FILE__, __LINE__); + ex.message = dx.what(); + throw ex; + } + cleanup(); +} + +void +Freeze::TransactionI::rollback() +{ + assert(_txn != 0); + + try + { + _connection->closeAllIterators(); + _txn->abort(); + } + catch(const ::DbDeadlockException& dx) + { + cleanup(); + DBDeadlockException ex(__FILE__, __LINE__); + ex.message = dx.what(); + throw ex; + } + catch(const ::DbException& dx) + { + cleanup(); + DBException ex(__FILE__, __LINE__); + ex.message = dx.what(); + throw ex; + } + cleanup(); +} + +Freeze::TransactionI::TransactionI(ConnectionI* connection) : + _connection(connection), + _txn(0) +{ + try + { + _connection->dbEnv()->txn_begin(0, &_txn, 0); + } + catch(const ::DbException& dx) + { + DBException ex(__FILE__, __LINE__); + ex.message = dx.what(); + throw ex; + } +} + +Freeze::TransactionI::~TransactionI() +{ + if(_txn != 0) + { + rollback(); + } +} + +void +Freeze::TransactionI::cleanup() +{ + _connection->clearTransaction(); + _connection = 0; + _txn = 0; +} diff --git a/cpp/src/Freeze/TransactionI.h b/cpp/src/Freeze/TransactionI.h new file mode 100644 index 00000000000..e3e4e73ef9f --- /dev/null +++ b/cpp/src/Freeze/TransactionI.h @@ -0,0 +1,59 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifndef FREEZE_TRANSACTIONI_H +#define FREEZE_TRANSACTIONI_H + +#include <Freeze/Transaction.h> +#include <db_cxx.h> + +namespace Freeze +{ + +class ConnectionI; +typedef IceUtil::Handle<ConnectionI> ConnectionIPtr; + +class TransactionI : public Transaction +{ +public: + + virtual void + commit(); + + virtual void + rollback(); + + TransactionI(ConnectionI*); + + ~TransactionI(); + + DbTxn* + dbTxn() const + { + return _txn; + } + +private: + + void + cleanup(); + + ConnectionIPtr _connection; + DbTxn* _txn; +}; + +typedef IceUtil::Handle<TransactionI> TransactionIPtr; + +} +#endif diff --git a/cpp/src/Freeze/freeze.dsp b/cpp/src/Freeze/freeze.dsp index 63dcbd12a8c..579d5b2d8c7 100644 --- a/cpp/src/Freeze/freeze.dsp +++ b/cpp/src/Freeze/freeze.dsp @@ -114,6 +114,18 @@ SOURCE=.\DBException.cpp # End Source File
# Begin Source File
+SOURCE=.\Connection.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConnectionF.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Transaction.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\Evictor.cpp
# End Source File
# Begin Source File
@@ -126,6 +138,22 @@ SOURCE=.\MapI.cpp # End Source File
# Begin Source File
+SOURCE=.\ConnectionI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TransactionHolder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TransactionI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SharedDb.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\EvictorStorage.cpp
# End Source File
# Begin Source File
@@ -150,11 +178,31 @@ SOURCE=..\..\include\Freeze\DBException.h # End Source File
# Begin Source File
-SOURCE=..\..\include\Freeze\DBF.h
+SOURCE=..\..\include\Freeze\Connection.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\Freeze\ConnectionF.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\Freeze\Transaction.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\Freeze\TransactionHolder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TransactionI.h
# End Source File
# Begin Source File
-SOURCE=.\DBI.h
+SOURCE=.\ConnectionI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MapI.h
# End Source File
# Begin Source File
@@ -288,6 +336,135 @@ BuildCmds= \ # End Source File
# Begin Source File
+SOURCE=..\..\slice\Freeze\Connection.ice
+
+!IF "$(CFG)" == "Freeze - Win32 Release"
+
+USERDEP__DBEXC="..\..\bin\slice2cpp.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=..\..\slice\Freeze\Connection.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --dll-export FREEZE_API --include-dir Freeze -I../../slice ../../slice/Freeze/Connection.ice \
+ move Connection.h ..\..\include\Freeze \
+
+
+"..\..\include\Freeze\Connection.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Connection.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "Freeze - Win32 Debug"
+
+USERDEP__DBEXC="..\..\bin\slice2cpp.exe"
+# Begin Custom Build
+InputPath=..\..\slice\Freeze\Connection.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --dll-export FREEZE_API --include-dir Freeze -I../../slice ../../slice/Freeze/Connection.ice \
+ move Connection.h ..\..\include\Freeze \
+
+
+"..\..\include\Freeze\Connection.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Connection.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\slice\Freeze\ConnectionF.ice
+
+!IF "$(CFG)" == "Freeze - Win32 Release"
+
+USERDEP__DBEXC="..\..\bin\slice2cpp.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=..\..\slice\Freeze\ConnectionF.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --dll-export FREEZE_API --include-dir Freeze -I../../slice ../../slice/Freeze/ConnectionF.ice \
+ move ConnectionF.h ..\..\include\Freeze \
+
+
+"..\..\include\Freeze\ConnectionF.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"ConnectionF.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "Freeze - Win32 Debug"
+
+USERDEP__DBEXC="..\..\bin\slice2cpp.exe"
+# Begin Custom Build
+InputPath=..\..\slice\Freeze\ConnectionF.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --dll-export FREEZE_API --include-dir Freeze -I../../slice ../../slice/Freeze/ConnectionF.ice \
+ move ConnectionF.h ..\..\include\Freeze \
+
+
+"..\..\include\Freeze\ConnectionF.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"ConnectionF.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\slice\Freeze\Transaction.ice
+
+!IF "$(CFG)" == "Freeze - Win32 Release"
+
+USERDEP__DBEXC="..\..\bin\slice2cpp.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=..\..\slice\Freeze\Transaction.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --dll-export FREEZE_API --include-dir Freeze -I../../slice ../../slice/Freeze/Transaction.ice \
+ move Transaction.h ..\..\include\Freeze \
+
+
+"..\..\include\Freeze\Transaction.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Transaction.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "Freeze - Win32 Debug"
+
+USERDEP__DBEXC="..\..\bin\slice2cpp.exe"
+# Begin Custom Build
+InputPath=..\..\slice\Freeze\Transaction.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --dll-export FREEZE_API --include-dir Freeze -I../../slice ../../slice/Freeze/Transaction.ice \
+ move Transaction.h ..\..\include\Freeze \
+
+
+"..\..\include\Freeze\Transaction.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Transaction.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
SOURCE=..\..\slice\Freeze\Evictor.ice
!IF "$(CFG)" == "Freeze - Win32 Release"
diff --git a/cpp/src/IcePack/AdapterRegistryI.cpp b/cpp/src/IcePack/AdapterRegistryI.cpp index abd2b465bcf..26d3dca3da2 100644 --- a/cpp/src/IcePack/AdapterRegistryI.cpp +++ b/cpp/src/IcePack/AdapterRegistryI.cpp @@ -14,6 +14,7 @@ #include <IcePack/AdapterRegistryI.h> #include <IcePack/TraceLevels.h> +#include <Freeze/Initialize.h> using namespace std; using namespace IcePack; @@ -21,16 +22,23 @@ using namespace IcePack; IcePack::AdapterRegistryI::AdapterRegistryI(const Ice::CommunicatorPtr& communicator, const string& envName, const string& dbName, const TraceLevelsPtr& traceLevels) : - _dict(communicator, envName, dbName), - _traceLevels(traceLevels) + _connectionCache(Freeze::createConnection(communicator, envName)), + _dictCache(_connectionCache, dbName), + _traceLevels(traceLevels), + _envName(envName), + _communicator(communicator), + _dbName(dbName) { } void IcePack::AdapterRegistryI::add(const string& id, const AdapterPrx& adapter, const Ice::Current&) { - StringObjectProxyDict::iterator p = _dict.find(id); - if(p != _dict.end()) + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(id); + if(p != dict.end()) { try { @@ -53,7 +61,7 @@ IcePack::AdapterRegistryI::add(const string& id, const AdapterPrx& adapter, cons } throw AdapterExistsException(); } - _dict.put(pair<const string, const Ice::ObjectPrx>(id, adapter)); + dict.put(pair<const string, const Ice::ObjectPrx>(id, adapter)); if(_traceLevels->adapterRegistry > 0) { @@ -65,13 +73,16 @@ IcePack::AdapterRegistryI::add(const string& id, const AdapterPrx& adapter, cons void IcePack::AdapterRegistryI::remove(const string& id, const Ice::Current&) { - StringObjectProxyDict::iterator p = _dict.find(id); - if(p == _dict.end()) + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(id); + if(p == dict.end()) { throw AdapterNotExistException(); } - _dict.erase(p); + dict.erase(p); if(_traceLevels->adapterRegistry > 0) { @@ -83,8 +94,11 @@ IcePack::AdapterRegistryI::remove(const string& id, const Ice::Current&) AdapterPrx IcePack::AdapterRegistryI::findById(const string& id, const Ice::Current&) { - StringObjectProxyDict::iterator p = _dict.find(id); - if(p != _dict.end()) + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(id); + if(p != dict.end()) { try { @@ -92,7 +106,7 @@ IcePack::AdapterRegistryI::findById(const string& id, const Ice::Current&) } catch(const Ice::ObjectNotExistException&) { - _dict.erase(p); + dict.erase(p); } catch(const Ice::LocalException&) { @@ -105,10 +119,13 @@ IcePack::AdapterRegistryI::findById(const string& id, const Ice::Current&) Ice::StringSeq IcePack::AdapterRegistryI::getAll(const Ice::Current&) const { + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + Ice::StringSeq ids; - ids.reserve(_dict.size()); + ids.reserve(dict.size()); - for(StringObjectProxyDict::const_iterator p = _dict.begin(); p != _dict.end(); ++p) + for(StringObjectProxyDict::const_iterator p = dict.begin(); p != dict.end(); ++p) { ids.push_back(p->first); } diff --git a/cpp/src/IcePack/AdapterRegistryI.h b/cpp/src/IcePack/AdapterRegistryI.h index 9378b691747..7361c0f8d24 100644 --- a/cpp/src/IcePack/AdapterRegistryI.h +++ b/cpp/src/IcePack/AdapterRegistryI.h @@ -38,8 +38,13 @@ public: private: - StringObjectProxyDict _dict; + Freeze::ConnectionPtr _connectionCache; + StringObjectProxyDict _dictCache; TraceLevelsPtr _traceLevels; + const std::string _envName; + const Ice::CommunicatorPtr _communicator; + const std::string _dbName; + }; } diff --git a/cpp/src/IcePack/NodeRegistryI.cpp b/cpp/src/IcePack/NodeRegistryI.cpp index bc4327f70b9..6b86c16c743 100644 --- a/cpp/src/IcePack/NodeRegistryI.cpp +++ b/cpp/src/IcePack/NodeRegistryI.cpp @@ -15,6 +15,7 @@ #include <IcePack/NodeRegistryI.h> #include <IcePack/AdapterFactory.h> #include <IcePack/TraceLevels.h> +#include <Freeze/Initialize.h> using namespace std; using namespace IcePack; @@ -25,12 +26,16 @@ IcePack::NodeRegistryI::NodeRegistryI(const Ice::CommunicatorPtr& communicator, const AdapterRegistryPtr& adapterRegistry, const AdapterFactoryPtr& adapterFactory, const TraceLevelsPtr& traceLevels) : - _dict(communicator, envName, dbName), + _connectionCache(Freeze::createConnection(communicator, envName)), + _dictCache(_connectionCache, dbName), _adapterRegistry(adapterRegistry), _adapterFactory(adapterFactory), - _traceLevels(traceLevels) + _traceLevels(traceLevels), + _envName(envName), + _communicator(communicator), + _dbName(dbName) { - for(StringObjectProxyDict::const_iterator p = _dict.begin(); p != _dict.end(); ++p) + for(StringObjectProxyDict::const_iterator p = _dictCache.begin(); p != _dictCache.end(); ++p) { NodePrx node = NodePrx::uncheckedCast(p->second); try @@ -52,8 +57,11 @@ IcePack::NodeRegistryI::add(const string& name, const NodePrx& node, const Ice:: { IceUtil::Mutex::Lock sync(*this); - StringObjectProxyDict::iterator p = _dict.find(name); - if(p != _dict.end()) + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(name); + if(p != dict.end()) { try { @@ -76,7 +84,7 @@ IcePack::NodeRegistryI::add(const string& name, const NodePrx& node, const Ice:: } else { - _dict.put(pair<const string, const Ice::ObjectPrx>(name, node)); + dict.put(pair<const string, const Ice::ObjectPrx>(name, node)); if(_traceLevels->nodeRegistry > 0) { @@ -120,13 +128,17 @@ IcePack::NodeRegistryI::remove(const string& name, const Ice::Current&) { IceUtil::Mutex::Lock sync(*this); - StringObjectProxyDict::iterator p = _dict.find(name); - if(p == _dict.end()) + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + + StringObjectProxyDict::iterator p = dict.find(name); + if(p == dict.end()) { throw NodeNotExistException(); } - _dict.erase(p); + dict.erase(p); if(_traceLevels->nodeRegistry > 0) { @@ -151,8 +163,11 @@ IcePack::NodeRegistryI::remove(const string& name, const Ice::Current&) NodePrx IcePack::NodeRegistryI::findByName(const string& name, const Ice::Current&) { - StringObjectProxyDict::const_iterator p = _dict.find(name); - if(p != _dict.end()) + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::const_iterator p = dict.find(name); + if(p != dict.end()) { try { @@ -172,10 +187,13 @@ IcePack::NodeRegistryI::findByName(const string& name, const Ice::Current&) Ice::StringSeq IcePack::NodeRegistryI::getAll(const Ice::Current&) const { + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + Ice::StringSeq names; - names.reserve(_dict.size()); + names.reserve(dict.size()); - for(StringObjectProxyDict::const_iterator p = _dict.begin(); p != _dict.end(); ++p) + for(StringObjectProxyDict::const_iterator p = dict.begin(); p != dict.end(); ++p) { names.push_back(p->first); } diff --git a/cpp/src/IcePack/NodeRegistryI.h b/cpp/src/IcePack/NodeRegistryI.h index 3da69bb4ed9..d2b4a74767f 100644 --- a/cpp/src/IcePack/NodeRegistryI.h +++ b/cpp/src/IcePack/NodeRegistryI.h @@ -42,10 +42,14 @@ public: private: - StringObjectProxyDict _dict; + Freeze::ConnectionPtr _connectionCache; + StringObjectProxyDict _dictCache; AdapterRegistryPtr _adapterRegistry; AdapterFactoryPtr _adapterFactory; TraceLevelsPtr _traceLevels; + const std::string _envName; + const Ice::CommunicatorPtr _communicator; + const std::string _dbName; }; } diff --git a/cpp/src/IcePack/ObjectRegistryI.cpp b/cpp/src/IcePack/ObjectRegistryI.cpp index 6f636313d3a..4278c96e7e9 100644 --- a/cpp/src/IcePack/ObjectRegistryI.cpp +++ b/cpp/src/IcePack/ObjectRegistryI.cpp @@ -14,6 +14,7 @@ #include <IcePack/ObjectRegistryI.h> #include <IcePack/TraceLevels.h> +#include <Freeze/Initialize.h> using namespace std; using namespace IcePack; @@ -23,8 +24,9 @@ IcePack::ObjectRegistryI::ObjectRegistryI(const Ice::CommunicatorPtr& communicat const string& objectsDbName, const string& typesDbName, const TraceLevelsPtr& traceLevels) : - _objects(communicator, envName, objectsDbName, true), - _types(communicator, envName, typesDbName, true), + _connection(Freeze::createConnection(communicator, envName)), + _objects(_connection, objectsDbName, true), + _types(_connection, typesDbName, true), _traceLevels(traceLevels) { } diff --git a/cpp/src/IcePack/ObjectRegistryI.h b/cpp/src/IcePack/ObjectRegistryI.h index 0553073e1a4..fd73eb78818 100644 --- a/cpp/src/IcePack/ObjectRegistryI.h +++ b/cpp/src/IcePack/ObjectRegistryI.h @@ -18,6 +18,7 @@ #include <IcePack/Internal.h> #include <IcePack/IdentityObjectDescDict.h> #include <IcePack/StringObjectProxySeqDict.h> +#include <Freeze/ConnectionF.h> namespace IcePack { @@ -46,6 +47,7 @@ public: private: + Freeze::ConnectionPtr _connection; IdentityObjectDescDict _objects; StringObjectProxySeqDict _types; TraceLevelsPtr _traceLevels; diff --git a/cpp/src/IcePack/ServerRegistryI.cpp b/cpp/src/IcePack/ServerRegistryI.cpp index 036a63d5d0e..a279de7665d 100644 --- a/cpp/src/IcePack/ServerRegistryI.cpp +++ b/cpp/src/IcePack/ServerRegistryI.cpp @@ -14,6 +14,7 @@ #include <IcePack/ServerRegistryI.h> #include <IcePack/TraceLevels.h> +#include <Freeze/Initialize.h> using namespace std; using namespace IcePack; @@ -21,16 +22,23 @@ using namespace IcePack; IcePack::ServerRegistryI::ServerRegistryI(const Ice::CommunicatorPtr& communicator, const string& envName, const string& dbName, const TraceLevelsPtr& traceLevels) : - _dict(communicator, envName, dbName), - _traceLevels(traceLevels) + _connectionCache(Freeze::createConnection(communicator, envName)), + _dictCache(_connectionCache, dbName), + _traceLevels(traceLevels), + _envName(envName), + _communicator(communicator), + _dbName(dbName) { } void IcePack::ServerRegistryI::add(const string& name, const ServerPrx& server, const Ice::Current&) { - StringObjectProxyDict::iterator p = _dict.find(name); - if(p != _dict.end()) + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(name); + if(p != dict.end()) { try { @@ -54,7 +62,7 @@ IcePack::ServerRegistryI::add(const string& name, const ServerPrx& server, const throw ServerExistsException(); } - _dict.put(pair<const string, const Ice::ObjectPrx>(name, server)); + dict.put(pair<const string, const Ice::ObjectPrx>(name, server)); if(_traceLevels->serverRegistry > 0) { @@ -66,13 +74,16 @@ IcePack::ServerRegistryI::add(const string& name, const ServerPrx& server, const void IcePack::ServerRegistryI::remove(const string& name, const Ice::Current&) { - StringObjectProxyDict::iterator p = _dict.find(name); - if(p == _dict.end()) + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(name); + if(p == dict.end()) { throw ServerNotExistException(); } - _dict.erase(p); + dict.erase(p); if(_traceLevels->serverRegistry > 0) { @@ -84,8 +95,11 @@ IcePack::ServerRegistryI::remove(const string& name, const Ice::Current&) ServerPrx IcePack::ServerRegistryI::findByName(const string& name, const Ice::Current&) { - StringObjectProxyDict::iterator p = _dict.find(name); - if(p != _dict.end()) + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(name); + if(p != dict.end()) { try { @@ -93,7 +107,7 @@ IcePack::ServerRegistryI::findByName(const string& name, const Ice::Current&) } catch(const Ice::ObjectNotExistException&) { - _dict.erase(p); + dict.erase(p); } catch(const Ice::LocalException&) { @@ -106,10 +120,13 @@ IcePack::ServerRegistryI::findByName(const string& name, const Ice::Current&) Ice::StringSeq IcePack::ServerRegistryI::getAll(const Ice::Current&) const { + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + Ice::StringSeq names; - names.reserve(_dict.size()); + names.reserve(dict.size()); - for(StringObjectProxyDict::const_iterator p = _dict.begin(); p != _dict.end(); ++p) + for(StringObjectProxyDict::const_iterator p = dict.begin(); p != dict.end(); ++p) { names.push_back(p->first); } diff --git a/cpp/src/IcePack/ServerRegistryI.h b/cpp/src/IcePack/ServerRegistryI.h index 165b6a7def9..232d9d0d6e2 100644 --- a/cpp/src/IcePack/ServerRegistryI.h +++ b/cpp/src/IcePack/ServerRegistryI.h @@ -38,8 +38,12 @@ public: private: - StringObjectProxyDict _dict; + Freeze::ConnectionPtr _connectionCache; + StringObjectProxyDict _dictCache; TraceLevelsPtr _traceLevels; + const std::string _envName; + const Ice::CommunicatorPtr _communicator; + const std::string _dbName; }; } diff --git a/cpp/src/IceStorm/Service.cpp b/cpp/src/IceStorm/Service.cpp index 2861657f620..e79546a680d 100644 --- a/cpp/src/IceStorm/Service.cpp +++ b/cpp/src/IceStorm/Service.cpp @@ -99,5 +99,5 @@ IceStorm::ServiceI::stop() // // It's necessary to reap all destroyed topics on shutdown. // - _manager->reap(); + _manager->shutdown(); } diff --git a/cpp/src/IceStorm/TopicI.cpp b/cpp/src/IceStorm/TopicI.cpp index c907fdc814a..674cd4c3f4b 100644 --- a/cpp/src/IceStorm/TopicI.cpp +++ b/cpp/src/IceStorm/TopicI.cpp @@ -18,8 +18,10 @@ #include <IceStorm/SubscriberFactory.h> #include <IceStorm/Subscriber.h> #include <IceStorm/TraceLevels.h> +#include <Freeze/Initialize.h> #include <algorithm> + using namespace IceStorm; using namespace std; @@ -301,7 +303,8 @@ TopicI::TopicI(const Ice::ObjectAdapterPtr& adapter, const TraceLevelsPtr& trace _name(name), _factory(factory), _destroyed(false), - _links(adapter->getCommunicator(), envName, dbName, createDb) + _connection(Freeze::createConnection(adapter->getCommunicator(), envName)), + _links(_connection, dbName, createDb) { _subscribers = new TopicSubscribers(_traceLevels); diff --git a/cpp/src/IceStorm/TopicI.h b/cpp/src/IceStorm/TopicI.h index e69238062be..76e1c7b15c5 100644 --- a/cpp/src/IceStorm/TopicI.h +++ b/cpp/src/IceStorm/TopicI.h @@ -117,6 +117,7 @@ private: TopicSubscribersPtr _subscribers; // Set of Subscribers + Freeze::ConnectionPtr _connection; IdentityLinkDict _links; // The database of Topic links }; diff --git a/cpp/src/IceStorm/TopicManagerI.cpp b/cpp/src/IceStorm/TopicManagerI.cpp index 009574b7706..444d734f153 100644 --- a/cpp/src/IceStorm/TopicManagerI.cpp +++ b/cpp/src/IceStorm/TopicManagerI.cpp @@ -17,6 +17,7 @@ #include <IceStorm/TopicI.h> #include <IceStorm/Flusher.h> #include <IceStorm/TraceLevels.h> +#include <Freeze/Initialize.h> #include <functional> #include <ctype.h> @@ -32,7 +33,8 @@ TopicManagerI::TopicManagerI(const Ice::CommunicatorPtr& communicator, const Ice _publishAdapter(publishAdapter), _traceLevels(traceLevels), _envName(envName), - _topics(_communicator, envName, dbName) + _connection(Freeze::createConnection(_communicator, envName)), + _topics(_connection, dbName) { _flusher = new Flusher(_communicator, _traceLevels); _factory = new SubscriberFactory(_communicator, _traceLevels, _flusher); @@ -195,6 +197,13 @@ TopicManagerI::reap() } void +TopicManagerI::shutdown() +{ + IceUtil::Mutex::Lock sync(*this); + reap(); +} + +void TopicManagerI::installTopic(const string& message, const string& name, bool create) { if(_traceLevels->topicMgr > 0) diff --git a/cpp/src/IceStorm/TopicManagerI.h b/cpp/src/IceStorm/TopicManagerI.h index 88b32e668ef..a50d3de8310 100644 --- a/cpp/src/IceStorm/TopicManagerI.h +++ b/cpp/src/IceStorm/TopicManagerI.h @@ -58,6 +58,8 @@ public: void reap(); + void shutdown(); + private: void installTopic(const std::string&, const std::string&, bool); @@ -71,6 +73,7 @@ private: FlusherPtr _flusher; SubscriberFactoryPtr _factory; std::string _envName; + Freeze::ConnectionPtr _connection; StringBoolDict _topics; }; diff --git a/cpp/src/slice2freezej/Main.cpp b/cpp/src/slice2freezej/Main.cpp index f449b98d8db..f3f3285363e 100644 --- a/cpp/src/slice2freezej/Main.cpp +++ b/cpp/src/slice2freezej/Main.cpp @@ -100,16 +100,11 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) out << sb; // - // Constructors + // Constructor // - out << sp << nl << "public" << nl << name << "(Ice.Communicator communicator, String envName, String dbName, boolean createDb)"; + out << sp << nl << "public" << nl << name << "(Freeze.Connection connection, String dbName, boolean createDb)"; out << sb; - out << nl << "super(communicator, envName, dbName, createDb);"; - out << eb; - - out << sp << nl << "public" << nl << name << "(Ice.Communicator communicator, com.sleepycat.db.DbEnv dbEnv, String dbName, boolean createDb)"; - out << sb; - out << nl << "super(communicator, dbEnv, dbName, createDb);"; + out << nl << "super(connection, dbName, createDb);"; out << eb; // diff --git a/cpp/test/Freeze/complex/Client.cpp b/cpp/test/Freeze/complex/Client.cpp index 9dd449d0449..1d9942f26a9 100644 --- a/cpp/test/Freeze/complex/Client.cpp +++ b/cpp/test/Freeze/complex/Client.cpp @@ -166,7 +166,8 @@ main(int argc, char* argv[]) } communicator = Ice::initialize(argc, argv); - Complex::ComplexDict m(communicator, envName, "test"); + ConnectionPtr connection = createConnection(communicator, envName); + Complex::ComplexDict m(connection, "test"); status = run(argc, argv, communicator, m); } catch(const Ice::Exception& ex) diff --git a/cpp/test/Freeze/dbmap/Client.cpp b/cpp/test/Freeze/dbmap/Client.cpp index 019c0e4ef08..44c69373f03 100644 --- a/cpp/test/Freeze/dbmap/Client.cpp +++ b/cpp/test/Freeze/dbmap/Client.cpp @@ -54,14 +54,36 @@ FindFirstOfTest(const pair<const Byte, const Int>& p, Byte q) return p.first == q; } + void -populateDB(ByteIntMap& m) +populateDB(const ConnectionPtr& connection, ByteIntMap& m) { alphabet.assign(alphabetChars, alphabetChars + sizeof(alphabetChars) - 1); - - for(vector<Byte>::const_iterator j = alphabet.begin(); j != alphabet.end(); ++j) + size_t length = alphabet.size(); + + for(;;) { - m.put(ByteIntMap::value_type(*j, static_cast<Int>(j - alphabet.begin()))); + try + { + TransactionHolder txHolder(connection); + for(size_t j = 0; j < length; ++j) + { + m.put(ByteIntMap::value_type(alphabet[j], static_cast<Int>(j))); + } + txHolder.commit(); + break; + } + catch(const DBDeadlockException&) + { +#ifdef SHOW_EXCEPTIONS + cerr << "t" << flush; +#endif + + length = length / 2; + // + // Try again + // + } } } @@ -69,8 +91,9 @@ class ReadThread : public IceUtil::Thread { public: - ReadThread(ByteIntMap& m) : - _map(m) + ReadThread(const CommunicatorPtr& communicator, const string& envName, const string& dbName) : + _connection(createConnection(communicator, envName)), + _map(_connection, dbName) { } @@ -112,15 +135,18 @@ public: private: - ByteIntMap& _map; + ConnectionPtr _connection; + ByteIntMap _map; }; + class WriteThread : public IceUtil::Thread { public: - WriteThread(ByteIntMap& m) : - _map(m) + WriteThread(const CommunicatorPtr& communicator, const string& envName, const string& dbName) : + _connection(createConnection(communicator, envName)), + _map(_connection, dbName) { } @@ -160,22 +186,27 @@ public: break; } } - populateDB(_map); + populateDB(_connection, _map); } } private: - ByteIntMap& _map; + ConnectionPtr _connection; + ByteIntMap _map; }; + int -run(int argc, char* argv[], ByteIntMap& m) +run(const CommunicatorPtr& communicator, const string& envName, const string&dbName) { + ConnectionPtr connection = createConnection(communicator, envName); + ByteIntMap m(connection, dbName); + // // Populate the database with the alphabet // - populateDB(m); + populateDB(connection, m); vector<Byte>::const_iterator j; ByteIntMap::iterator p; @@ -200,9 +231,7 @@ run(int argc, char* argv[], ByteIntMap& m) test(cp != m.end()); test(cp->first == *j && cp->second == j - alphabet.begin()); } - p = m.end(); - cp = m.end(); - + test(!m.empty()); test(m.size() == alphabet.size()); cout << "ok" << endl; @@ -213,11 +242,6 @@ run(int argc, char* argv[], ByteIntMap& m) cp = m.find(*j); test(cp != m.end()); test(cp->first == 'n' && cp->second == j - alphabet.begin()); - - // - // Close the iterator to release locks - // - cp = m.end(); cout << "ok" << endl; cout << " testing erase... "; @@ -237,12 +261,12 @@ run(int argc, char* argv[], ByteIntMap& m) p = m.find(*j); test(p != m.end()); m.erase(p); + // - // Need to release the iterator to commit the transaction - // and release the locks + // Release locks to avoid self deadlock // p = m.end(); - + p = m.find(*j); test(p == m.end()); vector<Byte>::iterator r = find(alphabet.begin(), alphabet.end(), *j); @@ -321,7 +345,6 @@ run(int argc, char* argv[], ByteIntMap& m) p2 = p++; test(c == p2->first); // p2 should still be the same test(p2->first != p->first && (++p2)->first == p->first); - p2 = m.end(); cout << "ok" << endl; @@ -332,37 +355,35 @@ run(int argc, char* argv[], ByteIntMap& m) p = m.find('d'); test(p != m.end() && p->second == 3); - p = m.end(); test(m.find('a') == m.end()); ByteIntMap::value_type i1('a', 1); + m.put(i1); // // Note: VC++ won't accept this // - //m.put(typename MAP::value_type('a', 1)); + //m.put(ByteIntMap::value_type('a', 1)); p = m.find('a'); test(p != m.end() && p->second == 1); - p = m.end(); ByteIntMap::value_type i2('a', 0); m.put(i2); // // Note: VC++ won't accept this // - //m.put(typename MAP::value_type('a', 0)); + //m.put(ByteIntMap::value_type('a', 0)); p = m.find('a'); test(p != m.end() && p->second == 0); - p = m.end(); // // Test inserts // ByteIntMap::value_type i3('a', 7); - pair<ByteIntMap::iterator, bool> insertResult = m.insert(i3); + test(insertResult.first == m.find('a')); test(insertResult.first->second == 0); test(insertResult.second == false); @@ -371,7 +392,6 @@ run(int argc, char* argv[], ByteIntMap& m) p = m.insert(m.end(), i3); test(p == m.find('a')); test(p->second == 0); - p = m.end(); ByteIntMap::value_type i4('b', 7); @@ -386,22 +406,26 @@ run(int argc, char* argv[], ByteIntMap& m) p = m.insert(m.end(), i5); test(p == m.find('c')); test(p->second == 8); - p = m.end(); p = m.find('a'); test(p != m.end() && p->second == 0); p.set(1); test(p != m.end() && p->second == 1); + + // + // This is necessary to release the locks held + // by p and avoid a self-deadlock + // p = m.end(); + p = m.find('a'); test(p != m.end() && p->second == 1); - p = m.end(); cout << "ok" << endl; // // Re-populate // - populateDB(m); + populateDB(connection, m); cout << " testing algorithms... "; @@ -463,18 +487,16 @@ run(int argc, char* argv[], ByteIntMap& m) } cout << "ok" << endl; - p = m.end(); - cout << " testing concurrent access... " << flush; m.clear(); - populateDB(m); + populateDB(connection, m); vector<IceUtil::ThreadControl> controls; for(int i = 0; i < 5; ++i) { - IceUtil::ThreadPtr rt = new ReadThread(m); + IceUtil::ThreadPtr rt = new ReadThread(communicator, envName, dbName); controls.push_back(rt->start()); - IceUtil::ThreadPtr wt = new WriteThread(m); + IceUtil::ThreadPtr wt = new WriteThread(communicator, envName, dbName); controls.push_back(wt->start()); } for(vector<IceUtil::ThreadControl>::iterator q = controls.begin(); q != controls.end(); ++q) @@ -503,10 +525,9 @@ main(int argc, char* argv[]) envName += "/"; envName += "db"; } - - ByteIntMap binary(communicator, envName, "binary"); - cout << "testing encoding..." << endl; - status = run(argc, argv, binary); + + cout << "testing encoding..." << endl; + status = run(communicator, envName, "binary"); } catch(const Ice::Exception& ex) { |