| 3719 | |
| 3720 | |
| 3721 | void LockManager::wait_for_request(thread_db* tdbb, lrq* request, SSHORT lck_wait) |
| 3722 | { |
| 3723 | /************************************** |
| 3724 | * |
| 3725 | * w a i t _ f o r _ r e q u e s t |
| 3726 | * |
| 3727 | ************************************** |
| 3728 | * |
| 3729 | * Functional description |
| 3730 | * There is a request that needs satisfaction, but is waiting for |
| 3731 | * somebody else. Mark the request as pending and go to sleep until |
| 3732 | * the lock gets poked. When we wake up, see if somebody else has |
| 3733 | * cleared the pending flag. If not, go back to sleep. |
| 3734 | * Returns |
| 3735 | * FB_SUCCESS - we waited until the request was granted or rejected |
| 3736 | * FB_FAILURE - Insufficient resouces to wait (eg: no semaphores) |
| 3737 | * |
| 3738 | **************************************/ |
| 3739 | ASSERT_ACQUIRED; |
| 3740 | |
| 3741 | ++(m_sharedMemory->getHeader()->lhb_waits); |
| 3742 | const ULONG scan_interval = m_sharedMemory->getHeader()->lhb_scan_interval; |
| 3743 | |
| 3744 | // lrq_count will be off if we wait for a pending request |
| 3745 | CHECK(!(request->lrq_flags & LRQ_pending)); |
| 3746 | |
| 3747 | const SRQ_PTR request_offset = SRQ_REL_PTR(request); |
| 3748 | const SRQ_PTR owner_offset = request->lrq_owner; |
| 3749 | |
| 3750 | own* owner = (own*) SRQ_ABS_PTR(owner_offset); |
| 3751 | owner->own_flags &= ~(OWN_scanned | OWN_wakeup); |
| 3752 | owner->own_waits++; |
| 3753 | |
| 3754 | request->lrq_flags &= ~LRQ_rejected; |
| 3755 | request->lrq_flags |= LRQ_pending; |
| 3756 | insert_tail(&owner->own_pending, &request->lrq_own_pending); |
| 3757 | |
| 3758 | const SRQ_PTR lock_offset = request->lrq_lock; |
| 3759 | lbl* lock = (lbl*) SRQ_ABS_PTR(lock_offset); |
| 3760 | lock->lbl_pending_lrq_count++; |
| 3761 | |
| 3762 | if (!request->lrq_state) |
| 3763 | { |
| 3764 | // If this is a conversion of an existing lock in LCK_none state - |
| 3765 | // put the lock to the end of the list so it's not taking cuts in the lineup |
| 3766 | remove_que(&request->lrq_lbl_requests); |
| 3767 | insert_tail(&lock->lbl_requests, &request->lrq_lbl_requests); |
| 3768 | } |
| 3769 | |
| 3770 | if (lck_wait <= 0) |
| 3771 | request->lrq_flags |= LRQ_wait_timeout; |
| 3772 | |
| 3773 | SLONG value = m_sharedMemory->eventClear(&owner->own_wakeup); |
| 3774 | |
| 3775 | // Post blockage. If the blocking owner has disappeared, the blockage |
| 3776 | // may clear spontaneously. |
| 3777 | |
| 3778 | post_blockage(tdbb, request, lock); |
nothing calls this directly
no test coverage detected