| 8856 | namespace |
| 8857 | { |
| 8858 | bool shutdownAttachments(AttachmentsRefHolder* arg, ISC_STATUS signal) |
| 8859 | { |
| 8860 | AutoPtr<AttachmentsRefHolder> queue(arg); |
| 8861 | AttachmentsRefHolder& attachments = *arg; |
| 8862 | bool success = true; |
| 8863 | |
| 8864 | if (signal) |
| 8865 | { |
| 8866 | // Set terminate flag for all attachments |
| 8867 | |
| 8868 | for (AttachmentsRefHolder::Iterator iter(attachments); *iter; ++iter) |
| 8869 | { |
| 8870 | StableAttachmentPart* const sAtt = *iter; |
| 8871 | |
| 8872 | AttSyncLockGuard guard(*(sAtt->getSync(true)), FB_FUNCTION); |
| 8873 | Attachment* attachment = sAtt->getHandle(); |
| 8874 | |
| 8875 | if (attachment) |
| 8876 | attachment->signalShutdown(signal); |
| 8877 | } |
| 8878 | } |
| 8879 | |
| 8880 | // Purge all attachments |
| 8881 | |
| 8882 | for (AttachmentsRefHolder::Iterator iter(attachments); *iter; ++iter) |
| 8883 | { |
| 8884 | StableAttachmentPart* const sAtt = *iter; |
| 8885 | |
| 8886 | MutexLockGuard guardBlocking(*(sAtt->getBlockingMutex()), FB_FUNCTION); |
| 8887 | AttSyncLockGuard guard(*(sAtt->getSync()), FB_FUNCTION); |
| 8888 | Attachment* attachment = sAtt->getHandle(); |
| 8889 | |
| 8890 | if (attachment) |
| 8891 | { |
| 8892 | ThreadContextHolder tdbb; |
| 8893 | tdbb->setAttachment(attachment); |
| 8894 | tdbb->setDatabase(attachment->att_database); |
| 8895 | |
| 8896 | try |
| 8897 | { |
| 8898 | // purge attachment, rollback any open transactions |
| 8899 | attachment->att_use_count++; |
| 8900 | purge_attachment(tdbb, sAtt, engineShutdown ? PURGE_FORCE : PURGE_NOCHECK); |
| 8901 | } |
| 8902 | catch (const Exception& ex) |
| 8903 | { |
| 8904 | iscLogException("error while shutting down attachment", ex); |
| 8905 | success = false; |
| 8906 | } |
| 8907 | |
| 8908 | attachment = sAtt->getHandle(); |
| 8909 | |
| 8910 | if (attachment) |
| 8911 | attachment->att_use_count--; |
| 8912 | } |
| 8913 | } |
| 8914 | |
| 8915 | return success; |
no test coverage detected