| 450 | } |
| 451 | |
| 452 | int jrd_rel::blocking_ast_gcLock(void* ast_object) |
| 453 | { |
| 454 | /**** |
| 455 | SR - gc forbidden, awaiting moment to re-establish SW lock |
| 456 | SW - gc allowed, usual state |
| 457 | PW - gc allowed to the one connection only |
| 458 | ****/ |
| 459 | |
| 460 | jrd_rel* relation = static_cast<jrd_rel*>(ast_object); |
| 461 | |
| 462 | try |
| 463 | { |
| 464 | Lock* lock = relation->rel_gc_lock; |
| 465 | Database* dbb = lock->lck_dbb; |
| 466 | |
| 467 | AsyncContextHolder tdbb(dbb, FB_FUNCTION, lock); |
| 468 | |
| 469 | fb_assert(!(relation->rel_flags & REL_gc_lockneed)); |
| 470 | if (relation->rel_flags & REL_gc_lockneed) // work already done synchronously ? |
| 471 | return 0; |
| 472 | |
| 473 | relation->rel_flags |= REL_gc_blocking; |
| 474 | if (relation->rel_sweep_count) |
| 475 | return 0; |
| 476 | |
| 477 | if (relation->rel_flags & REL_gc_disabled) |
| 478 | { |
| 479 | // someone acquired EX lock |
| 480 | |
| 481 | fb_assert(lock->lck_id); |
| 482 | fb_assert(lock->lck_physical == LCK_SR); |
| 483 | |
| 484 | LCK_release(tdbb, lock); |
| 485 | relation->rel_flags &= ~(REL_gc_disabled | REL_gc_blocking); |
| 486 | relation->rel_flags |= REL_gc_lockneed; |
| 487 | } |
| 488 | else |
| 489 | { |
| 490 | // someone acquired PW lock |
| 491 | |
| 492 | fb_assert(lock->lck_id); |
| 493 | fb_assert(lock->lck_physical == LCK_SW); |
| 494 | |
| 495 | relation->rel_flags |= REL_gc_disabled; |
| 496 | relation->downgradeGCLock(tdbb); |
| 497 | } |
| 498 | } |
| 499 | catch (const Firebird::Exception&) |
| 500 | {} // no-op |
| 501 | |
| 502 | return 0; |
| 503 | } |
| 504 | |
| 505 | |
| 506 | /// jrd_rel::GCExclusive |
nothing calls this directly
no test coverage detected