diff --git a/src/jrd/extds/InternalDS.cpp b/src/jrd/extds/InternalDS.cpp index dbd0c96b70..70ccb789ba 100644 --- a/src/jrd/extds/InternalDS.cpp +++ b/src/jrd/extds/InternalDS.cpp @@ -168,7 +168,13 @@ void InternalConnection::doDetach(thread_db *tdbb) m_attachment = att; } - if (status[1]) { + if (status[1] == isc_att_shutdown) + { + m_attachment = 0; + fb_utils::init_status(status); + } + if (status[1]) + { raise(status, tdbb, "detach"); } } @@ -283,6 +289,12 @@ void InternalTransaction::doRollback(ISC_STATUS* status, thread_db *tdbb, bool r else jrd8_rollback_transaction(status, &m_transaction); } + + if (status[1] == isc_att_shutdown && !retain) + { + m_transaction = 0; + fb_utils::init_status(status); + } } diff --git a/src/jrd/extds/IscDS.cpp b/src/jrd/extds/IscDS.cpp index 1ea8d4808e..681e28699f 100644 --- a/src/jrd/extds/IscDS.cpp +++ b/src/jrd/extds/IscDS.cpp @@ -60,6 +60,7 @@ public: static RegisterFBProvider reg; +static bool isConnectionBrokenError(ISC_STATUS status); static void parseSQLDA(XSQLDA *xsqlda, UCharBuffer &buff, Firebird::Array &descs); static UCHAR sqlTypeToDscType(SSHORT sqlType); @@ -167,19 +168,8 @@ void IscConnection::doDetach(thread_db *tdbb) m_handle = h; } - switch (status[1]) - { - case 0: // nothing to do - break; - case isc_att_shutdown: - case isc_network_error: - case isc_net_read_err: - case isc_net_write_err: - m_handle = 0; - break; - default: + if (status[1] && !isConnectionBrokenError(status[1])) raise(status, tdbb, "detach"); - } } bool IscConnection::cancelExecution(thread_db *tdbb) @@ -268,6 +258,12 @@ void IscTransaction::doRollback(ISC_STATUS* status, thread_db *tdbb, bool retain else m_iscProvider.isc_rollback_transaction(status, &m_handle); + if (status[1] && isConnectionBrokenError(status[1]) && !retain) + { + m_handle = 0; + fb_utils::init_status(status); + } + fb_assert(retain && m_handle || !retain && !m_handle || status[1] && m_handle); } @@ -1505,6 +1501,20 @@ void FBProvider::loadAPI() } +static bool isConnectionBrokenError(ISC_STATUS status) +{ + switch (status) + { + case isc_att_shutdown: + case isc_network_error: + case isc_net_read_err: + case isc_net_write_err: + return true; + } + return false; +}; + + static void parseSQLDA(XSQLDA *xsqlda, UCharBuffer &buff, Firebird::Array &descs) { size_t offset = 0; diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 44ccad969e..2e75c6b381 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -512,9 +512,9 @@ static THREAD_ENTRY_DECLARE shutdown_thread(THREAD_ENTRY_PARAM); static void cancel_attachments() { + MutexLockGuard guard(databases_mutex); engineShuttingDown = true; - MutexLockGuard guard(databases_mutex); for (Database* dbb = databases; dbb; dbb = dbb->dbb_next) { if ( !(dbb->dbb_flags & (DBB_bugcheck | DBB_not_in_use | DBB_security_db)) ) @@ -5733,13 +5733,10 @@ static void purge_attachment(thread_db* tdbb, } } - const bool wasShuttingDown = engineShuttingDown; try { // allow to free resources used by dynamic statements - engineShuttingDown = false; EDS::Manager::jrdAttachmentEnd(tdbb, attachment); - engineShuttingDown = wasShuttingDown; const ULONG att_flags = attachment->att_flags; attachment->att_flags |= ATT_shutdown; @@ -5758,7 +5755,6 @@ static void purge_attachment(thread_db* tdbb, } catch (const Exception&) { - engineShuttingDown = wasShuttingDown; attachment->att_flags |= (ATT_shutdown | ATT_purge_error); throw; }