Open (or re-open after a staleness check) the index mmap. Readers use ACCESS_READ and never acquire the lock. Writers use ACCESS_WRITE and are expected to hold the lock.
(self, write=False)
| 712 | # ------------------------------------------------------------------ |
| 713 | |
| 714 | def open(self, write=False): |
| 715 | """ |
| 716 | Open (or re-open after a staleness check) the index mmap. |
| 717 | |
| 718 | Readers use ACCESS_READ and never acquire the lock. |
| 719 | Writers use ACCESS_WRITE and are expected to hold the lock. |
| 720 | """ |
| 721 | if self._mm: |
| 722 | # Check for staleness (Atomic Swap detection). |
| 723 | need_writable = write and not self._mm_writable |
| 724 | now = time.monotonic() |
| 725 | interval = self._staleness_check_interval |
| 726 | # Only throttle if the existing mapping already satisfies the |
| 727 | # caller. A read-only mmap can never service a write — we must |
| 728 | # always tear it down and reopen ACCESS_WRITE, regardless of how |
| 729 | # recently we last stat()ed. |
| 730 | if ( |
| 731 | not need_writable |
| 732 | and interval |
| 733 | and self._last_staleness_check is not None |
| 734 | and (now - self._last_staleness_check) < interval |
| 735 | ): |
| 736 | return True |
| 737 | self._last_staleness_check = now |
| 738 | current_id = self._get_cache_id() |
| 739 | if current_id != self._cache_id or need_writable: |
| 740 | # Preserve the persistent lock fd: ``put`` / ``delete`` / |
| 741 | # ``atomic_rebuild`` call ``open(write=True)`` *while holding* |
| 742 | # the cross-process flock on ``_lock_fd``. Closing that fd |
| 743 | # releases the flock as a side effect, letting another writer |
| 744 | # race the rest of this operation. Use the underscore helper |
| 745 | # so only mmaps and data fds are reset. |
| 746 | self._close_mmaps_and_fds() |
| 747 | else: |
| 748 | return True |
| 749 | |
| 750 | if write: |
| 751 | if not self._init_index_file(): |
| 752 | return False |
| 753 | if not self._init_heap_file(): |
| 754 | return False |
| 755 | mode = "r+b" |
| 756 | access = mmap.ACCESS_WRITE |
| 757 | else: |
| 758 | if not os.path.exists(self.path): |
| 759 | return False |
| 760 | mode = "rb" |
| 761 | access = mmap.ACCESS_READ |
| 762 | |
| 763 | try: |
| 764 | # Intentionally long-lived: closed in _close_mmaps_and_fds after mmap |
| 765 | idx_fp = salt.utils.files.fopen( # pylint: disable=resource-leakage |
| 766 | self.path, mode |
| 767 | ) |
| 768 | try: |
| 769 | fd = idx_fp.fileno() |
| 770 | self._cache_id = self._get_cache_id() |
| 771 | st = os.fstat(fd) |