| 394 | } |
| 395 | |
| 396 | bool jrd_rel::acquireGCLock(thread_db* tdbb, int wait) |
| 397 | { |
| 398 | fb_assert(rel_flags & REL_gc_lockneed); |
| 399 | if (!(rel_flags & REL_gc_lockneed)) |
| 400 | { |
| 401 | fb_assert(rel_gc_lock->lck_id); |
| 402 | fb_assert(rel_gc_lock->lck_physical == (rel_flags & REL_gc_disabled ? LCK_SR : LCK_SW)); |
| 403 | return true; |
| 404 | } |
| 405 | |
| 406 | if (!rel_gc_lock) |
| 407 | rel_gc_lock = createLock(tdbb, NULL, this, LCK_rel_gc, false); |
| 408 | |
| 409 | fb_assert(!rel_gc_lock->lck_id); |
| 410 | fb_assert(!(rel_flags & REL_gc_blocking)); |
| 411 | |
| 412 | ThreadStatusGuard temp_status(tdbb); |
| 413 | |
| 414 | const USHORT level = (rel_flags & REL_gc_disabled) ? LCK_SR : LCK_SW; |
| 415 | bool ret = LCK_lock(tdbb, rel_gc_lock, level, wait); |
| 416 | if (!ret && (level == LCK_SW)) |
| 417 | { |
| 418 | rel_flags |= REL_gc_disabled; |
| 419 | ret = LCK_lock(tdbb, rel_gc_lock, LCK_SR, wait); |
| 420 | if (!ret) |
| 421 | rel_flags &= ~REL_gc_disabled; |
| 422 | } |
| 423 | |
| 424 | if (ret) |
| 425 | rel_flags &= ~REL_gc_lockneed; |
| 426 | |
| 427 | return ret; |
| 428 | } |
| 429 | |
| 430 | void jrd_rel::downgradeGCLock(thread_db* tdbb) |
| 431 | { |