mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 19:23:03 +01:00
Fixed CORE-1610 and its subtask CORE-1615.
This commit is contained in:
parent
615e5f8f88
commit
df6706bb4b
117
src/jrd/jrd.cpp
117
src/jrd/jrd.cpp
@ -4467,78 +4467,85 @@ bool JRD_reschedule(thread_db* tdbb, SLONG quantum, bool punt)
|
||||
THREAD_ENTER();
|
||||
}
|
||||
|
||||
/* If database has been shutdown then get out */
|
||||
// Test various flags and unwind/throw if required.
|
||||
// But do that only if we're not in the verb cleanup state,
|
||||
// which should never be interrupted.
|
||||
|
||||
Database* dbb = tdbb->tdbb_database;
|
||||
Attachment* attachment = tdbb->tdbb_attachment;
|
||||
if (attachment)
|
||||
if (!(tdbb->tdbb_flags & TDBB_verb_cleanup))
|
||||
{
|
||||
Firebird::PathName file_name = attachment->att_filename;
|
||||
/* If database has been shutdown then get out */
|
||||
|
||||
if (dbb->dbb_ast_flags & DBB_shutdown &&
|
||||
attachment->att_flags & ATT_shutdown)
|
||||
Database* dbb = tdbb->tdbb_database;
|
||||
Attachment* attachment = tdbb->tdbb_attachment;
|
||||
if (attachment)
|
||||
{
|
||||
if (punt) {
|
||||
CCH_unwind(tdbb, false);
|
||||
ERR_post(isc_shutdown, isc_arg_string,
|
||||
ERR_cstring(file_name), 0);
|
||||
}
|
||||
else {
|
||||
ISC_STATUS* status = tdbb->tdbb_status_vector;
|
||||
*status++ = isc_arg_gds;
|
||||
*status++ = isc_shutdown;
|
||||
*status++ = isc_arg_string;
|
||||
*status++ = (ISC_STATUS) ERR_cstring(file_name);
|
||||
*status++ = isc_arg_end;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (attachment->att_flags & ATT_shutdown &&
|
||||
!(tdbb->tdbb_flags & TDBB_shutdown_manager))
|
||||
{
|
||||
if (punt) {
|
||||
CCH_unwind(tdbb, false);
|
||||
ERR_post(isc_att_shutdown, 0);
|
||||
}
|
||||
else {
|
||||
ISC_STATUS* status = tdbb->tdbb_status_vector;
|
||||
*status++ = isc_arg_gds;
|
||||
*status++ = isc_att_shutdown;
|
||||
*status++ = isc_arg_end;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#ifdef CANCEL_OPERATION
|
||||
Firebird::PathName file_name = attachment->att_filename;
|
||||
|
||||
/* If a cancel has been raised, defer its acknowledgement
|
||||
when executing in the context of an internal request or
|
||||
the system transaction. */
|
||||
|
||||
if ((attachment->att_flags & ATT_cancel_raise) &&
|
||||
!(attachment->att_flags & ATT_cancel_disable))
|
||||
{
|
||||
const jrd_tra* transaction;
|
||||
jrd_req* request = tdbb->tdbb_request;
|
||||
if ((!request ||
|
||||
!(request->req_flags & (req_internal | req_sys_trigger))) &&
|
||||
(!(transaction = tdbb->tdbb_transaction) ||
|
||||
!(transaction->tra_flags & TRA_system)))
|
||||
if (dbb->dbb_ast_flags & DBB_shutdown &&
|
||||
attachment->att_flags & ATT_shutdown)
|
||||
{
|
||||
attachment->att_flags &= ~ATT_cancel_raise;
|
||||
if (punt) {
|
||||
CCH_unwind(tdbb, false);
|
||||
ERR_post(isc_cancelled, 0);
|
||||
ERR_post(isc_shutdown, isc_arg_string,
|
||||
ERR_cstring(file_name), 0);
|
||||
}
|
||||
else {
|
||||
ISC_STATUS* status = tdbb->tdbb_status_vector;
|
||||
*status++ = isc_arg_gds;
|
||||
*status++ = isc_cancelled;
|
||||
*status++ = isc_shutdown;
|
||||
*status++ = isc_arg_string;
|
||||
*status++ = (ISC_STATUS) ERR_cstring(file_name);
|
||||
*status++ = isc_arg_end;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (attachment->att_flags & ATT_shutdown &&
|
||||
!(tdbb->tdbb_flags & TDBB_shutdown_manager))
|
||||
{
|
||||
if (punt) {
|
||||
CCH_unwind(tdbb, false);
|
||||
ERR_post(isc_att_shutdown, 0);
|
||||
}
|
||||
else {
|
||||
ISC_STATUS* status = tdbb->tdbb_status_vector;
|
||||
*status++ = isc_arg_gds;
|
||||
*status++ = isc_att_shutdown;
|
||||
*status++ = isc_arg_end;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#ifdef CANCEL_OPERATION
|
||||
|
||||
/* If a cancel has been raised, defer its acknowledgement
|
||||
when executing in the context of an internal request or
|
||||
the system transaction. */
|
||||
|
||||
if ((attachment->att_flags & ATT_cancel_raise) &&
|
||||
!(attachment->att_flags & ATT_cancel_disable))
|
||||
{
|
||||
const jrd_tra* transaction;
|
||||
jrd_req* request = tdbb->tdbb_request;
|
||||
if ((!request ||
|
||||
!(request->req_flags & (req_internal | req_sys_trigger))) &&
|
||||
(!(transaction = tdbb->tdbb_transaction) ||
|
||||
!(transaction->tra_flags & TRA_system)))
|
||||
{
|
||||
attachment->att_flags &= ~ATT_cancel_raise;
|
||||
if (punt) {
|
||||
CCH_unwind(tdbb, false);
|
||||
ERR_post(isc_cancelled, 0);
|
||||
}
|
||||
else {
|
||||
ISC_STATUS* status = tdbb->tdbb_status_vector;
|
||||
*status++ = isc_arg_gds;
|
||||
*status++ = isc_cancelled;
|
||||
*status++ = isc_arg_end;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
tdbb->tdbb_quantum = (tdbb->tdbb_quantum <= 0) ?
|
||||
|
@ -1042,6 +1042,7 @@ const USHORT TDBB_set_backup_state = 8; /* Setting state for backup lock */
|
||||
const USHORT TDBB_backup_merge = 16; /* Merging changes from difference file */
|
||||
const USHORT TDBB_stack_trace_done = 32; /* PSQL stack trase is added into status-vector */
|
||||
const USHORT TDBB_shutdown_manager = 64; /* Server shutdown thread */
|
||||
const USHORT TDBB_verb_cleanup = 128; /* Verb cleanup is in progress */
|
||||
|
||||
|
||||
// duplicate context of firebird string to store in jrd_nod::nod_arg
|
||||
|
@ -2897,6 +2897,7 @@ void VIO_verb_cleanup(thread_db* tdbb, jrd_tra* transaction)
|
||||
VerbAction* action;
|
||||
jrd_tra* old_tran = tdbb->tdbb_transaction;
|
||||
try {
|
||||
tdbb->tdbb_flags |= TDBB_verb_cleanup;
|
||||
tdbb->tdbb_transaction = transaction;
|
||||
|
||||
while ( (action = sav_point->sav_verb_actions) ) {
|
||||
@ -3044,9 +3045,11 @@ void VIO_verb_cleanup(thread_db* tdbb, jrd_tra* transaction)
|
||||
delete action;
|
||||
}
|
||||
tdbb->tdbb_transaction = old_tran;
|
||||
tdbb->tdbb_flags &= ~TDBB_verb_cleanup;
|
||||
}
|
||||
catch (...) {
|
||||
tdbb->tdbb_transaction = old_tran;
|
||||
tdbb->tdbb_flags &= ~TDBB_verb_cleanup;
|
||||
throw;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user