"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/jrd/extds/ExtDS.cpp" between
Firebird-3.0.2.32703-0.tar.bz2 and Firebird-3.0.4.33054-0.tar.bz2

About: Firebird is a relational database offering many ANSI SQL standard features.

ExtDS.cpp  (Firebird-3.0.2.32703-0.tar.bz2):ExtDS.cpp  (Firebird-3.0.4.33054-0.tar.bz2)
skipping to change at line 63 skipping to change at line 63
Provider* Manager::m_providers = NULL; Provider* Manager::m_providers = NULL;
volatile bool Manager::m_initialized = false; volatile bool Manager::m_initialized = false;
Manager::Manager(MemoryPool& pool) : Manager::Manager(MemoryPool& pool) :
PermanentStorage(pool) PermanentStorage(pool)
{ {
} }
Manager::~Manager() Manager::~Manager()
{ {
ThreadContextHolder tdbb;
while (m_providers) while (m_providers)
{ {
Provider* to_delete = m_providers; Provider* to_delete = m_providers;
m_providers = m_providers->m_next; m_providers = m_providers->m_next;
to_delete->clearConnections(tdbb);
delete to_delete; delete to_delete;
} }
} }
void Manager::addProvider(Provider* provider) void Manager::addProvider(Provider* provider)
{ {
for (const Provider* prv = m_providers; prv; prv = prv->m_next) for (const Provider* prv = m_providers; prv; prv = prv->m_next)
{ {
if (prv->m_name == provider->m_name) { if (prv->m_name == provider->m_name) {
return; return;
skipping to change at line 273 skipping to change at line 276
} }
void Provider::cancelConnections() void Provider::cancelConnections()
{ {
MutexLockGuard guard(m_mutex, FB_FUNCTION); MutexLockGuard guard(m_mutex, FB_FUNCTION);
Connection** ptr = m_connections.begin(); Connection** ptr = m_connections.begin();
Connection** end = m_connections.end(); Connection** end = m_connections.end();
for (; ptr < end; ptr++) { for (; ptr < end; ptr++) {
(*ptr)->cancelExecution(); (*ptr)->cancelExecution(true);
} }
} }
// Connection // Connection
Connection::Connection(Provider& prov) : Connection::Connection(Provider& prov) :
PermanentStorage(prov.getPool()), PermanentStorage(prov.getPool()),
m_provider(prov), m_provider(prov),
m_dbName(getPool()), m_dbName(getPool()),
m_dpb(getPool(), ClumpletReader::dpbList, MAX_DPB_SIZE), m_dpb(getPool(), ClumpletReader::dpbList, MAX_DPB_SIZE),
skipping to change at line 364 skipping to change at line 367
return m_dpb.simpleCompare(dpb); return m_dpb.simpleCompare(dpb);
} }
Transaction* Connection::createTransaction() Transaction* Connection::createTransaction()
{ {
Transaction* tran = doCreateTransaction(); Transaction* tran = doCreateTransaction();
m_transactions.add(tran); m_transactions.add(tran);
return tran; return tran;
} }
void Connection::deleteTransaction(Transaction* tran) void Connection::deleteTransaction(thread_db* tdbb, Transaction* tran)
{ {
// Close all active statements in tran context avoiding commit of already
// deleted transaction
Statement** stmt_ptr = m_statements.begin();
while (stmt_ptr < m_statements.end())
{
Statement* stmt = *stmt_ptr;
if (stmt->getTransaction() == tran)
{
if (stmt->isActive())
stmt->close(tdbb, true);
}
// close() above could destroy statement and remove it from m_sta
tements
if (stmt_ptr < m_statements.end() && *stmt_ptr == stmt)
stmt_ptr++;
}
FB_SIZE_T pos; FB_SIZE_T pos;
if (m_transactions.find(tran, pos)) if (m_transactions.find(tran, pos))
{ {
m_transactions.remove(pos); m_transactions.remove(pos);
delete tran; delete tran;
} }
else { else {
fb_assert(false); fb_assert(false);
} }
if (!m_used_stmts && m_transactions.getCount() == 0 && !m_deleting) if (!m_used_stmts && m_transactions.getCount() == 0 && !m_deleting)
m_provider.releaseConnection(JRD_get_thread_data(), *this); m_provider.releaseConnection(tdbb, *this);
} }
Statement* Connection::createStatement(const string& sql) Statement* Connection::createStatement(const string& sql)
{ {
m_used_stmts++; m_used_stmts++;
for (Statement** stmt_ptr = &m_freeStatements; *stmt_ptr; stmt_ptr = &(*s tmt_ptr)->m_nextFree) for (Statement** stmt_ptr = &m_freeStatements; *stmt_ptr; stmt_ptr = &(*s tmt_ptr)->m_nextFree)
{ {
Statement* stmt = *stmt_ptr; Statement* stmt = *stmt_ptr;
if (stmt->getSql() == sql) if (stmt->getSql() == sql)
skipping to change at line 444 skipping to change at line 463
if (!m_used_stmts && m_transactions.getCount() == 0 && !m_deleting) if (!m_used_stmts && m_transactions.getCount() == 0 && !m_deleting)
m_provider.releaseConnection(tdbb, *this); m_provider.releaseConnection(tdbb, *this);
} }
void Connection::clearTransactions(Jrd::thread_db* tdbb) void Connection::clearTransactions(Jrd::thread_db* tdbb)
{ {
while (m_transactions.getCount()) while (m_transactions.getCount())
{ {
Transaction* tran = m_transactions[0]; Transaction* tran = m_transactions[0];
tran->rollback(tdbb, false); try
{
tran->rollback(tdbb, false);
}
catch (const Exception&)
{
if (!m_deleting)
throw;
}
} }
} }
void Connection::clearStatements(thread_db* tdbb) void Connection::clearStatements(thread_db* tdbb)
{ {
Statement** stmt_ptr = m_statements.begin(); Statement** stmt_ptr = m_statements.begin();
Statement** end = m_statements.end(); while (stmt_ptr < m_statements.end())
for (; stmt_ptr < end; stmt_ptr++)
{ {
Statement* stmt = *stmt_ptr; Statement* stmt = *stmt_ptr;
if (stmt->isActive()) if (stmt->isActive())
stmt->close(tdbb); stmt->close(tdbb);
Statement::deleteStatement(tdbb, stmt);
// close() above could destroy statement and remove it from m_sta
tements
if (stmt_ptr < m_statements.end() && *stmt_ptr == stmt)
{
Statement::deleteStatement(tdbb, stmt);
stmt_ptr++;
}
} }
m_statements.clear(); m_statements.clear();
m_freeStatements = NULL; m_freeStatements = NULL;
m_free_stmts = m_used_stmts = 0; m_free_stmts = m_used_stmts = 0;
} }
void Connection::detach(thread_db* tdbb) void Connection::detach(thread_db* tdbb)
{ {
skipping to change at line 654 skipping to change at line 685
FbLocalStatus status; FbLocalStatus status;
doCommit(&status, tdbb, retain); doCommit(&status, tdbb, retain);
if (status->getState() & IStatus::STATE_ERRORS) { if (status->getState() & IStatus::STATE_ERRORS) {
m_connection.raise(&status, tdbb, "transaction commit"); m_connection.raise(&status, tdbb, "transaction commit");
} }
if (!retain) if (!retain)
{ {
detachFromJrdTran(); detachFromJrdTran();
m_connection.deleteTransaction(this); m_connection.deleteTransaction(tdbb, this);
} }
} }
void Transaction::rollback(thread_db* tdbb, bool retain) void Transaction::rollback(thread_db* tdbb, bool retain)
{ {
FbLocalStatus status; FbLocalStatus status;
doRollback(&status, tdbb, retain); doRollback(&status, tdbb, retain);
Connection& conn = m_connection; Connection& conn = m_connection;
if (!retain) if (!retain)
{ {
detachFromJrdTran(); detachFromJrdTran();
m_connection.deleteTransaction(this); m_connection.deleteTransaction(tdbb, this);
} }
if (status->getState() & IStatus::STATE_ERRORS) { if (status->getState() & IStatus::STATE_ERRORS) {
conn.raise(&status, tdbb, "transaction rollback"); conn.raise(&status, tdbb, "transaction rollback");
} }
} }
Transaction* Transaction::getTransaction(thread_db* tdbb, Connection* conn, TraS cope tra_scope) Transaction* Transaction::getTransaction(thread_db* tdbb, Connection* conn, TraS cope tra_scope)
{ {
jrd_tra* tran = tdbb->getTransaction(); jrd_tra* tran = tdbb->getTransaction();
skipping to change at line 707 skipping to change at line 738
ext_tran->start(tdbb, ext_tran->start(tdbb,
tra_scope, tra_scope,
traMode, traMode,
tran->tra_flags & TRA_readonly, tran->tra_flags & TRA_readonly,
tran->getLockWait() != 0, tran->getLockWait() != 0,
-tran->getLockWait() -tran->getLockWait()
); );
} }
catch (const Exception&) catch (const Exception&)
{ {
conn->deleteTransaction(ext_tran); conn->deleteTransaction(tdbb, ext_tran);
throw; throw;
} }
} }
return ext_tran; return ext_tran;
} }
void Transaction::detachFromJrdTran() void Transaction::detachFromJrdTran()
{ {
if (m_scope != traCommon) if (m_scope != traCommon)
return; return;
fb_assert(m_jrdTran); fb_assert(m_jrdTran || m_connection.isBroken());
if (!m_jrdTran) if (!m_jrdTran)
return; return;
Transaction** tran_ptr = &m_jrdTran->tra_ext_common; Transaction** tran_ptr = &m_jrdTran->tra_ext_common;
m_jrdTran = NULL;
for (; *tran_ptr; tran_ptr = &(*tran_ptr)->m_nextTran) for (; *tran_ptr; tran_ptr = &(*tran_ptr)->m_nextTran)
{ {
if (*tran_ptr == this) if (*tran_ptr == this)
{ {
*tran_ptr = this->m_nextTran; *tran_ptr = this->m_nextTran;
this->m_nextTran = NULL; this->m_nextTran = NULL;
return; return;
} }
} }
skipping to change at line 804 skipping to change at line 836
{ {
} }
Statement::~Statement() Statement::~Statement()
{ {
clearNames(); clearNames();
} }
void Statement::deleteStatement(Jrd::thread_db* tdbb, Statement* stmt) void Statement::deleteStatement(Jrd::thread_db* tdbb, Statement* stmt)
{ {
if (stmt->m_boundReq)
stmt->unBindFromRequest();
stmt->deallocate(tdbb); stmt->deallocate(tdbb);
delete stmt; delete stmt;
} }
void Statement::prepare(thread_db* tdbb, Transaction* tran, const string& sql, b ool named) void Statement::prepare(thread_db* tdbb, Transaction* tran, const string& sql, b ool named)
{ {
fb_assert(!m_active); fb_assert(!m_active);
// already prepared the same non-empty statement // already prepared the same non-empty statement
if (isAllocated() && (m_sql == sql) && (m_sql != "") && if (isAllocated() && (m_sql == sql) && (m_sql != "") &&
skipping to change at line 905 skipping to change at line 939
FbLocalStatus status; FbLocalStatus status;
Arg::Gds(isc_sing_select_err).copyTo(&status); Arg::Gds(isc_sing_select_err).copyTo(&status);
raise(&status, tdbb, "isc_dsql_fetch"); raise(&status, tdbb, "isc_dsql_fetch");
} }
return false; return false;
} }
return true; return true;
} }
void Statement::close(thread_db* tdbb) void Statement::close(thread_db* tdbb, bool invalidTran)
{ {
// we must stuff exception if and only if this is the first time it occur s // we must stuff exception if and only if this is the first time it occur s
// once we stuff exception we must punt // once we stuff exception we must punt
const bool wasError = m_error; const bool wasError = m_error;
bool doPunt = false; bool doPunt = false;
if (isAllocated() && m_active) if (isAllocated() && m_active)
{ {
fb_assert(isAllocated() && m_stmt_selectable); fb_assert(isAllocated() && m_stmt_selectable);
skipping to change at line 934 skipping to change at line 968
ex.stuffException(tdbb->tdbb_status_vector); ex.stuffException(tdbb->tdbb_status_vector);
} }
} }
m_active = false; m_active = false;
} }
if (m_boundReq) { if (m_boundReq) {
unBindFromRequest(); unBindFromRequest();
} }
if (invalidTran)
m_transaction = NULL;
if (m_transaction && m_transaction->getScope() == traAutonomous) if (m_transaction && m_transaction->getScope() == traAutonomous)
{ {
bool commitFailed = false; bool commitFailed = false;
if (!m_error) if (!m_error)
{ {
try { try {
m_transaction->commit(tdbb, false); m_transaction->commit(tdbb, false);
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
skipping to change at line 1044 skipping to change at line 1081
} }
} }
else { else {
ret = ttOther; ret = ttOther;
} }
break; break;
case '-': case '-':
if (p < end && *p == '-') if (p < end && *p == '-')
{ {
while (p < end) while (++p < end)
{ {
if (*p++ == '\n') if (*p == '\r')
{ {
p--; p++;
ret = ttComment; if (p < end && *p == '\n')
p++;
break; break;
} }
else if (*p == '\n')
break;
} }
ret = ttComment;
} }
else { else {
ret = ttOther; ret = ttOther;
} }
break; break;
default: default:
if (classes(c) & CHR_DIGIT) if (classes(c) & CHR_DIGIT)
{ {
while (p < end && (classes(*p) & CHR_DIGIT)) while (p < end && (classes(*p) & CHR_DIGIT))
skipping to change at line 1573 skipping to change at line 1614
m_ReqImpure = NULL; m_ReqImpure = NULL;
m_boundReq = NULL; m_boundReq = NULL;
m_prevInReq = m_nextInReq = NULL; m_prevInReq = m_nextInReq = NULL;
} }
// EngineCallbackGuard // EngineCallbackGuard
void EngineCallbackGuard::init(thread_db* tdbb, Connection& conn, const char* fr om) void EngineCallbackGuard::init(thread_db* tdbb, Connection& conn, const char* fr om)
{ {
m_tdbb = tdbb; m_tdbb = tdbb;
m_mutex = conn.isConnected() ? &conn.m_mutex : &conn.m_provider.m_mutex; m_mutex = &conn.m_mutex;
m_saveConnection = NULL; m_saveConnection = NULL;
if (m_tdbb) if (m_tdbb)
{ {
jrd_tra* transaction = m_tdbb->getTransaction(); jrd_tra* transaction = m_tdbb->getTransaction();
if (transaction) if (transaction)
{ {
if (transaction->tra_callback_count >= MAX_CALLBACKS) if (transaction->tra_callback_count >= MAX_CALLBACKS)
ERR_post(Arg::Gds(isc_exec_sql_max_call_exceeded) ); ERR_post(Arg::Gds(isc_exec_sql_max_call_exceeded) );
transaction->tra_callback_count++; transaction->tra_callback_count++;
} }
Jrd::Attachment* attachment = m_tdbb->getAttachment(); Jrd::Attachment* attachment = m_tdbb->getAttachment();
if (attachment) if (attachment)
{ {
m_saveConnection = attachment->att_ext_connection; m_saveConnection = attachment->att_ext_connection;
attachment->att_ext_connection = &conn; m_stable = attachment->getStable();
attachment->getStable()->getMutex()->leave(); m_stable->getMutex()->leave();
MutexLockGuard guardAsync(*m_stable->getMutex(true, true)
, FB_FUNCTION);
MutexLockGuard guardMain(*m_stable->getMutex(), FB_FUNCTI
ON);
if (m_stable->getHandle() == attachment)
attachment->att_ext_connection = &conn;
} }
} }
if (m_mutex) { if (m_mutex) {
m_mutex->enter(from); m_mutex->enter(from);
} }
} }
EngineCallbackGuard::~EngineCallbackGuard() EngineCallbackGuard::~EngineCallbackGuard()
{ {
if (m_mutex) { if (m_mutex) {
m_mutex->leave(); m_mutex->leave();
} }
if (m_tdbb) if (m_tdbb)
{ {
Jrd::Attachment* attachment = m_tdbb->getAttachment(); Jrd::Attachment* attachment = m_tdbb->getAttachment();
if (attachment && m_stable.hasData())
if (attachment)
{ {
attachment->getStable()->getMutex()->enter(FB_FUNCTION); MutexLockGuard guardAsync(*m_stable->getMutex(true, true)
attachment->att_ext_connection = m_saveConnection; , FB_FUNCTION);
m_stable->getMutex()->enter(FB_FUNCTION);
if (m_stable->getHandle() == attachment)
attachment->att_ext_connection = m_saveConnection
;
else
m_stable->getMutex()->leave();
} }
jrd_tra* transaction = m_tdbb->getTransaction(); jrd_tra* transaction = m_tdbb->getTransaction();
if (transaction) if (transaction)
transaction->tra_callback_count--; transaction->tra_callback_count--;
} }
} }
} // namespace EDS } // namespace EDS
 End of changes. 26 change blocks. 
24 lines changed or deleted 80 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)