mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 04:43:03 +01:00
Another bunch of changes for CORE-4004: Sometimes long-running operations cannot be interrupted by asynchronous shutdown / cancellation requests. The looper nodes should never ignore req_unwind and transform it to something else.
Review and testing would be appreciated, especially in regard to EXE_assignment.
This commit is contained in:
parent
bc1edae943
commit
3971e49b30
@ -378,7 +378,10 @@ AssignmentNode* AssignmentNode::pass2(thread_db* tdbb, CompilerScratch* csb)
|
||||
const StmtNode* AssignmentNode::execute(thread_db* tdbb, jrd_req* request, ExeState* /*exeState*/) const
|
||||
{
|
||||
if (request->req_operation == jrd_req::req_evaluate)
|
||||
{
|
||||
EXE_assignment(tdbb, this);
|
||||
request->req_operation = jrd_req::req_return;
|
||||
}
|
||||
|
||||
return parentStmt;
|
||||
}
|
||||
@ -884,9 +887,12 @@ void ContinueLeaveNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
|
||||
const StmtNode* ContinueLeaveNode::execute(thread_db* /*tdbb*/, jrd_req* request, ExeState* /*exeState*/) const
|
||||
{
|
||||
request->req_operation = jrd_req::req_unwind;
|
||||
request->req_label = labelNumber;
|
||||
request->req_flags |= (blrOp == blr_continue_loop ? req_continue_loop : req_leave);
|
||||
if (request->req_operation == jrd_req::req_evaluate)
|
||||
{
|
||||
request->req_operation = jrd_req::req_unwind;
|
||||
request->req_label = labelNumber;
|
||||
request->req_flags |= (blrOp == blr_continue_loop ? req_continue_loop : req_leave);
|
||||
}
|
||||
return parentStmt;
|
||||
}
|
||||
|
||||
@ -1841,25 +1847,28 @@ DeclareVariableNode* DeclareVariableNode::pass2(thread_db* /*tdbb*/, CompilerScr
|
||||
|
||||
const StmtNode* DeclareVariableNode::execute(thread_db* tdbb, jrd_req* request, ExeState* /*exeState*/) const
|
||||
{
|
||||
impure_value* variable = request->getImpure<impure_value>(impureOffset);
|
||||
variable->vlu_desc = varDesc;
|
||||
variable->vlu_desc.dsc_flags = 0;
|
||||
|
||||
if (variable->vlu_desc.dsc_dtype <= dtype_varying)
|
||||
if (request->req_operation == jrd_req::req_evaluate)
|
||||
{
|
||||
if (!variable->vlu_string)
|
||||
impure_value* variable = request->getImpure<impure_value>(impureOffset);
|
||||
variable->vlu_desc = varDesc;
|
||||
variable->vlu_desc.dsc_flags = 0;
|
||||
|
||||
if (variable->vlu_desc.dsc_dtype <= dtype_varying)
|
||||
{
|
||||
const USHORT len = variable->vlu_desc.dsc_length;
|
||||
variable->vlu_string = FB_NEW_RPT(*tdbb->getDefaultPool(), len) VaryingString();
|
||||
variable->vlu_string->str_length = len;
|
||||
if (!variable->vlu_string)
|
||||
{
|
||||
const USHORT len = variable->vlu_desc.dsc_length;
|
||||
variable->vlu_string = FB_NEW_RPT(*tdbb->getDefaultPool(), len) VaryingString();
|
||||
variable->vlu_string->str_length = len;
|
||||
}
|
||||
|
||||
variable->vlu_desc.dsc_address = variable->vlu_string->str_data;
|
||||
}
|
||||
else
|
||||
variable->vlu_desc.dsc_address = (UCHAR*) &variable->vlu_misc;
|
||||
|
||||
variable->vlu_desc.dsc_address = variable->vlu_string->str_data;
|
||||
request->req_operation = jrd_req::req_return;
|
||||
}
|
||||
else
|
||||
variable->vlu_desc.dsc_address = (UCHAR*) &variable->vlu_misc;
|
||||
|
||||
request->req_operation = jrd_req::req_return;
|
||||
|
||||
return parentStmt;
|
||||
}
|
||||
@ -2693,12 +2702,12 @@ ExecProcedureNode* ExecProcedureNode::pass2(thread_db* tdbb, CompilerScratch* cs
|
||||
|
||||
const StmtNode* ExecProcedureNode::execute(thread_db* tdbb, jrd_req* request, ExeState* /*exeState*/) const
|
||||
{
|
||||
if (request->req_operation == jrd_req::req_unwind)
|
||||
return parentStmt;
|
||||
if (request->req_operation == jrd_req::req_evaluate)
|
||||
{
|
||||
executeProcedure(tdbb, request);
|
||||
request->req_operation = jrd_req::req_return;
|
||||
}
|
||||
|
||||
executeProcedure(tdbb, request);
|
||||
|
||||
request->req_operation = jrd_req::req_return;
|
||||
return parentStmt;
|
||||
}
|
||||
|
||||
@ -5990,21 +5999,23 @@ PostEventNode* PostEventNode::pass2(thread_db* tdbb, CompilerScratch* csb)
|
||||
|
||||
const StmtNode* PostEventNode::execute(thread_db* tdbb, jrd_req* request, ExeState* /*exeState*/) const
|
||||
{
|
||||
jrd_tra* transaction = request->req_transaction;
|
||||
if (request->req_operation == jrd_req::req_evaluate)
|
||||
{
|
||||
jrd_tra* transaction = request->req_transaction;
|
||||
|
||||
DeferredWork* work = DFW_post_work(transaction, dfw_post_event,
|
||||
EVL_expr(tdbb, request, event), 0);
|
||||
DeferredWork* work = DFW_post_work(transaction, dfw_post_event,
|
||||
EVL_expr(tdbb, request, event), 0);
|
||||
|
||||
if (argument)
|
||||
DFW_post_work_arg(transaction, work, EVL_expr(tdbb, request, argument), 0);
|
||||
if (argument)
|
||||
DFW_post_work_arg(transaction, work, EVL_expr(tdbb, request, argument), 0);
|
||||
|
||||
// For an autocommit transaction, events can be posted without any updates.
|
||||
// For an autocommit transaction, events can be posted without any updates.
|
||||
|
||||
if (transaction->tra_flags & TRA_autocommit)
|
||||
transaction->tra_flags |= TRA_perform_autocommit;
|
||||
if (transaction->tra_flags & TRA_autocommit)
|
||||
transaction->tra_flags |= TRA_perform_autocommit;
|
||||
|
||||
if (request->req_operation == jrd_req::req_evaluate)
|
||||
request->req_operation = jrd_req::req_return;
|
||||
}
|
||||
|
||||
return parentStmt;
|
||||
}
|
||||
@ -6857,9 +6868,9 @@ const StmtNode* UserSavepointNode::execute(thread_db* tdbb, jrd_req* request, Ex
|
||||
BUGCHECK(232);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
request->req_operation = jrd_req::req_return;
|
||||
request->req_operation = jrd_req::req_return;
|
||||
}
|
||||
|
||||
return parentStmt;
|
||||
}
|
||||
@ -7231,18 +7242,19 @@ const StmtNode* StallNode::execute(thread_db* /*tdbb*/, jrd_req* request, ExeSta
|
||||
{
|
||||
switch (request->req_operation)
|
||||
{
|
||||
case jrd_req::req_sync:
|
||||
return parentStmt;
|
||||
case jrd_req::req_evaluate:
|
||||
case jrd_req::req_return:
|
||||
request->req_message = this;
|
||||
request->req_operation = jrd_req::req_return;
|
||||
request->req_flags |= req_stall;
|
||||
return this;
|
||||
|
||||
case jrd_req::req_proceed:
|
||||
request->req_operation = jrd_req::req_return;
|
||||
return parentStmt;
|
||||
|
||||
default:
|
||||
request->req_message = this;
|
||||
request->req_operation = jrd_req::req_return;
|
||||
request->req_flags |= req_stall;
|
||||
return this;
|
||||
return parentStmt;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7445,6 +7457,8 @@ const StmtNode* SavePointNode::execute(thread_db* tdbb, jrd_req* request, ExeSta
|
||||
// Start a save point.
|
||||
if (transaction != sysTransaction)
|
||||
VIO_start_save_point(tdbb, transaction);
|
||||
|
||||
request->req_operation = jrd_req::req_return;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -7461,11 +7475,16 @@ const StmtNode* SavePointNode::execute(thread_db* tdbb, jrd_req* request, ExeSta
|
||||
++transaction->tra_save_point->sav_verb_count;
|
||||
EXE_verb_cleanup(tdbb, transaction);
|
||||
}
|
||||
|
||||
if (request->req_operation == jrd_req::req_evaluate)
|
||||
request->req_operation = jrd_req::req_return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fb_assert(false);
|
||||
}
|
||||
|
||||
request->req_operation = jrd_req::req_return;
|
||||
return parentStmt;
|
||||
}
|
||||
|
||||
|
@ -216,8 +216,6 @@ void EXE_assignment(thread_db* tdbb, const AssignmentNode* node)
|
||||
|
||||
EXE_assignment(tdbb, node->asgnTo, from_desc, (request->req_flags & req_null),
|
||||
node->missing, node->missing2);
|
||||
|
||||
request->req_operation = jrd_req::req_return;
|
||||
}
|
||||
|
||||
// Perform an assignment.
|
||||
@ -231,8 +229,6 @@ void EXE_assignment(thread_db* tdbb, const ValueExprNode* source, const ValueExp
|
||||
dsc* from_desc = EVL_expr(tdbb, request, source);
|
||||
|
||||
EXE_assignment(tdbb, target, from_desc, (request->req_flags & req_null), NULL, NULL);
|
||||
|
||||
request->req_operation = jrd_req::req_return;
|
||||
}
|
||||
|
||||
// Perform an assignment.
|
||||
@ -1470,13 +1466,16 @@ const StmtNode* EXE_looper(thread_db* tdbb, jrd_req* request, const StmtNode* no
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (request->req_operation == jrd_req::req_evaluate && (--tdbb->tdbb_quantum < 0))
|
||||
JRD_reschedule(tdbb, 0, true);
|
||||
|
||||
if (request->req_operation == jrd_req::req_evaluate && node->hasLineColumn)
|
||||
if (request->req_operation == jrd_req::req_evaluate)
|
||||
{
|
||||
request->req_src_line = node->line;
|
||||
request->req_src_column = node->column;
|
||||
if (--tdbb->tdbb_quantum < 0)
|
||||
JRD_reschedule(tdbb, 0, true);
|
||||
|
||||
if (node->hasLineColumn)
|
||||
{
|
||||
request->req_src_line = node->line;
|
||||
request->req_src_column = node->column;
|
||||
}
|
||||
}
|
||||
|
||||
node = node->execute(tdbb, request, &exeState);
|
||||
|
@ -78,8 +78,6 @@ void ProcedureScan::open(thread_db* tdbb) const
|
||||
|
||||
if (m_sourceList)
|
||||
{
|
||||
enum jrd_req::req_s saved_state = request->req_operation;
|
||||
|
||||
const NestConst<ValueExprNode>* const sourceEnd = m_sourceList->items.end();
|
||||
const NestConst<ValueExprNode>* sourcePtr = m_sourceList->items.begin();
|
||||
const NestConst<ValueExprNode>* targetPtr = m_targetList->items.begin();
|
||||
@ -87,7 +85,6 @@ void ProcedureScan::open(thread_db* tdbb) const
|
||||
for (; sourcePtr != sourceEnd; ++sourcePtr, ++targetPtr)
|
||||
EXE_assignment(tdbb, *sourcePtr, *targetPtr);
|
||||
|
||||
request->req_operation = saved_state;
|
||||
iml = m_message->format->fmt_length;
|
||||
im = request->getImpure<UCHAR>(m_message->impureOffset);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user