| 653 | } |
| 654 | |
| 655 | void shutdown() |
| 656 | { |
| 657 | if (!sharedMemory) |
| 658 | return; |
| 659 | MutexLockGuard gLocal(initMutex, FB_FUNCTION); |
| 660 | if (!sharedMemory) |
| 661 | return; |
| 662 | |
| 663 | { // scope |
| 664 | Guard gShared(this); |
| 665 | |
| 666 | MappingHeader* sMem = sharedMemory->getHeader(); |
| 667 | fb_assert(sMem->process[process].id); |
| 668 | sMem->process[process].flags &= ~MappingHeader::FLAG_ACTIVE; |
| 669 | |
| 670 | (void) // Ignore errors in cleanup |
| 671 | sharedMemory->eventPost(&sMem->process[process].notifyEvent); |
| 672 | |
| 673 | cleanupSync.waitForCompletion(); |
| 674 | |
| 675 | // Ignore errors in cleanup |
| 676 | sharedMemory->eventFini(&sMem->process[process].notifyEvent); |
| 677 | sharedMemory->eventFini(&sMem->process[process].callbackEvent); |
| 678 | |
| 679 | while (sMem->processes) |
| 680 | { |
| 681 | if (sMem->process[sMem->processes - 1].flags & MappingHeader::FLAG_ACTIVE) |
| 682 | break; |
| 683 | sMem->processes--; |
| 684 | } |
| 685 | |
| 686 | if (!sMem->processes) |
| 687 | sharedMemory->removeMapFile(); |
| 688 | } |
| 689 | |
| 690 | sharedMemory = nullptr; |
| 691 | } |
| 692 | |
| 693 | void clearCache(const char* dbName, USHORT index) |
| 694 | { |
no test coverage detected