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

Fixed CORE-1610 and its subtask CORE-1615.

This commit is contained in:
dimitr 2007-12-10 07:21:27 +00:00
parent 615e5f8f88
commit df6706bb4b
3 changed files with 66 additions and 55 deletions

View File

@ -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) ?

View File

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

View File

@ -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;
}