8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 09:23:03 +01:00

Fixed CORE-3217: Server crashes inside the lock manager when multiple connections attaching/detaching simultaneously.

This commit is contained in:
dimitr 2010-11-08 10:10:29 +00:00
parent c45d0e5cdb
commit 475f873682
6 changed files with 59 additions and 34 deletions

View File

@ -93,7 +93,8 @@ namespace Jrd
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.
dbb_lock_mgr = NULL;
LockManager::destroy(dbb_lock_mgr);
EventManager::destroy(dbb_event_mgr);
}
void Database::deletePool(MemoryPool* pool)

View File

@ -330,8 +330,8 @@ public:
mutable Firebird::RefPtr<Sync> dbb_sync; // Database sync primitive
Firebird::RefPtr<LockManager> dbb_lock_mgr;
Firebird::RefPtr<EventManager> dbb_event_mgr;
LockManager* dbb_lock_mgr;
EventManager* dbb_event_mgr;
Database* dbb_next; // Next database block in system
Attachment* dbb_attachments; // Active attachments

View File

@ -76,7 +76,7 @@ Firebird::GlobalPtr<Firebird::Mutex> EventManager::g_mapMutex;
void EventManager::init(Attachment* attachment)
{
Database* dbb = attachment->att_database;
Database* const dbb = attachment->att_database;
EventManager* eventMgr = dbb->dbb_event_mgr;
if (!eventMgr)
{
@ -87,10 +87,16 @@ void EventManager::init(Attachment* attachment)
if (!g_emMap->get(id, eventMgr))
{
eventMgr = new EventManager(id);
if (g_emMap->put(id, eventMgr))
{
fb_assert(false);
}
}
fb_assert(eventMgr);
eventMgr->addRef();
dbb->dbb_event_mgr = eventMgr;
}
@ -101,6 +107,25 @@ void EventManager::init(Attachment* attachment)
}
void EventManager::destroy(EventManager* eventMgr)
{
if (eventMgr)
{
const Firebird::string id = eventMgr->m_dbId;
Firebird::MutexLockGuard guard(g_mapMutex);
if (!eventMgr->release())
{
if (!g_emMap->remove(id))
{
fb_assert(false);
}
}
}
}
EventManager::EventManager(const Firebird::string& id)
: PID(getpid()),
m_header(NULL),
@ -111,13 +136,6 @@ EventManager::EventManager(const Firebird::string& id)
m_exiting(false)
{
attach_shared_file();
Firebird::MutexLockGuard guard(g_mapMutex);
if (g_emMap->put(m_dbId, this))
{
fb_assert(false);
}
}
@ -157,13 +175,6 @@ EventManager::~EventManager()
release_shmem();
detach_shared_file();
Firebird::MutexLockGuard guard(g_mapMutex);
if (!g_emMap->remove(m_dbId))
{
fb_assert(false);
}
}

View File

@ -35,7 +35,7 @@ namespace Jrd {
class Attachment;
class EventManager : public Firebird::RefCounted, public Firebird::GlobalStorage
class EventManager : private Firebird::RefCounted, public Firebird::GlobalStorage
{
typedef Firebird::GenericMap<Firebird::Pair<Firebird::Left<Firebird::string, EventManager*> > > DbEventMgrMap;
@ -46,6 +46,7 @@ class EventManager : public Firebird::RefCounted, public Firebird::GlobalStorage
public:
static void init(Attachment*);
static void destroy(EventManager*);
explicit EventManager(const Firebird::string&);
~EventManager();

View File

@ -176,14 +176,39 @@ LockManager* LockManager::create(const Firebird::string& id)
if (!g_lmMap->get(id, lockMgr))
{
lockMgr = new LockManager(id);
if (g_lmMap->put(id, lockMgr))
{
fb_assert(false);
}
}
fb_assert(lockMgr);
lockMgr->addRef();
return lockMgr;
}
void LockManager::destroy(LockManager* lockMgr)
{
if (lockMgr)
{
const Firebird::string id = lockMgr->m_dbId;
Firebird::MutexLockGuard guard(g_mapMutex);
if (!lockMgr->release())
{
if (!g_lmMap->remove(id))
{
fb_assert(false);
}
}
}
}
LockManager::LockManager(const Firebird::string& id)
: PID(getpid()),
m_bugcheck(false),
@ -203,13 +228,6 @@ LockManager::LockManager(const Firebird::string& id)
{
Firebird::status_exception::raise(local_status);
}
Firebird::MutexLockGuard guard(g_mapMutex);
if (g_lmMap->put(m_dbId, this))
{
fb_assert(false);
}
}
@ -271,13 +289,6 @@ LockManager::~LockManager()
ISC_unmap_file(local_status, &m_extents[i].sh_data);
}
#endif //USE_SHMEM_EXT
Firebird::MutexLockGuard guard(g_mapMutex);
if (!g_lmMap->remove(m_dbId))
{
fb_assert(false);
}
}

View File

@ -310,7 +310,7 @@ namespace Jrd {
class thread_db;
class LockManager : public Firebird::RefCounted, public Firebird::GlobalStorage
class LockManager : private Firebird::RefCounted, public Firebird::GlobalStorage
{
typedef Firebird::GenericMap<Firebird::Pair<Firebird::Left<Firebird::string, LockManager*> > > DbLockMgrMap;
@ -321,6 +321,7 @@ class LockManager : public Firebird::RefCounted, public Firebird::GlobalStorage
public:
static LockManager* create(const Firebird::string&);
static void destroy(LockManager*);
bool initializeOwner(thread_db*, LOCK_OWNER_T, UCHAR, SRQ_PTR*);
void shutdownOwner(thread_db*, SRQ_PTR*);