|
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] |