| 779 | |
| 780 | |
| 781 | AttachmentHolder::AttachmentHolder(thread_db* tdbb, StableAttachmentPart* sa, unsigned lockFlags, const char* from) |
| 782 | : sAtt(sa), |
| 783 | async(lockFlags & ATT_LOCK_ASYNC), |
| 784 | nolock(lockFlags & ATT_DONT_LOCK), |
| 785 | blocking(!(lockFlags & ATT_NON_BLOCKING)) |
| 786 | { |
| 787 | if (!sa) |
| 788 | Arg::Gds(isc_att_shutdown).raise(); |
| 789 | |
| 790 | if (blocking) |
| 791 | sAtt->getBlockingMutex()->enter(from); |
| 792 | |
| 793 | try |
| 794 | { |
| 795 | if (!nolock) |
| 796 | sAtt->getSync(async)->enter(from); |
| 797 | |
| 798 | Jrd::Attachment* attachment = sAtt->getHandle(); // Must be done after entering mutex |
| 799 | |
| 800 | try |
| 801 | { |
| 802 | if (!attachment || (engineShutdown && !(lockFlags & ATT_NO_SHUTDOWN_CHECK))) |
| 803 | { |
| 804 | // This shutdown check is an optimization, threads can still enter engine |
| 805 | // with the flag set cause shutdownMutex mutex is not locked here. |
| 806 | // That's not a danger cause check of att_use_count |
| 807 | // in shutdown code makes it anyway safe. |
| 808 | Arg::Gds err(isc_att_shutdown); |
| 809 | if (sAtt->getShutError()) |
| 810 | err << Arg::Gds(sAtt->getShutError()); |
| 811 | |
| 812 | err.raise(); |
| 813 | } |
| 814 | |
| 815 | tdbb->setAttachment(attachment); |
| 816 | tdbb->setDatabase(attachment->att_database); |
| 817 | |
| 818 | if (!async) |
| 819 | { |
| 820 | attachment->att_use_count++; |
| 821 | attachment->setupIdleTimer(true); |
| 822 | } |
| 823 | } |
| 824 | catch (const Firebird::Exception&) |
| 825 | { |
| 826 | if (!nolock) |
| 827 | sAtt->getSync(async)->leave(); |
| 828 | throw; |
| 829 | } |
| 830 | } |
| 831 | catch (const Firebird::Exception&) |
| 832 | { |
| 833 | if (blocking) |
| 834 | sAtt->getBlockingMutex()->leave(); |
| 835 | throw; |
| 836 | } |
| 837 | } |
| 838 |
nothing calls this directly
no test coverage detected