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

Reverted back to the single-pass algorithm used in v2.x. This should work around the issue with non-zero-timeout shutdown in SC.

This commit is contained in:
dimitr 2016-01-24 21:02:31 +00:00
parent eacbf41269
commit dd738c7f80

View File

@ -2685,8 +2685,10 @@ void LockManager::post_blockage(thread_db* tdbb, lrq* request, lbl* lock)
ASSERT_ACQUIRED; ASSERT_ACQUIRED;
CHECK(request->lrq_flags & LRQ_pending); CHECK(request->lrq_flags & LRQ_pending);
srq* lock_srq = SRQ_NEXT(lock->lbl_requests); Firebird::HalfStaticArray<SRQ_PTR, 16> blocking_owners;
while (lock_srq != &lock->lbl_requests)
SRQ lock_srq;
SRQ_LOOP(lock->lbl_requests, lock_srq)
{ {
lrq* const block = (lrq*) ((UCHAR*) lock_srq - offsetof(lrq, lrq_lbl_requests)); lrq* const block = (lrq*) ((UCHAR*) lock_srq - offsetof(lrq, lrq_lbl_requests));
own* const blocking_owner = (own*) SRQ_ABS_PTR(block->lrq_owner); own* const blocking_owner = (own*) SRQ_ABS_PTR(block->lrq_owner);
@ -2705,7 +2707,6 @@ void LockManager::post_blockage(thread_db* tdbb, lrq* request, lbl* lock)
!block->lrq_ast_routine || !block->lrq_ast_routine ||
(block->lrq_flags & LRQ_blocking_seen)) (block->lrq_flags & LRQ_blocking_seen))
{ {
lock_srq = SRQ_NEXT((*lock_srq));
continue; continue;
} }
@ -2719,27 +2720,33 @@ void LockManager::post_blockage(thread_db* tdbb, lrq* request, lbl* lock)
block->lrq_flags &= ~(LRQ_blocking_seen | LRQ_just_granted); block->lrq_flags &= ~(LRQ_blocking_seen | LRQ_just_granted);
} }
if (blocking_owner->own_flags & OWN_signaled) blocking_owners.add(block->lrq_owner);
{
lock_srq = SRQ_NEXT((*lock_srq)); if (block->lrq_state == LCK_EX)
continue; break;
} }
if (!signal_owner(tdbb, blocking_owner)) Firebird::HalfStaticArray<SRQ_PTR, 16> dead_processes;
for (SRQ_PTR* iter = blocking_owners.begin(); iter != blocking_owners.end(); ++iter)
{ {
prc* const process = (prc*) SRQ_ABS_PTR(blocking_owner->own_process); own* const blocking_owner = (own*) SRQ_ABS_PTR(*iter);
if (blocking_owner->own_count &&
!(blocking_owner->own_flags & OWN_signaled) &&
!signal_owner(tdbb, blocking_owner))
{
dead_processes.add(blocking_owner->own_process);
}
}
for (SRQ_PTR* iter = dead_processes.begin(); iter != dead_processes.end(); ++iter)
{
prc* const process = (prc*) SRQ_ABS_PTR(*iter);
if (process->prc_process_id)
purge_process(process); purge_process(process);
} }
// Restart from the beginning, as the list of requests chained to our lock
// could be changed in the meantime thus invalidating the iterator
owner = (own*) SRQ_ABS_PTR(owner_offset);
request = (lrq*) SRQ_ABS_PTR(request_offset);
lock = (lbl*) SRQ_ABS_PTR(lock_offset);
lock_srq = SRQ_NEXT(lock->lbl_requests);
}
} }