From: <hv...@us...> - 2011-05-09 10:15:29
|
Revision: 52896 http://firebird.svn.sourceforge.net/firebird/?rev=52896&view=rev Author: hvlad Date: 2011-05-09 10:15:19 +0000 (Mon, 09 May 2011) Log Message: ----------- Shared page cache implementation Modified Paths: -------------- firebird/trunk/builds/install/misc/firebird.conf.in firebird/trunk/src/common/classes/SyncObject.h firebird/trunk/src/common/classes/locks.h firebird/trunk/src/common/config/config.cpp firebird/trunk/src/common/config/config.h firebird/trunk/src/common/isc_sync.cpp firebird/trunk/src/dsql/AggNodes.cpp firebird/trunk/src/dsql/dsql.cpp firebird/trunk/src/dsql/dsql.h firebird/trunk/src/jrd/Attachment.cpp firebird/trunk/src/jrd/Attachment.h firebird/trunk/src/jrd/Database.cpp firebird/trunk/src/jrd/Database.h firebird/trunk/src/jrd/DatabaseSnapshot.cpp firebird/trunk/src/jrd/ExtEngineManager.cpp firebird/trunk/src/jrd/ExtEngineManager.h firebird/trunk/src/jrd/Function.epp firebird/trunk/src/jrd/GlobalRWLock.cpp firebird/trunk/src/jrd/GlobalRWLock.h firebird/trunk/src/jrd/JrdStatement.cpp firebird/trunk/src/jrd/Relation.cpp firebird/trunk/src/jrd/Relation.h firebird/trunk/src/jrd/RuntimeStatistics.cpp firebird/trunk/src/jrd/RuntimeStatistics.h firebird/trunk/src/jrd/ValueImpl.cpp firebird/trunk/src/jrd/blb.cpp firebird/trunk/src/jrd/cch.cpp firebird/trunk/src/jrd/cch.h firebird/trunk/src/jrd/cch_proto.h firebird/trunk/src/jrd/cmp.cpp firebird/trunk/src/jrd/dfw.epp firebird/trunk/src/jrd/dpm.epp firebird/trunk/src/jrd/dyn.epp firebird/trunk/src/jrd/exe.cpp firebird/trunk/src/jrd/exe_proto.h firebird/trunk/src/jrd/ext.cpp firebird/trunk/src/jrd/extds/ExtDS.cpp firebird/trunk/src/jrd/fun.epp firebird/trunk/src/jrd/idx.cpp firebird/trunk/src/jrd/inf.cpp firebird/trunk/src/jrd/ini.epp firebird/trunk/src/jrd/intl.cpp firebird/trunk/src/jrd/jrd.cpp firebird/trunk/src/jrd/jrd.h firebird/trunk/src/jrd/jrd_proto.h firebird/trunk/src/jrd/lck.cpp firebird/trunk/src/jrd/lck.h firebird/trunk/src/jrd/met.epp firebird/trunk/src/jrd/nbak.cpp firebird/trunk/src/jrd/nbak.h firebird/trunk/src/jrd/os/pio.h firebird/trunk/src/jrd/os/win32/winnt.cpp firebird/trunk/src/jrd/pag.cpp firebird/trunk/src/jrd/pcmet.epp firebird/trunk/src/jrd/recsrc/SortedStream.cpp firebird/trunk/src/jrd/sdw.cpp firebird/trunk/src/jrd/shut.cpp firebird/trunk/src/jrd/sort.cpp firebird/trunk/src/jrd/sort.h firebird/trunk/src/jrd/tpc.cpp firebird/trunk/src/jrd/tpc_proto.h firebird/trunk/src/jrd/tra.cpp firebird/trunk/src/jrd/tra.h firebird/trunk/src/jrd/trace/TraceDSQLHelpers.h firebird/trunk/src/jrd/trace/TraceJrdHelpers.h firebird/trunk/src/jrd/trace/TraceObjects.cpp firebird/trunk/src/jrd/trace/TraceObjects.h firebird/trunk/src/jrd/validation.cpp firebird/trunk/src/jrd/vio.cpp firebird/trunk/src/lock/lock.cpp firebird/trunk/src/lock/lock_proto.h firebird/trunk/src/remote/server/os/win32/srvr_w32.cpp firebird/trunk/src/remote/server/server.cpp Modified: firebird/trunk/builds/install/misc/firebird.conf.in =================================================================== --- firebird/trunk/builds/install/misc/firebird.conf.in 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/builds/install/misc/firebird.conf.in 2011-05-09 10:15:19 UTC (rev 52896) @@ -660,11 +660,11 @@ # The value is taken from a bit map in which each bit represents a CPU. # Thus, to use only the first processor, the value is 1. To use both # CPU 1 and CPU 2, the value is 3. To use CPU 2 and CPU 3, the value -# is 6. The default value is 1. +# is 6. The default value is 0 - no affinity will be set. # # Type: integer # -#CpuAffinityMask = 1 +#CpuAffinityMask = 0 # ---------------------------- @@ -838,3 +838,16 @@ # 16 16777216 320 335544320 896 939524096 # 32 33554432 384 402653184 1024 1073741824 # + +# Type: boolean +#SharedCache = true + +# Type: boolean +#SharedDatabase = false + + +# SharedCache SharedDatabase Mode +# false false Classic with exlusive access // single attachment only ? +# false true Classic with shared access // traditional CS\SC +# true false Super with exlusive access // traditional SS +# true true Super with shared access // Modified: firebird/trunk/src/common/classes/SyncObject.h =================================================================== --- firebird/trunk/src/common/classes/SyncObject.h 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/common/classes/SyncObject.h 2011-05-09 10:15:19 UTC (rev 52896) @@ -173,6 +173,11 @@ syncObject = obj; } + SyncType getState() const + { + return state; + } + protected: SyncType state; SyncType request; @@ -199,27 +204,28 @@ } }; -class SyncUnlockGuard : public Sync +class SyncUnlockGuard { public: - SyncUnlockGuard(SyncObject* obj, const char* fromWhere) - : Sync(obj, fromWhere) + SyncUnlockGuard(Sync& _sync) : + sync(_sync) { - oldState = state; + oldState = sync.getState(); fb_assert(oldState != SYNC_NONE); if (oldState != SYNC_NONE) - unlock(); + sync.unlock(); } ~SyncUnlockGuard() { if (oldState != SYNC_NONE) - lock(oldState); + sync.lock(oldState); } private: SyncType oldState; + Sync& sync; }; } // namespace Firebird Modified: firebird/trunk/src/common/classes/locks.h =================================================================== --- firebird/trunk/src/common/classes/locks.h 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/common/classes/locks.h 2011-05-09 10:15:19 UTC (rev 52896) @@ -378,6 +378,49 @@ Mutex* lock; }; +class MutexUnlockGuard +{ +public: + explicit MutexUnlockGuard(Mutex &aLock) + : lock(&aLock) + { + try { + lock->leave(); + } + catch (const Exception&) + { + DtorException::devHalt(); + } + } + + ~MutexUnlockGuard() + { + lock->enter(); + } + +private: + // Forbid copying + MutexUnlockGuard(const MutexUnlockGuard&); + MutexUnlockGuard& operator=(const MutexUnlockGuard&); + + Mutex* lock; +}; + + +class MutexCheckoutGuard +{ +public: + MutexCheckoutGuard(Mutex& mtxCout, Mutex& mtxLock) : + unlock(mtxCout), + lock(mtxLock) + { + } + +private: + MutexUnlockGuard unlock; + MutexLockGuard lock; +}; + } //namespace Firebird #endif // CLASSES_LOCKS_H Modified: firebird/trunk/src/common/config/config.cpp =================================================================== --- firebird/trunk/src/common/config/config.cpp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/common/config/config.cpp 2011-05-09 10:15:19 UTC (rev 52896) @@ -115,7 +115,7 @@ {TYPE_INTEGER, "TempCacheLimit", (ConfigValue) -1}, // bytes {TYPE_BOOLEAN, "RemoteFileOpenAbility", (ConfigValue) false}, {TYPE_INTEGER, "GuardianOption", (ConfigValue) 1}, - {TYPE_INTEGER, "CpuAffinityMask", (ConfigValue) 1}, + {TYPE_INTEGER, "CpuAffinityMask", (ConfigValue) 0}, {TYPE_INTEGER, "TcpRemoteBufferSize", (ConfigValue) 8192}, // bytes {TYPE_BOOLEAN, "TcpNoNagle", (ConfigValue) true}, {TYPE_INTEGER, "DefaultDbCachePages", (ConfigValue) -1}, // pages @@ -171,7 +171,9 @@ {TYPE_STRING, "AuthClient", (ConfigValue) "Legacy_Auth, Win_Sspi"}, {TYPE_STRING, "UserManager", (ConfigValue) "Legacy_Auth"}, {TYPE_STRING, "TracePlugin", (ConfigValue) "fbtrace"}, - {TYPE_STRING, "SecurityDatabase", (ConfigValue) "$(root)/security3.fdb"} // security database name + {TYPE_STRING, "SecurityDatabase", (ConfigValue) "$(root)/security3.fdb"}, // security database name + {TYPE_BOOLEAN, "SharedCache", (ConfigValue) true}, + {TYPE_BOOLEAN, "SharedDatabase", (ConfigValue) false} }; /****************************************************************************** @@ -668,20 +670,12 @@ bool Config::getSharedCache() { -#ifdef SUPERSERVER - return true; -#else - return false; -#endif + return (bool) getDefaultConfig()->values[KEY_SHARED_CACHE]; } bool Config::getSharedDatabase() { -#ifdef SUPERSERVER - return false; -#else - return true; -#endif + return (bool) getDefaultConfig()->values[KEY_SHARED_DATABASE]; } bool Config::getMultiClientServer() Modified: firebird/trunk/src/common/config/config.h =================================================================== --- firebird/trunk/src/common/config/config.h 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/common/config/config.h 2011-05-09 10:15:19 UTC (rev 52896) @@ -135,6 +135,8 @@ KEY_PLUG_AUTH_MANAGE, KEY_PLUG_TRACE, KEY_SECURITY_DATABASE, + KEY_SHARED_CACHE, + KEY_SHARED_DATABASE, MAX_CONFIG_KEY // keep it last }; Modified: firebird/trunk/src/common/isc_sync.cpp =================================================================== --- firebird/trunk/src/common/isc_sync.cpp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/common/isc_sync.cpp 2011-05-09 10:15:19 UTC (rev 52896) @@ -1334,13 +1334,9 @@ * **************************************/ -#ifdef SUPERSERVER - event->event_id = 0; -#else - static int idCounter = 0; // Should it be AtomicCounter? AP-2008 + static AtomicCounter idCounter; event->event_id = ++idCounter; -#endif event->event_pid = process_id = getpid(); event->event_count = 0; @@ -2745,16 +2741,12 @@ BOOL res = FALSE; if (fnSwitchToThread) { -#if !defined SUPERSERVER const HANDLE hThread = GetCurrentThread(); SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL); -#endif res = (*fnSwitchToThread)(); -#if !defined SUPERSERVER SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL); -#endif } return res; Modified: firebird/trunk/src/dsql/AggNodes.cpp =================================================================== --- firebird/trunk/src/dsql/AggNodes.cpp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/dsql/AggNodes.cpp 2011-05-09 10:15:19 UTC (rev 52896) @@ -322,7 +322,7 @@ asbImpure->iasb_sort = NULL; asbImpure->iasb_sort = FB_NEW(request->req_sorts.getPool()) Sort( - database, &request->req_sorts, asb->length, + request->req_attachment, &request->req_sorts, asb->length, asb->keyItems.getCount(), 1, asb->keyItems.begin(), RecordSource::rejectDuplicate, 0); } Modified: firebird/trunk/src/dsql/dsql.cpp =================================================================== --- firebird/trunk/src/dsql/dsql.cpp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/dsql/dsql.cpp 2011-05-09 10:15:19 UTC (rev 52896) @@ -1381,10 +1381,9 @@ if (attachment->att_dsql_instance) return attachment->att_dsql_instance; - MemoryPool& pool = *attachment->att_database->createPool(); + MemoryPool& pool = *attachment->createPool(); dsql_dbb* const database = FB_NEW(pool) dsql_dbb(pool); database->dbb_attachment = attachment; - database->dbb_database = attachment->att_database; attachment->att_dsql_instance = database; INI_init_dsql(tdbb, database); Modified: firebird/trunk/src/dsql/dsql.h =================================================================== --- firebird/trunk/src/dsql/dsql.h 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/dsql/dsql.h 2011-05-09 10:15:19 UTC (rev 52896) @@ -37,7 +37,7 @@ #include "../common/common.h" #include "../jrd/RuntimeStatistics.h" #include "../jrd/val.h" // Get rid of duplicated FUN_T enum. -#include "../jrd/Database.h" +#include "../jrd/Attachment.h" #include "../dsql/BlrWriter.h" #include "../common/classes/array.h" #include "../common/classes/GenericMap.h" @@ -146,7 +146,6 @@ Firebird::string, class dsql_req*> > > dbb_cursors; // known cursors in database MemoryPool& dbb_pool; // The current pool for the dbb - Database* dbb_database; Attachment* dbb_attachment; dsql_str* dbb_dfl_charset; bool dbb_no_charset; @@ -170,12 +169,12 @@ MemoryPool* createPool() { - return dbb_database->createPool(); + return dbb_attachment->createPool(); } void deletePool(MemoryPool* pool) { - dbb_database->deletePool(pool); + dbb_attachment->deletePool(pool); } }; Modified: firebird/trunk/src/jrd/Attachment.cpp =================================================================== --- firebird/trunk/src/jrd/Attachment.cpp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/Attachment.cpp 2011-05-09 10:15:19 UTC (rev 52896) @@ -25,6 +25,7 @@ #include "firebird.h" #include "../jrd/Attachment.h" #include "../jrd/Database.h" +#include "../jrd/Function.h" #include "../jrd/nbak.h" #include "../jrd/trace/TraceManager.h" #include "../jrd/PreparedStatement.h" @@ -95,6 +96,29 @@ } +MemoryPool* Jrd::Attachment::createPool() +{ + MemoryPool* const pool = MemoryPool::createPool(att_pool, att_memory_stats); + att_pools.add(pool); + return pool; +} + + +void Jrd::Attachment::deletePool(MemoryPool* pool) +{ + if (pool) + { + size_t pos; + if (att_pools.find(pool, pos)) + { + att_pools.remove(pos); + } + + MemoryPool::deletePool(pool); + } +} + + bool Jrd::Attachment::backupStateWriteLock(thread_db* tdbb, SSHORT wait) { if (att_backup_state_counter++) @@ -157,15 +181,29 @@ att_ext_call_depth(0), att_trace_manager(FB_NEW(*att_pool) TraceManager(this)), att_interface(NULL), - att_public_interface(NULL) + att_public_interface(NULL), + att_functions(*pool), + att_internal(*pool), + att_dyn_req(*pool), + att_charsets(*pool), + att_charset_ids(*pool), + att_pools(*pool) { + att_internal.grow(irq_MAX); + att_dyn_req.grow(drq_MAX); } Jrd::Attachment::~Attachment() { + destroyIntlObjects(); delete att_trace_manager; + while (att_pools.getCount()) + { + deletePool(att_pools.pop()); + } + // For normal attachments that happens in release_attachment(), // but for special ones like GC should be done also in dtor - // they do not (and should not) call release_attachment(). @@ -326,6 +364,12 @@ * block doesn't get dereferenced after it is released * **************************************/ + if (!att_long_locks) + return; + + Sync lckSync(&att_database->dbb_lck_sync, "Attachment::detachLocksFromAttachment"); + lckSync.lock(SYNC_EXCLUSIVE); + Lock* long_lock = att_long_locks; while (long_lock) { @@ -337,3 +381,134 @@ } att_long_locks = NULL; } + +// Find an inactive incarnation of a system request. If necessary, clone it. +jrd_req* Jrd::Attachment::findSystemRequest(thread_db* tdbb, USHORT id, USHORT which) +{ + static const int MAX_RECURSION = 100; + + // If the request hasn't been compiled or isn't active, there're nothing to do. + + //Database::CheckoutLockGuard guard(this, dbb_cmp_clone_mutex); + + fb_assert(which == IRQ_REQUESTS || which == DYN_REQUESTS); + + JrdStatement* statement = (which == IRQ_REQUESTS ? att_internal[id] : att_dyn_req[id]); + + if (!statement) + return NULL; + + // Look for requests until we find one that is available. + + for (int n = 0;; ++n) + { + if (n > MAX_RECURSION) + { + ERR_post(Arg::Gds(isc_no_meta_update) << + Arg::Gds(isc_req_depth_exceeded) << Arg::Num(MAX_RECURSION)); + // Msg363 "request depth exceeded. (Recursive definition?)" + } + + jrd_req* clone = statement->getRequest(tdbb, n); + + if (!(clone->req_flags & (req_active | req_reserved))) + { + clone->req_flags |= req_reserved; + return clone; + } + } +} + +void Jrd::Attachment::shutdown(thread_db* tdbb) +{ + // go through relations and indices and release + // all existence locks that might have been taken + + vec<jrd_rel*>* rvector = att_relations; + if (rvector) + { + vec<jrd_rel*>::iterator ptr, end; + for (ptr = rvector->begin(), end = rvector->end(); ptr < end; ++ptr) + { + jrd_rel* relation = *ptr; + if (relation) + { + if (relation->rel_existence_lock) + { + LCK_release(tdbb, relation->rel_existence_lock); + relation->rel_flags |= REL_check_existence; + relation->rel_use_count = 0; + } + if (relation->rel_partners_lock) + { + LCK_release(tdbb, relation->rel_partners_lock); + relation->rel_flags |= REL_check_partners; + } + if (relation->rel_rescan_lock) + { + LCK_release(tdbb, relation->rel_rescan_lock); + relation->rel_flags &= ~REL_scanned; + } + for (IndexLock* index = relation->rel_index_locks; index; index = index->idl_next) + { + if (index->idl_lock) + { + index->idl_count = 0; + LCK_release(tdbb, index->idl_lock); + } + } + } + } + } + + // release all procedure existence locks that might have been taken + + vec<jrd_prc*>* pvector = att_procedures; + if (pvector) + { + vec<jrd_prc*>::iterator pptr, pend; + for (pptr = pvector->begin(), pend = pvector->end(); pptr < pend; ++pptr) + { + jrd_prc* procedure = *pptr; + if (procedure) + { + if (procedure->prc_existence_lock) + { + LCK_release(tdbb, procedure->prc_existence_lock); + procedure->prc_flags |= PRC_check_existence; + procedure->prc_use_count = 0; + } + } + } + } + + // release all function existence locks that might have been taken + + for (Function** iter = att_functions.begin(); iter < att_functions.end(); ++iter) + { + Function* const function = *iter; + + if (function) + { + function->releaseLocks(tdbb); + } + } + + // release collation existence locks + + releaseIntlObjects(); + + // And release the system requests. + + for (JrdStatement** itr = att_internal.begin(); itr != att_internal.end(); ++itr) + { + if (*itr) + (*itr)->release(tdbb); + } + + for (JrdStatement** itr = att_dyn_req.begin(); itr != att_dyn_req.end(); ++itr) + { + if (*itr) + (*itr)->release(tdbb); + } +} Modified: firebird/trunk/src/jrd/Attachment.h =================================================================== --- firebird/trunk/src/jrd/Attachment.h 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/Attachment.h 2011-05-09 10:15:19 UTC (rev 52896) @@ -45,6 +45,8 @@ class Connection; } +class CharSetContainer; + namespace Jrd { class thread_db; @@ -71,6 +73,12 @@ class PreparedStatement; class TraceManager; template <typename T> class vec; + class jrd_rel; + class jrd_prc; + class Trigger; + typedef Firebird::ObjectsArray<Trigger> trig_vec; + class Function; + class JrdStatement; struct DSqlCacheItem { @@ -121,6 +129,95 @@ class Attachment : public pool_alloc<type_att> { public: + class SyncGuard + { + public: + SyncGuard(Attachment* att, bool optional = false) : + m_mutex(NULL) + { + if (att && att->att_interface) + m_mutex = att->att_interface->getMutex(); + + fb_assert(optional || m_mutex); + + if (m_mutex) + m_mutex->enter(); + } + + ~SyncGuard() + { + if (m_mutex) + m_mutex->leave(); + } + + private: + // copying is prohibited + SyncGuard(const SyncGuard&); + SyncGuard& operator=(const SyncGuard&); + + Firebird::Mutex* m_mutex; + }; + + class Checkout + { + public: + Checkout(Attachment* att, bool optional = false) : + m_mutex(NULL) + { + if (att && att->att_interface) + { + m_ref = att->att_interface; + m_mutex = att->att_interface->getMutex(); + } + + fb_assert(optional || m_mutex); + + if (m_mutex) + m_mutex->leave(); + } + + ~Checkout() + { + if (m_mutex) + m_mutex->enter(); + } + + private: + // copying is prohibited + Checkout(const Checkout&); + Checkout& operator=(const Checkout&); + + Firebird::Mutex* m_mutex; + Firebird::RefPtr<JAttachment> m_ref; + }; + + class CheckoutLockGuard + { + public: + CheckoutLockGuard(Attachment* att, Firebird::Mutex& mutex, bool optional = false) : + m_mutex(mutex) + { + if (!m_mutex.tryEnter()) + { + Checkout attCout(att, optional); + m_mutex.enter(); + } + } + + ~CheckoutLockGuard() + { + m_mutex.leave(); + } + + private: + // copying is prohibited + CheckoutLockGuard(const CheckoutLockGuard&); + CheckoutLockGuard& operator=(const CheckoutLockGuard&); + + Firebird::Mutex& m_mutex; + }; + +public: static Attachment* create(Database* dbb); static void destroy(Attachment* const attachment); @@ -170,6 +267,7 @@ Firebird::SortedArray<void*> att_udf_pointers; dsql_dbb* att_dsql_instance; bool att_in_use; // attachment in use (can't be detached or dropped) + int att_use_count; // number of API calls running except of asyncronous ones EDS::Connection* att_ext_connection; // external connection executed by this attachment ULONG att_ext_call_depth; // external connection call depth, 0 for user attachment @@ -178,6 +276,35 @@ JAttachment* att_interface; Firebird::IAttachment* att_public_interface; +/// former Database members + vec<jrd_rel*>* att_relations; // relation vector + vec<jrd_prc*>* att_procedures; // scanned procedures + trig_vec* att_triggers[DB_TRIGGER_MAX]; + trig_vec* att_ddl_triggers; + Firebird::Array<Function*> att_functions; // User defined functions + + Firebird::Array<JrdStatement*> att_internal; // internal statements + Firebird::Array<JrdStatement*> att_dyn_req; // internal dyn statements + + jrd_req* findSystemRequest(thread_db* tdbb, USHORT id, USHORT which); + + Firebird::Array<CharSetContainer*> att_charsets; // intl character set descriptions + Firebird::GenericMap<Firebird::Pair<Firebird::Left< + Firebird::MetaName, USHORT> > > att_charset_ids; // Character set ids + + void releaseIntlObjects(); // defined in intl.cpp + void destroyIntlObjects(); // defined in intl.cpp + + // from CMP_shutdown_database and CMP_fini + void shutdown(thread_db* tdbb); + + Firebird::Array<MemoryPool*> att_pools; // pools + + MemoryPool* createPool(); + void deletePool(MemoryPool* pool); + +/// former Database members + bool locksmith() const; jrd_tra* getSysTransaction(); void setSysTransaction(jrd_tra* trans); // used only by TRA_init Modified: firebird/trunk/src/jrd/Database.cpp =================================================================== --- firebird/trunk/src/jrd/Database.cpp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/Database.cpp 2011-05-09 10:15:19 UTC (rev 52896) @@ -77,12 +77,14 @@ Database::~Database() { - destroyIntlObjects(); - - fb_assert(dbb_pools[0] == dbb_permanent); - for (size_t i = 1; i < dbb_pools.getCount(); ++i) { - MemoryPool::deletePool(dbb_pools[i]); + Firebird::SyncLockGuard guard(&dbb_pools_sync, SYNC_EXCLUSIVE, "Database::~Database"); + + fb_assert(dbb_pools[0] == dbb_permanent); + for (size_t i = 1; i < dbb_pools.getCount(); ++i) + { + MemoryPool::deletePool(dbb_pools[i]); + } } delete dbb_monitoring_data; @@ -90,7 +92,8 @@ dbb_flags |= DBB_destroying; - Checkout dcoHolder(this); +// Checkout dcoHolder(this); + // This line decrements the usage counter and may cause the destructor to be called. // It should happen with the dbb_sync unlocked. LockManager::destroy(dbb_lock_mgr); @@ -101,57 +104,19 @@ { if (pool) { - size_t pos; - if (dbb_pools.find(pool, pos)) { - dbb_pools.remove(pos); + Firebird::SyncLockGuard guard(&dbb_pools_sync, SYNC_EXCLUSIVE, "Database::deletePool"); + size_t pos; + if (dbb_pools.find(pool, pos)) + { + dbb_pools.remove(pos); + } } MemoryPool::deletePool(pool); } } - // Find an inactive incarnation of a system request. If necessary, clone it. - jrd_req* Database::findSystemRequest(thread_db* tdbb, USHORT id, USHORT which) - { - static const int MAX_RECURSION = 100; - - // If the request hasn't been compiled or isn't active, there're nothing to do. - - Database::CheckoutLockGuard guard(this, dbb_cmp_clone_mutex); - - fb_assert(which == IRQ_REQUESTS || which == DYN_REQUESTS); - - JrdStatement* statement = (which == IRQ_REQUESTS ? dbb_internal[id] : dbb_dyn_req[id]); - - if (!statement) - return NULL; - - // Look for requests until we find one that is available. - - for (int n = 0;; ++n) - { - if (n > MAX_RECURSION) - { - ERR_post(Arg::Gds(isc_no_meta_update) << - Arg::Gds(isc_req_depth_exceeded) << Arg::Num(MAX_RECURSION)); - // Msg363 "request depth exceeded. (Recursive definition?)" - } - - jrd_req* clone = statement->getRequest(tdbb, n); - - if (!(clone->req_flags & (req_active | req_reserved))) - { - clone->req_flags |= req_reserved; - clone->setAttachment(tdbb->getAttachment()); - fb_assert(clone->req_attachment); - return clone; - } - } - } - - // Database::SharedCounter implementation - Database::SharedCounter::SharedCounter() { memset(m_counters, 0, sizeof(m_counters)); @@ -180,6 +145,8 @@ ValueCache* const counter = &m_counters[space]; Database* const dbb = tdbb->getDatabase(); + SyncLockGuard guard(&dbb->dbb_sh_counter_sync, SYNC_EXCLUSIVE, "Database::SharedCounter::generate"); + if (!counter->lock) { Lock* const lock = FB_NEW_RPT(*dbb->dbb_permanent, sizeof(SLONG)) Lock(); @@ -225,11 +192,13 @@ try { - Database::SyncGuard dsGuard(dbb, true); + if (dbb->dbb_flags & DBB_not_in_use) + return 0; + SyncLockGuard guard(&dbb->dbb_sh_counter_sync, SYNC_EXCLUSIVE, "Database::blockingAstSharedCounter"); + ThreadContextHolder tdbb; tdbb->setDatabase(dbb); - // tdbb->setAttachment(counter->lock->lck_attachment); Jrd::ContextPoolHolder context(tdbb, dbb->dbb_permanent); Modified: firebird/trunk/src/jrd/Database.h =================================================================== --- firebird/trunk/src/jrd/Database.h 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/Database.h 2011-05-09 10:15:19 UTC (rev 52896) @@ -62,25 +62,21 @@ #include "../jrd/event_proto.h" #include "../lock/lock_proto.h" #include "../common/config/config.h" +#include "../common/classes/SyncObject.h" +#include "../common/classes/Synchronize.h" -class CharSetContainer; - namespace Jrd { - class Trigger; - template <typename T> class vec; - class jrd_prc; - class jrd_rel; - class Shadow; - class BlobFilter; - class TxPageCache; - class BackupManager; - class ExternalFileDirectoryList; - class MonitoringData; +template <typename T> class vec; +class jrd_rel; +class Shadow; +class BlobFilter; +class TipCache; +class BackupManager; +class ExternalFileDirectoryList; +class MonitoringData; - typedef Firebird::ObjectsArray<Trigger> trig_vec; - // general purpose vector template <class T, BlockType TYPE = type_vec> class vec_base : protected pool_alloc<TYPE> @@ -238,150 +234,7 @@ class Database : public pool_alloc<type_dbb> { - class Sync : public Firebird::RefCounted - { - public: - Sync() : threadId(0) - {} - - void lock() - { - ThreadPriorityScheduler::enter(); - ++waiters; - syncMutex.enter(); - --waiters; - threadId = getThreadId(); - } - - void unlock() - { - ThreadPriorityScheduler::exit(); - threadId = 0; - syncMutex.leave(); - } - - bool hasContention() const - { - return (waiters.value() > 0); - } - - private: - ~Sync() - { - if (threadId) - { - syncMutex.leave(); - } - } - - // copying is prohibited - Sync(const Sync&); - Sync& operator=(const Sync&); - - Firebird::Mutex syncMutex; - Firebird::AtomicCounter waiters; - FB_THREAD_ID threadId; - }; - public: - - class SyncGuard - { - public: - explicit SyncGuard(Database* dbb, bool ast = false) - : sync(*dbb->dbb_sync) - { - if (!dbb) - { - Firebird::status_exception::raise(Firebird::Arg::Gds(isc_bad_db_handle)); - } - - sync.addRef(); - sync.lock(); - - if (ast && dbb->dbb_flags & DBB_destroying) - { - sync.unlock(); - sync.release(); - Firebird::LongJump::raise(); - } - } - - ~SyncGuard() - { - try - { - sync.unlock(); - } - catch (const Firebird::Exception&) - { - DtorException::devHalt(); - } - sync.release(); - } - - private: - // copying is prohibited - SyncGuard(const SyncGuard&); - SyncGuard& operator=(const SyncGuard&); - - Sync& sync; - }; - - class Checkout - { - public: - explicit Checkout(Database* dbb) - : sync(*dbb->dbb_sync) - { - sync.unlock(); - } - - ~Checkout() - { - sync.lock(); - } - - private: - // copying is prohibited - Checkout(const Checkout&); - Checkout& operator=(const Checkout&); - - Sync& sync; - }; - - class CheckoutLockGuard - { - public: - CheckoutLockGuard(Database* dbb, Firebird::Mutex& m) - : mutex(m) - { - if (!mutex.tryEnter()) - { - Checkout dcoHolder(dbb); - mutex.enter(); - } - } - - ~CheckoutLockGuard() - { - try { - mutex.leave(); - } - catch (const Firebird::Exception&) - { - DtorException::devHalt(); - } - } - - private: - // copying is prohibited - CheckoutLockGuard(const CheckoutLockGuard&); - CheckoutLockGuard& operator=(const CheckoutLockGuard&); - - Firebird::Mutex& mutex; - }; - class SharedCounter { static const ULONG DEFAULT_CACHE_SIZE = 16; @@ -452,44 +305,42 @@ return fb_utils::genUniqueId(); } - mutable Firebird::RefPtr<Sync> dbb_sync; // Database sync primitive + Firebird::SyncObject dbb_sync; + Firebird::SyncObject dbb_lck_sync; // syncronize operations with att_long_locks at different attachments + LockManager* dbb_lock_mgr; EventManager* dbb_event_mgr; Database* dbb_next; // Next database block in system Attachment* dbb_attachments; // Active attachments BufferControl* dbb_bcb; // Buffer control block - vec<jrd_rel*>* dbb_relations; // relation vector - vec<jrd_prc*>* dbb_procedures; // scanned procedures int dbb_monitoring_id; // dbb monitoring identifier Lock* dbb_lock; // granddaddy lock + + Firebird::SyncObject dbb_sh_counter_sync; + + Firebird::SyncObject dbb_shadow_sync; Shadow* dbb_shadow; // shadow control block Lock* dbb_shadow_lock; // lock for synchronizing addition of shadows + Lock* dbb_retaining_lock; // lock for preserving commit retaining snapshot Lock* dbb_monitor_lock; // lock for monitoring purposes PageManager dbb_page_manager; vcl* dbb_t_pages; // pages number for transactions vcl* dbb_gen_id_pages; // known pages for gen_id BlobFilter* dbb_blob_filters; // known blob filters - trig_vec* dbb_triggers[DB_TRIGGER_MAX]; - trig_vec* dbb_ddl_triggers; - MonitoringData* dbb_monitoring_data; // monitoring data + Firebird::SyncObject dbb_mon_sync; // syncronize operations with dbb_monitor_lock + MonitoringData* dbb_monitoring_data; // monitoring data DatabaseModules dbb_modules; // external function/filter modules - ExtEngineManager dbb_extManager; // external engine manager + ExtEngineManager dbb_extManager; // external engine manager - Firebird::Mutex dbb_meta_mutex; // Mutex to protect metadata changes while dbb_sync is unlocked - Firebird::Mutex dbb_cmp_clone_mutex; - Firebird::Mutex dbb_exe_clone_mutex; - Firebird::Mutex dbb_flush_count_mutex; - Firebird::Mutex dbb_dyn_mutex; + Firebird::SyncObject dbb_flush_count_mutex; - //SLONG dbb_sort_size; // Size of sort space per sort, unused for now - - ULONG dbb_ast_flags; // flags modified at AST level - ULONG dbb_flags; + Firebird::AtomicCounter dbb_ast_flags; // flags modified at AST level + Firebird::AtomicCounter dbb_flags; USHORT dbb_ods_version; // major ODS version number USHORT dbb_minor_version; // minor ODS version number USHORT dbb_page_size; // page size @@ -508,30 +359,17 @@ Firebird::string dbb_encrypt_key; // encryption key MemoryPool* dbb_permanent; - MemoryPool* dbb_bufferpool; - Firebird::Array<MemoryPool*> dbb_pools; // pools + Firebird::SyncObject dbb_pools_sync; + Firebird::Array<MemoryPool*> dbb_pools; // pools - Firebird::Array<JrdStatement*> dbb_internal; // internal statements - Firebird::Array<JrdStatement*> dbb_dyn_req; // internal dyn statements - SLONG dbb_oldest_active; // Cached "oldest active" transaction SLONG dbb_oldest_transaction; // Cached "oldest interesting" transaction SLONG dbb_oldest_snapshot; // Cached "oldest snapshot" of all active transactions SLONG dbb_next_transaction; // Next transaction id used by NETWARE SLONG dbb_attachment_id; // Next attachment id for ReadOnly DB's - SLONG dbb_page_incarnation; // Cache page incarnation counter ULONG dbb_page_buffers; // Page buffers from header page - Firebird::Semaphore dbb_writer_sem; // Wake up cache writer - Firebird::Semaphore dbb_writer_init;// Cache writer initialization - Firebird::Semaphore dbb_writer_fini;// Cache writer finalization -#ifdef SUPERSERVER_V2 - // the code in cch.cpp is not tested for semaphore instead event !!! - Firebird::Semaphore dbb_reader_sem; // Wake up cache reader - Firebird::Semaphore dbb_reader_init;// Cache reader initialization - Firebird::Semaphore dbb_reader_fini;// Cache reader finalization -#endif #ifdef GARBAGE_THREAD Firebird::Semaphore dbb_gc_sem; // Event to wake up garbage collector @@ -554,14 +392,10 @@ crypt_routine dbb_encrypt; // External encryption routine crypt_routine dbb_decrypt; // External decryption routine - Firebird::Array<CharSetContainer*> dbb_charsets; // intl character set descriptions - TxPageCache* dbb_tip_cache; // cache of latest known state of all transactions in system + TipCache* dbb_tip_cache; // cache of latest known state of all transactions in system TransactionsVector* dbb_pc_transactions; // active precommitted transactions BackupManager* dbb_backup_manager; // physical backup manager Firebird::TimeStamp dbb_creation_date; // creation date - Firebird::Array<Function*> dbb_functions; // User defined functions - Firebird::GenericMap<Firebird::Pair<Firebird::Left< - Firebird::MetaName, USHORT> > > dbb_charset_ids; // Character set ids ExternalFileDirectoryList* dbb_external_file_directory_list; Firebird::RefPtr<Config> dbb_config; @@ -576,6 +410,8 @@ MemoryPool* createPool() { MemoryPool* const pool = MemoryPool::createPool(dbb_permanent, dbb_memory_stats); + + Firebird::SyncLockGuard guard(&dbb_pools_sync, Firebird::SYNC_EXCLUSIVE, "Database::createPool"); dbb_pools.add(pool); return pool; } @@ -584,8 +420,7 @@ private: explicit Database(MemoryPool* p) - : dbb_sync(FB_NEW(*getDefaultMemoryPool()) Sync), - dbb_page_manager(this, *p), + : dbb_page_manager(this, *p), dbb_modules(*p), dbb_extManager(*p), dbb_filename(*p), @@ -593,31 +428,18 @@ dbb_encrypt_key(*p), dbb_permanent(p), dbb_pools(*p, 4), - dbb_internal(*p), - dbb_dyn_req(*p), dbb_stats(*p), dbb_lock_owner_id(getLockOwnerId()), - dbb_charsets(*p), dbb_creation_date(Firebird::TimeStamp::getCurrentTimeStamp()), - dbb_functions(*p), - dbb_charset_ids(*p), + dbb_tip_cache(NULL), dbb_external_file_directory_list(NULL) { dbb_pools.add(p); - dbb_internal.grow(irq_MAX); - dbb_dyn_req.grow(drq_MAX); } ~Database(); public: - // temporary measure to avoid unstable state of lock file - - // this is anyway called in ~Database(), and in theory should be private - void releaseIntlObjects(); // defined in intl.cpp - void destroyIntlObjects(); // defined in intl.cpp - - jrd_req* findSystemRequest(thread_db* tdbb, USHORT id, USHORT which); - SLONG generateAttachmentId(thread_db* tdbb) { return dbb_shared_counter.generate(tdbb, SharedCounter::ATTACHMENT_ID_SPACE, 1); Modified: firebird/trunk/src/jrd/DatabaseSnapshot.cpp =================================================================== --- firebird/trunk/src/jrd/DatabaseSnapshot.cpp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/DatabaseSnapshot.cpp 2011-05-09 10:15:19 UTC (rev 52896) @@ -350,32 +350,33 @@ { Lock* const lock = dbb->dbb_monitor_lock; - Database::SyncGuard dsGuard(dbb, true); - ThreadContextHolder tdbb; tdbb->setDatabase(lock->lck_dbb); - tdbb->setAttachment(lock->lck_attachment); - ContextPoolHolder context(tdbb, dbb->dbb_permanent); - if (!(dbb->dbb_ast_flags & DBB_monitor_off)) { - // Write the data to the shared memory - if (!(dbb->dbb_flags & DBB_not_in_use)) + SyncLockGuard monGuard(&dbb->dbb_mon_sync, SYNC_EXCLUSIVE, "DatabaseSnapshot::blockingAst"); + + if (!(dbb->dbb_ast_flags & DBB_monitor_off)) { - try + // Write the data to the shared memory + if (!(dbb->dbb_flags & DBB_not_in_use)) { - dumpData(tdbb); + ContextPoolHolder context(tdbb, dbb->dbb_permanent); + try + { + dumpData(tdbb); + } + catch (const Exception& ex) + { + iscLogException("Cannot dump the monitoring data", ex); + } } - catch (const Exception& ex) - { - iscLogException("Cannot dump the monitoring data", ex); - } + + // Release the lock and mark dbb as requesting a new one + LCK_release(tdbb, lock); + dbb->dbb_ast_flags |= DBB_monitor_off; } - - // Release the lock and mark dbb as requesting a new one - LCK_release(tdbb, lock); - dbb->dbb_ast_flags |= DBB_monitor_off; } } catch (const Exception&) @@ -406,17 +407,21 @@ RecordBuffer* const ctx_var_buffer = allocBuffer(tdbb, pool, rel_mon_ctx_vars); RecordBuffer* const mem_usage_buffer = allocBuffer(tdbb, pool, rel_mon_mem_usage); - // Release our own lock - LCK_release(tdbb, dbb->dbb_monitor_lock); - dbb->dbb_ast_flags &= ~DBB_monitor_off; + { + SyncLockGuard monGuard(&dbb->dbb_mon_sync, SYNC_EXCLUSIVE, "DatabaseSnapshot::DatabaseSnapshot"); - { // scope for the RAII object + // Release our own lock + LCK_release(tdbb, dbb->dbb_monitor_lock); + dbb->dbb_ast_flags &= ~DBB_monitor_off; - // Ensure we'll be dealing with a valid backup state inside the call below - BackupManager::StateReadGuard holder(tdbb); + { // scope for the RAII object - // Dump our own data - dumpData(tdbb); + // Ensure we'll be dealing with a valid backup state inside the call below + BackupManager::StateReadGuard holder(tdbb); + + // Dump our own data + dumpData(tdbb); + } } // Signal other processes to dump their data @@ -770,9 +775,15 @@ putDatabase(dbb, writer, fb_utils::genUniqueId()); // Attachment information + + Attachment* old_attachment = tdbb->getAttachment(); + Attachment::Checkout attCout(old_attachment, true); for (Attachment* attachment = dbb->dbb_attachments; attachment; attachment = attachment->att_next) { + Attachment::SyncGuard attGuard(attachment); + tdbb->setAttachment(attachment); + if (!putAttachment(tdbb, attachment, writer, fb_utils::genUniqueId())) continue; @@ -823,6 +834,8 @@ } } } + + tdbb->setAttachment(old_attachment); } Modified: firebird/trunk/src/jrd/ExtEngineManager.cpp =================================================================== --- firebird/trunk/src/jrd/ExtEngineManager.cpp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/ExtEngineManager.cpp 2011-05-09 10:15:19 UTC (rev 52896) @@ -134,7 +134,7 @@ Utf8 charSetName[MAX_SQL_IDENTIFIER_SIZE]; { // scope - Database::Checkout dcoHolder(tdbb->getDatabase()); + Attachment::Checkout attCout(attachment); obj->getCharSet(RaiseError(), attInfo->context, charSetName, MAX_SQL_IDENTIFIER_LEN); charSetName[MAX_SQL_IDENTIFIER_LEN] = '\0'; @@ -299,7 +299,7 @@ ExtEngineManager::Function::~Function() { - Database::Checkout dcoHolder(database); + // Database::Checkout dcoHolder(database); function->dispose(LogError()); } @@ -358,7 +358,7 @@ } { // scope - Database::Checkout dcoHolder(tdbb->getDatabase()); + Attachment::Checkout attCout(tdbb->getAttachment()); function->execute(RaiseError(), attInfo->context, ¶ms, &result); } } @@ -397,7 +397,7 @@ ExtEngineManager::Procedure::~Procedure() { - Database::Checkout dcoHolder(database); + //Database::Checkout dcoHolder(database); procedure->dispose(LogError()); } @@ -415,7 +415,7 @@ ExtEngineManager::ResultSet::ResultSet(thread_db* tdbb, ValuesImpl* inputParams, ValuesImpl* outputParams, const ExtEngineManager::Procedure* aProcedure) : procedure(aProcedure), - database(tdbb->getDatabase()), + attachment(tdbb->getAttachment()), firstFetch(true) { attInfo = procedure->extManager->getEngineAttachment(tdbb, procedure->engine); @@ -423,11 +423,10 @@ (procedure->prc->getName().package.isEmpty() ? CallerName(obj_procedure, procedure->prc->getName().identifier) : CallerName(obj_package_header, procedure->prc->getName().package))); - Attachment* attachment = tdbb->getAttachment(); charSet = attachment->att_charset; - Database::Checkout dcoHolder(tdbb->getDatabase()); + Attachment::Checkout attCout(attachment); resultSet = procedure->procedure->open(RaiseError(), attInfo->context, inputParams, outputParams); @@ -438,7 +437,8 @@ { if (resultSet) { - Database::Checkout dcoHolder(database); + fb_assert(attachment == JRD_get_thread_data()->getAttachment()); + Attachment::Checkout attCout(attachment); resultSet->dispose(LogError()); } } @@ -457,7 +457,8 @@ CallerName(obj_procedure, procedure->prc->getName().identifier) : CallerName(obj_package_header, procedure->prc->getName().package))); - Database::Checkout dcoHolder(tdbb->getDatabase()); + fb_assert(attachment == tdbb->getAttachment()); + Attachment::Checkout attCout(attachment); return resultSet->fetch(RaiseError()); } @@ -479,6 +480,7 @@ ExtEngineManager::Trigger::~Trigger() { + // hvlad: shouldn't we call trigger->dispose() here ? } @@ -504,7 +506,7 @@ valueNewCount = setValues(tdbb, pool, newValues, descs, newRpb); { // scope - Database::Checkout dcoHolder(tdbb->getDatabase()); + Attachment::Checkout attCout(tdbb->getAttachment()); trigger->execute(RaiseError(), attInfo->context, action, oldValues, newValues); @@ -605,7 +607,7 @@ } -void ExtEngineManager::closeAttachment(thread_db* tdbb, Attachment* /*attachment*/) +void ExtEngineManager::closeAttachment(thread_db* tdbb, Attachment* attachment) { Array<ExternalEngine*> enginesCopy; @@ -617,7 +619,7 @@ enginesCopy.add(accessor.current()->second); } - Database::Checkout dcoHolder(tdbb->getDatabase()); + Attachment::Checkout attCout(attachment, true); for (Array<ExternalEngine*>::iterator i = enginesCopy.begin(); i != enginesCopy.end(); ++i) { @@ -652,7 +654,7 @@ ExternalFunction* externalFunction; { // scope - Database::Checkout dcoHolder(tdbb->getDatabase()); + Attachment::Checkout attCout(tdbb->getAttachment()); externalFunction = attInfo->engine->makeFunction(RaiseError(), attInfo->context, udf->getName().package.nullStr(), udf->getName().identifier.c_str(), @@ -672,7 +674,7 @@ } catch (...) { - Database::Checkout dcoHolder(tdbb->getDatabase()); + Attachment::Checkout attCout(tdbb->getAttachment()); externalFunction->dispose(LogError()); throw; } @@ -694,7 +696,7 @@ ExternalProcedure* externalProcedure; { // scope - Database::Checkout dcoHolder(tdbb->getDatabase()); + Attachment::Checkout attCout(tdbb->getAttachment()); externalProcedure = attInfo->engine->makeProcedure(RaiseError(), attInfo->context, prc->getName().package.nullStr(), prc->getName().identifier.c_str(), @@ -714,7 +716,7 @@ } catch (...) { - Database::Checkout dcoHolder(tdbb->getDatabase()); + Attachment::Checkout attCout(tdbb->getAttachment()); externalProcedure->dispose(LogError()); throw; } @@ -738,7 +740,7 @@ ExternalTrigger* externalTrigger; { // scope - Database::Checkout dcoHolder(tdbb->getDatabase()); + Attachment::Checkout attCout(tdbb->getAttachment()); externalTrigger = attInfo->engine->makeTrigger(RaiseError(), attInfo->context, trg->name.c_str(), entryPointTrimmed.nullStr(), body.nullStr(), @@ -757,7 +759,7 @@ } catch (...) { - Database::Checkout dcoHolder(tdbb->getDatabase()); + Attachment::Checkout attCout(tdbb->getAttachment()); externalTrigger->dispose(LogError()); throw; } @@ -786,7 +788,7 @@ try { - Database::Checkout dcoHolder(tdbb->getDatabase()); + Attachment::Checkout attCout(tdbb->getAttachment()); engine = engineControl.plugin(); if (engine) @@ -799,7 +801,7 @@ Arg::Num(version) << name); } - Database::SyncGuard dsGuard(tdbb->getDatabase()); + Attachment::SyncGuard attGuard(tdbb->getAttachment()); key = EngineAttachment(engine, tdbb->getAttachment()); attInfo = FB_NEW(getPool()) EngineAttachmentInfo(); @@ -874,7 +876,7 @@ enginesAttachments.put(key, attInfo); ContextManager<ExternalFunction> ctxManager(tdbb, attInfo, attInfo->adminCharSet); - Database::Checkout dcoHolder(tdbb->getDatabase()); + Attachment::Checkout attCout(tdbb->getAttachment()); engine->openAttachment(LogError(), attInfo->context); } Modified: firebird/trunk/src/jrd/ExtEngineManager.h =================================================================== --- firebird/trunk/src/jrd/ExtEngineManager.h 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/ExtEngineManager.h 2011-05-09 10:15:19 UTC (rev 52896) @@ -179,7 +179,7 @@ private: const Procedure* procedure; - Database* database; + Attachment* attachment; bool firstFetch; EngineAttachmentInfo* attInfo; Firebird::ExternalResultSet* resultSet; Modified: firebird/trunk/src/jrd/Function.epp =================================================================== --- firebird/trunk/src/jrd/Function.epp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/Function.epp 2011-05-09 10:15:19 UTC (rev 52896) @@ -65,7 +65,7 @@ Database* const dbb = tdbb->getDatabase(); Function* check_function = NULL; - Function* function = (id < dbb->dbb_functions.getCount()) ? dbb->dbb_functions[id] : NULL; + Function* function = (id < attachment->att_functions.getCount()) ? attachment->att_functions[id] : NULL; if (function && function->getId() == id && !(function->fun_flags & FUN_being_scanned) && @@ -117,7 +117,7 @@ // See if we already know the function by name - for (Function** iter = dbb->dbb_functions.begin(); iter < dbb->dbb_functions.end(); ++iter) + for (Function** iter = attachment->att_functions.begin(); iter < attachment->att_functions.end(); ++iter) { Function* const function = *iter; @@ -174,15 +174,13 @@ jrd_tra* sysTransaction = attachment->getSysTransaction(); Database* const dbb = tdbb->getDatabase(); - if (id >= dbb->dbb_functions.getCount()) + if (id >= attachment->att_functions.getCount()) { - dbb->dbb_functions.grow(id + 1); + attachment->att_functions.grow(id + 1); } - Database::CheckoutLockGuard guard(dbb, dbb->dbb_meta_mutex); + Function* function = attachment->att_functions[id]; - Function* function = dbb->dbb_functions[id]; - if (function && !(function->fun_flags & FUN_obsolete)) { // Make sure FUN_being_scanned and FUN_scanned are not set at the same time @@ -196,7 +194,7 @@ if (!function) { - function = FB_NEW(*dbb->dbb_permanent) Function(*dbb->dbb_permanent); + function = FB_NEW(*attachment->att_pool) Function(*attachment->att_pool); } try @@ -205,11 +203,11 @@ function->fun_flags &= ~FUN_obsolete; function->setId(id); - dbb->dbb_functions[id] = function; + attachment->att_functions[id] = function; if (!function->fun_existence_lock) { - Lock* const lock = FB_NEW_RPT(*dbb->dbb_permanent, 0) Lock; + Lock* const lock = FB_NEW_RPT(*attachment->att_pool, 0) Lock; function->fun_existence_lock = lock; lock->lck_parent = dbb->dbb_lock; lock->lck_dbb = dbb; @@ -328,7 +326,7 @@ { function->fun_defaults++; - MemoryPool* const csb_pool = dbb->createPool(); + MemoryPool* const csb_pool = attachment->createPool(); Jrd::ContextPoolHolder context(tdbb, csb_pool); try @@ -338,7 +336,7 @@ } catch (const Exception&) { - dbb->deletePool(csb_pool); + attachment->deletePool(csb_pool); throw; // an explicit error message would be better } } @@ -403,7 +401,7 @@ } else if (!X.RDB$FUNCTION_BLR.NULL) { - MemoryPool* const csb_pool = dbb->createPool(); + MemoryPool* const csb_pool = attachment->createPool(); Jrd::ContextPoolHolder context(tdbb, csb_pool); try @@ -427,7 +425,7 @@ } catch (const Exception&) { - dbb->deletePool(csb_pool); + attachment->deletePool(csb_pool); throw; } @@ -513,8 +511,9 @@ try { Database* const dbb = function->fun_existence_lock->lck_dbb; + Jrd::Attachment* att = function->fun_existence_lock->lck_attachment; - Database::SyncGuard dsGuard(dbb, true); + Jrd::Attachment::SyncGuard guard(att); ThreadContextHolder tdbb; tdbb->setDatabase(dbb); @@ -624,8 +623,8 @@ { fun_use_count--; - Database* const dbb = tdbb->getDatabase(); - if (fun_use_count == 0 && dbb->dbb_functions[getId()] != this) + Jrd::Attachment* attachment = tdbb->getAttachment(); + if (fun_use_count == 0 && attachment->att_functions[getId()] != this) { if (getStatement()) { Modified: firebird/trunk/src/jrd/GlobalRWLock.cpp =================================================================== --- firebird/trunk/src/jrd/GlobalRWLock.cpp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/GlobalRWLock.cpp 2011-05-09 10:15:19 UTC (rev 52896) @@ -35,6 +35,7 @@ #include "jrd.h" #include "lck_proto.h" #include "err_proto.h" +#include "Attachment.h" #include "../common/classes/rwlock.h" #include "../common/classes/condition.h" @@ -43,6 +44,7 @@ IMPLEMENT_TRACE_ROUTINE(cos_trace, "COS") #endif + namespace Jrd { int GlobalRWLock::blocking_ast_cached_lock(void* ast_object) @@ -56,8 +58,6 @@ return 0; Database* dbb = globalRWLock->cachedLock->lck_dbb; - Database::SyncGuard dsGuard(dbb, true); - ThreadContextHolder tdbb; tdbb->setDatabase(dbb); @@ -101,7 +101,7 @@ { thread_db* tdbb = JRD_get_thread_data(); - Database::CheckoutLockGuard counterGuard(tdbb->getDatabase(), counterMutex); + Attachment::CheckoutLockGuard counterGuard(tdbb->getAttachment(), counterMutex, true); COS_TRACE(("(%p)->shutdownLock readers(%d), blocking(%d), pendingWriters(%d), currentWriter(%d), lck_physical(%d)", this, readers, blocking, pendingWriters, currentWriter, cachedLock->lck_physical)); @@ -119,19 +119,18 @@ { SET_TDBB(tdbb); - Database* dbb = tdbb->getDatabase(); + Attachment* att = tdbb->getAttachment(); { // scope 1 + Attachment::CheckoutLockGuard counterGuard(att, counterMutex, true); - Database::CheckoutLockGuard counterGuard(dbb, counterMutex); - COS_TRACE(("(%p)->lockWrite stage 1 readers(%d), blocking(%d), pendingWriters(%d), currentWriter(%d), lck_physical(%d)", this, readers, blocking, pendingWriters, currentWriter, cachedLock->lck_physical)); ++pendingWriters; while (readers > 0 ) { - Database::Checkout checkoutDbb(dbb); + Attachment::Checkout attCout(att, true); noReaders.wait(counterMutex); } @@ -140,7 +139,7 @@ while (currentWriter || pendingLock) { - Database::Checkout checkoutDbb(dbb); + Attachment::Checkout attCout(att, true); writerFinished.wait(counterMutex); } @@ -164,7 +163,7 @@ if (!LCK_lock(tdbb, cachedLock, LCK_write, wait)) { - Database::CheckoutLockGuard counterGuard(dbb, counterMutex); + Attachment::CheckoutLockGuard counterGuard(att, counterMutex, true); --pendingLock; if (--pendingWriters) { @@ -175,9 +174,8 @@ } { // scope 2 + Attachment::CheckoutLockGuard counterGuard(att, counterMutex, true); - Database::CheckoutLockGuard counterGuard(dbb, counterMutex); - --pendingLock; --pendingWriters; @@ -196,10 +194,9 @@ { SET_TDBB(tdbb); - Database* dbb = tdbb->getDatabase(); + Attachment* att = tdbb->getAttachment(); + Attachment::CheckoutLockGuard counterGuard(att, counterMutex, true); - Database::CheckoutLockGuard counterGuard(dbb, counterMutex); - COS_TRACE(("(%p)->unlockWrite readers(%d), blocking(%d), pendingWriters(%d), currentWriter(%d), lck_physical(%d)", this, readers, blocking, pendingWriters, currentWriter, cachedLock->lck_physical)); @@ -225,12 +222,12 @@ { SET_TDBB(tdbb); - Database* dbb = tdbb->getDatabase(); + Attachment* att = tdbb->getAttachment(); bool needFetch; { // scope 1 - Database::CheckoutLockGuard counterGuard(dbb, counterMutex); + Attachment::CheckoutLockGuard counterGuard(att, counterMutex, true); COS_TRACE(("(%p)->lockRead stage 1 readers(%d), blocking(%d), pendingWriters(%d), currentWriter(%d), lck_physical(%d)", this, readers, blocking, pendingWriters, currentWriter, cachedLock->lck_physical)); @@ -246,7 +243,7 @@ while (pendingWriters > 0 || currentWriter) { - Database::Checkout checkoutDbb(dbb); + Attachment::Checkout attCout(att, true); writerFinished.wait(counterMutex); } @@ -256,9 +253,9 @@ if (!pendingLock) break; - counterMutex.leave(); - Database::Checkout checkoutDbb(dbb); - counterMutex.enter(); + Firebird::MutexUnlockGuard cout(counterMutex); + Attachment::Checkout attCout(att, true); + THD_yield(); } needFetch = cachedLock->lck_physical < LCK_read; @@ -275,14 +272,13 @@ if (!LCK_lock(tdbb, cachedLock, LCK_read, wait)) { - Database::CheckoutLockGuard counterGuard(dbb, counterMutex); + Attachment::CheckoutLockGuard counterGuard(att, counterMutex, true); --pendingLock; return false; } { // scope 2 - Database::CheckoutLockGuard counterGuard(dbb, counterMutex); - + Attachment::CheckoutLockGuard counterGuard(att, counterMutex, true); --pendingLock; ++readers; @@ -297,10 +293,9 @@ { SET_TDBB(tdbb); - Database* dbb = tdbb->getDatabase(); + Attachment* att = tdbb->getAttachment(); + Attachment::CheckoutLockGuard counterGuard(att, counterMutex, true); - Database::CheckoutLockGuard counterGuard(dbb, counterMutex); - COS_TRACE(("(%p)->unlockRead readers(%d), blocking(%d), pendingWriters(%d), currentWriter(%d), lck_physical(%d)", this, readers, blocking, pendingWriters, currentWriter, cachedLock->lck_physical)); readers--; @@ -321,7 +316,8 @@ bool GlobalRWLock::tryReleaseLock(thread_db* tdbb) { - Database::CheckoutLockGuard counterGuard(tdbb->getDatabase(), counterMutex); + Attachment* att = tdbb->getAttachment(); + Attachment::CheckoutLockGuard counterGuard(att, counterMutex, true); COS_TRACE(("(%p)->tryReleaseLock readers(%d), blocking(%d), pendingWriters(%d), currentWriter(%d), lck_physical(%d)", this, readers, blocking, pendingWriters, currentWriter, cachedLock->lck_physical)); Modified: firebird/trunk/src/jrd/GlobalRWLock.h =================================================================== --- firebird/trunk/src/jrd/GlobalRWLock.h 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/GlobalRWLock.h 2011-05-09 10:15:19 UTC (rev 52896) @@ -87,8 +87,9 @@ virtual void blockingAstHandler(thread_db* tdbb); + Firebird::Mutex counterMutex; // Protects counter and blocking flag + private: - Firebird::Mutex counterMutex; // Protects counter and blocking flag ULONG pendingLock; ULONG readers; Modified: firebird/trunk/src/jrd/JrdStatement.cpp =================================================================== --- firebird/trunk/src/jrd/JrdStatement.cpp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/JrdStatement.cpp 2011-05-09 10:15:19 UTC (rev 52896) @@ -288,8 +288,6 @@ if (!this) BUGCHECK(167); /* msg 167 invalid SEND request */ - Database::CheckoutLockGuard guard(dbb, dbb->dbb_exe_clone_mutex); - // Search clones for one request in use by this attachment. // If not found, return first inactive request. @@ -539,7 +537,8 @@ sqlText = NULL; - dbb->deletePool(pool); + Jrd::Attachment* const att = tdbb->getAttachment(); + att->deletePool(pool); } // Check that we have enough rights to access all resources this list of triggers touches. Modified: firebird/trunk/src/jrd/Relation.cpp =================================================================== --- firebird/trunk/src/jrd/Relation.cpp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/Relation.cpp 2011-05-09 10:15:19 UTC (rev 52896) @@ -137,10 +137,8 @@ else inst_id = PAG_attachment_id(tdbb); - if (!rel_pages_inst) - { - MemoryPool& pool = *dbb->dbb_permanent; - rel_pages_inst = FB_NEW(pool) RelationPagesInstances(pool); + if (!rel_pages_inst) { + rel_pages_inst = FB_NEW(*rel_pool) RelationPagesInstances(*rel_pool); } size_t pos; @@ -155,7 +153,7 @@ const size_t BULK_ALLOC = 8; RelationPages* allocatedPages = newPages = - FB_NEW(*dbb->dbb_permanent) RelationPages[BULK_ALLOC]; + FB_NEW(*rel_pool) RelationPages[BULK_ALLOC]; rel_pages_free = ++allocatedPages; for (size_t i = 1; i < BULK_ALLOC - 1; i++, allocatedPages++) Modified: firebird/trunk/src/jrd/Relation.h =================================================================== --- firebird/trunk/src/jrd/Relation.h 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/Relation.h 2011-05-09 10:15:19 UTC (rev 52896) @@ -25,6 +25,7 @@ #include "../jrd/jrd.h" #include "../jrd/pag.h" #include "../jrd/val.h" +#include "../jrd/Attachment.h" namespace Jrd { @@ -179,6 +180,7 @@ class jrd_rel : public pool_alloc<type_rel> { public: + MemoryPool* rel_pool; USHORT rel_id; USHORT rel_current_fmt; // Current format number ULONG rel_flags; @@ -278,7 +280,7 @@ public: explicit jrd_rel(MemoryPool& p) - : rel_name(p), rel_owner_name(p), rel_view_contexts(p), rel_security_name(p) + : rel_pool(&p), rel_name(p), rel_owner_name(p), rel_view_contexts(p), rel_security_name(p) { } bool hasTriggers() const; Modified: firebird/trunk/src/jrd/RuntimeStatistics.cpp =================================================================== --- firebird/trunk/src/jrd/RuntimeStatistics.cpp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/RuntimeStatistics.cpp 2011-05-09 10:15:19 UTC (rev 52896) @@ -226,7 +226,7 @@ } } -PerformanceInfo* RuntimeStatistics::computeDifference(Database* dbb, +PerformanceInfo* RuntimeStatistics::computeDifference(Attachment* att, const RuntimeStatistics& new_stat, PerformanceInfo& dest, TraceCountsArray& temp) @@ -262,8 +262,8 @@ // Point TraceCounts to counts array from baseline object if (!all_zeros) { - jrd_rel* relation = size_t(new_cnts->rlc_relation_id) < dbb->dbb_relations->count() ? - (*dbb->dbb_relations)[new_cnts->rlc_relation_id] : NULL; + jrd_rel* relation = size_t(new_cnts->rlc_relation_id) < att->att_relations->count() ? + (*att->att_relations)[new_cnts->rlc_relation_id] : NULL; TraceCounts traceCounts; traceCounts.trc_relation_id = new_cnts->rlc_relation_id; traceCounts.trc_counters = base_cnts->rlc_counter; @@ -276,8 +276,8 @@ } else { - jrd_rel* relation = size_t(new_cnts->rlc_relation_id) < dbb->dbb_relations->count() ? - (*dbb->dbb_relations)[new_cnts->rlc_relation_id] : NULL; + jrd_rel* relation = size_t(new_cnts->rlc_relation_id) < att->att_relations->count() ? + (*att->att_relations)[new_cnts->rlc_relation_id] : NULL; // Point TraceCounts to counts array from object with updated counters TraceCounts traceCounts; Modified: firebird/trunk/src/jrd/RuntimeStatistics.h =================================================================== --- firebird/trunk/src/jrd/RuntimeStatistics.h 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/RuntimeStatistics.h 2011-05-09 10:15:19 UTC (rev 52896) @@ -35,6 +35,7 @@ // #define REL_COUNTS_TREE // #define REL_COUNTS_PTR +class Attachment; class Database; // Performance counters for individual table @@ -135,7 +136,7 @@ // Calculate difference between counts stored in this object and current // counts of given request. Counts stored in object are destroyed. - PerformanceInfo* computeDifference(Database* dbb, const RuntimeStatistics& new_stat, + PerformanceInfo* computeDifference(Attachment* att, const RuntimeStatistics& new_stat, PerformanceInfo& dest, TraceCountsArray& temp); // bool operator==(const RuntimeStatistics& other) const; Modified: firebird/trunk/src/jrd/ValueImpl.cpp =================================================================== --- firebird/trunk/src/jrd/ValueImpl.cpp 2011-05-09 03:17:15 UTC (rev 52895) +++ firebird/trunk/src/jrd/ValueImpl.cpp 2011-05-09 10:15:19 UTC (rev 52896) @@ -45,7 +45,7 @@ void ValueMover::getClientCharSetName(Firebird::MetaName& name) const { thread_db* tdbb = getThreadData(); - Database::SyncGuard dsGuard(tdbb->getDatabase()); + Attachment::SyncGuard attGuard(tdbb->getAttachment()); CharSet* cs = INTL_charset_lookup(tdbb, tdbb->getAttachment()->att_charset); name = cs->getName()... [truncated message content] |