From: Dmitry Y. <di...@us...> - 2008-03-20 16:42:35
|
Build Version : T2.5.0.18981 Firebird 2.5 Unstable (writeBuildNum.sh,v 1.19141 2008/03/20 16:42:32 dimitr Exp ) Update of /cvsroot/firebird/firebird2/src/jrd In directory sc8-pr-cvs17.sourceforge.net:/tmp/cvs-serv4691 Modified Files: Database.cpp Database.h GlobalRWLock.cpp GlobalRWLock.h jrd.cpp jrd.h lck.cpp Log Message: 1) Added proper handle validation for dbb. 2) Changed dbb_sync lifestyle handling. 3) Sync'ed access to the att_long_locks. 4) Put in a temporary workaround for nbackup deadlocks. Index: Database.cpp =================================================================== RCS file: /cvsroot/firebird/firebird2/src/jrd/Database.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -b -U3 -r1.3 -r1.4 --- Database.cpp 19 Mar 2008 16:19:34 -0000 1.3 +++ Database.cpp 20 Mar 2008 16:42:29 -0000 1.4 @@ -20,14 +20,10 @@ * All Rights Reserved. * Contributor(s): ______________________________________. * - * 2002.10.28 Sean Leyne - Code cleanup, removed obsolete "DecOSF" port - * - * 2002.10.29 Sean Leyne - Removed obsolete "Netware" port + * Sean Leyne * Claudio Valderrama C. - * */ - #include "firebird.h" #include "../jrd/ibase.h" #include "../jrd/common.h" @@ -47,7 +43,6 @@ // Definition of block types for data allocation in JRD #include "../include/fb_blk.h" - namespace Jrd { bool Database::onRawDevice() const @@ -70,6 +65,8 @@ { MemoryPool::deletePool(dbb_pools[i]); } + + dbb_sync->release(); } void Database::deletePool(MemoryPool* pool) Index: Database.h =================================================================== RCS file: /cvsroot/firebird/firebird2/src/jrd/Database.h,v retrieving revision 1.7 retrieving revision 1.8 diff -b -U3 -r1.7 -r1.8 --- Database.h 13 Mar 2008 14:20:30 -0000 1.7 +++ Database.h 20 Mar 2008 16:42:29 -0000 1.8 @@ -34,7 +34,6 @@ #include "firebird.h" #include "../jrd/cch.h" #include "../jrd/que.h" - #include "../jrd/gdsassert.h" #include "../jrd/common.h" #include "../jrd/dsc.h" @@ -45,6 +44,8 @@ #include "../jrd/val.h" #include "../jrd/irq.h" #include "../jrd/drq.h" +#include "../include/gen/iberror.h" + #if defined(UNIX) && defined(SUPERSERVER) #include <setjmp.h> #endif @@ -57,14 +58,14 @@ #include "../common/classes/stack.h" #include "../common/classes/timestamp.h" #include "../common/classes/GenericMap.h" +#include "../common/classes/RefCounted.h" +#include "../common/classes/PublicHandle.h" #include "../jrd/RandomGenerator.h" #include "../jrd/os/guid.h" #include "../jrd/sbm.h" #include "../jrd/flu.h" #include "../jrd/RuntimeStatistics.h" - - class CharSetContainer; namespace Jrd @@ -76,7 +77,6 @@ class jrd_rel; class Shadow; class BlobFilter; - //class PageControl; class TxPageCache; class BackupManager; class vcl; @@ -84,24 +84,15 @@ typedef Firebird::ObjectsArray<Trigger> trig_vec; -class Database : public pool_alloc<type_dbb> +class Database : public pool_alloc<type_dbb>, public Firebird::PublicHandle { - class Sync + class Sync : public Firebird::RefCounted { public: Sync() - : threadId(0), isAst(false) + : threadId(0), isAst(false), astInhibits(0) {} - ~Sync() - { - if (threadId) - { - syncMutex.leave(); - threadId = 0; - } - } - void lock(bool ast = false) { const FB_THREAD_ID currentId = getThreadId(); @@ -113,6 +104,12 @@ stateMutex.leave(); ++waiters; syncMutex.enter(); + while (ast && astInhibits) + { + syncMutex.leave(); + THREAD_SLEEP(1); + syncMutex.enter(); + } --waiters; stateMutex.enter(); threadId = currentId; @@ -140,7 +137,26 @@ return (waiters.value() > 0); } + void disableAsts() + { + ++astInhibits; + } + + void enableAsts() + { + --astInhibits; + } + private: + ~Sync() + { + if (threadId) + { + syncMutex.leave(); + threadId = 0; + } + } + // copying is prohibited Sync(const Sync&); Sync& operator=(const Sync&); @@ -150,29 +166,59 @@ Firebird::AtomicCounter waiters; FB_THREAD_ID threadId; bool isAst; + int astInhibits; }; public: + class AstInhibit + { + public: + AstInhibit(Database* dbb) + : sync(*dbb->dbb_sync) + { + sync.disableAsts(); + } + ~AstInhibit() + { + sync.enableAsts(); + } + Sync& sync; + }; + class SyncGuard { public: - SyncGuard(Database* arg, bool ast = false) - : dbb(*arg) + SyncGuard(Database* dbb, bool ast = false) + : sync(*dbb->dbb_sync) + { + if (!dbb->checkHandle()) { - dbb.dbb_sync.lock(ast); + Firebird::status_exception::raise(isc_bad_db_handle, 0); + } + + sync.addRef(); + sync.lock(ast); + + if (!dbb->checkHandle()) + { + sync.unlock(); + sync.release(); + Firebird::status_exception::raise(isc_bad_db_handle, 0); + } } ~SyncGuard() { try { - dbb.dbb_sync.unlock(); + sync.unlock(); } catch (const Firebird::Exception&) { Firebird::MutexLockGuard::onDtorException(); } + sync.release(); } private: @@ -180,19 +226,19 @@ SyncGuard(const SyncGuard&); SyncGuard& operator=(const SyncGuard&); - Database& dbb; + Sync& sync; }; class Checkout { public: - explicit Checkout(Database* arg, bool flag = false) - : dbb(*arg), io(flag) + explicit Checkout(Database* dbb, bool flag = false) + : sync(*dbb->dbb_sync), io(flag) { #ifndef SUPERSERVER if (!io) #endif - dbb.checkout(); + sync.unlock(true); } ~Checkout() @@ -200,7 +246,7 @@ #ifndef SUPERSERVER if (!io) #endif - dbb.checkin(); + sync.lock(); } private: @@ -208,7 +254,7 @@ Checkout(const Checkout&); Checkout& operator=(const Checkout&); - Database& dbb; + Sync& sync; const bool io; }; @@ -275,7 +321,17 @@ return ++counter; } - mutable Sync dbb_sync; // Database sync primitive + bool checkHandle() const + { + if (!isKnownHandle()) + { + return false; + } + + return TypedHandle::checkHandle(); + } + + mutable Sync* dbb_sync; // Database sync primitive Database* dbb_next; // Next database block in system Attachment* dbb_attachments; // Active attachments @@ -390,16 +446,6 @@ return ++dbb_current_id; } - void checkin() const - { - dbb_sync.lock(); - } - - void checkout() const - { - dbb_sync.unlock(true); - } - // returns true if primary file is located on raw device bool onRawDevice() const; @@ -431,6 +477,8 @@ dbb_charsets(*p), dbb_functions(*p) { + dbb_sync = FB_NEW(*getDefaultMemoryPool()) Sync; + dbb_sync->addRef(); dbb_pools.add(p); dbb_internal.grow(irq_MAX); dbb_dyn_req.grow(drq_MAX); Index: GlobalRWLock.cpp =================================================================== RCS file: /cvsroot/firebird/firebird2/src/jrd/GlobalRWLock.cpp,v retrieving revision 1.14 retrieving revision 1.15 diff -b -U3 -r1.14 -r1.15 --- GlobalRWLock.cpp 19 Mar 2008 16:19:34 -0000 1.14 +++ GlobalRWLock.cpp 20 Mar 2008 16:42:29 -0000 1.15 @@ -212,8 +212,9 @@ COS_TRACE(("Replace lock, type=%i", cached_lock->lck_type)); if (newLock->lck_physical > cached_lock->lck_physical) { LCK_release(tdbb, cached_lock); - delete cached_lock; + Lock* const old_lock = cached_lock; cached_lock = newLock; + delete old_lock; if (!LCK_set_owner_handle(tdbb, cached_lock, LCK_get_owner_handle_by_type(tdbb, physicalLockOwner))) { COS_TRACE(("Error: set owner handle for captured lock, type=%i", cached_lock->lck_type)); LCK_release(tdbb, cached_lock); Index: GlobalRWLock.h =================================================================== RCS file: /cvsroot/firebird/firebird2/src/jrd/GlobalRWLock.h,v retrieving revision 1.12 retrieving revision 1.13 diff -b -U3 -r1.12 -r1.13 --- GlobalRWLock.h 29 Jan 2008 01:36:39 -0000 1.12 +++ GlobalRWLock.h 20 Mar 2008 16:42:29 -0000 1.13 @@ -153,21 +153,21 @@ SLONG, ObjectOwnerData, Firebird::DefaultComparator<SLONG> > readers; ObjectOwnerData writer; - class CountersLockHolder { + class CountersLockHolder : public Database::AstInhibit { public: CountersLockHolder(Database* dbb, Firebird::Mutex& alock) - : lock(&alock) + : Database::AstInhibit(dbb), lock(alock) { - Database::Checkout dcoHolder(dbb, true); - lock->enter(); + Database::Checkout dcoHolder(dbb); + lock.enter(); } - ~CountersLockHolder() { lock->leave(); } + ~CountersLockHolder() { lock.leave(); } private: // Forbid copy constructor CountersLockHolder(const CountersLockHolder& source); - Firebird::Mutex* lock; + Firebird::Mutex& lock; }; static int blocking_ast_cached_lock(void* ast_object); Index: jrd.cpp =================================================================== RCS file: /cvsroot/firebird/firebird2/src/jrd/jrd.cpp,v retrieving revision 1.420 retrieving revision 1.421 diff -b -U3 -r1.420 -r1.421 --- jrd.cpp 19 Mar 2008 16:19:34 -0000 1.420 +++ jrd.cpp 20 Mar 2008 16:42:29 -0000 1.421 @@ -216,15 +216,15 @@ Firebird::status_exception::raise(isc_bad_svc_handle, 0); } - class DatabaseContextHolder : public Jrd::ContextPoolHolder + class DatabaseContextHolder : public Database::SyncGuard, public Jrd::ContextPoolHolder { public: DatabaseContextHolder(thread_db* arg) - : Jrd::ContextPoolHolder(arg, arg->getDatabase()->dbb_permanent), + : Database::SyncGuard(arg->getDatabase()), + Jrd::ContextPoolHolder(arg, arg->getDatabase()->dbb_permanent), tdbb(arg) { Database* dbb = tdbb->getDatabase(); - dbb->dbb_sync.lock(); ++dbb->dbb_use_count; } @@ -234,7 +234,6 @@ if (dbb->checkHandle()) { --dbb->dbb_use_count; - dbb->dbb_sync.unlock(); } } @@ -3730,7 +3729,7 @@ **************************************/ Database* dbb = tdbb->getDatabase(); - if (dbb->dbb_sync.hasContention()) + if (dbb->dbb_sync->hasContention()) { Database::Checkout dcoHolder(dbb); THREAD_YIELD(); @@ -4839,6 +4838,8 @@ * block doesn't get dereferenced after it is released * **************************************/ + Database::CheckoutLockGuard guard(attachment->att_database, attachment->att_long_locks_mutex); + Lock* long_lock = attachment->att_long_locks; while (long_lock) { Lock* next = long_lock->lck_next; Index: jrd.h =================================================================== RCS file: /cvsroot/firebird/firebird2/src/jrd/jrd.h,v retrieving revision 1.229 retrieving revision 1.230 diff -b -U3 -r1.229 -r1.230 --- jrd.h 19 Mar 2008 16:19:34 -0000 1.229 +++ jrd.h 20 Mar 2008 16:42:29 -0000 1.230 @@ -277,6 +277,7 @@ // customized firebird.msg file doesn't work; the only way is to use an env var. Firebird::PathName att_lc_messages; // attachment's preference for message natural language Lock* att_long_locks; // outstanding two phased locks + Firebird::Mutex att_long_locks_mutex; vec<Lock*>* att_compatibility_table; // hash table of compatible locks vcl* att_val_errors; Firebird::PathName att_working_directory; // Current working directory is cached Index: lck.cpp =================================================================== RCS file: /cvsroot/firebird/firebird2/src/jrd/lck.cpp,v retrieving revision 1.79 retrieving revision 1.80 diff -b -U3 -r1.79 -r1.80 --- lck.cpp 19 Mar 2008 20:46:04 -0000 1.79 +++ lck.cpp 20 Mar 2008 16:42:29 -0000 1.80 @@ -1396,6 +1396,8 @@ // Delist in old attachment if (lock->lck_attachment) { + Firebird::MutexLockGuard guard(lock->lck_attachment->att_long_locks_mutex); + // Check that attachment seems to be valid, check works only when DEBUG_GDS_ALLOC is defined fb_assert(lock->lck_attachment->att_flags != 0xDEADBEEF); @@ -1423,6 +1425,8 @@ // Enlist in new attachment if (attachment) { + Firebird::MutexLockGuard guard(attachment->att_long_locks_mutex); + // Check that attachment seems to be valid, check works only when DEBUG_GDS_ALLOC is defined fb_assert(attachment->att_flags != 0xDEADBEEF); |