Cross-platform exclusive file lock. The lock file fd is kept open persistently to avoid re-opening it on every call. If the persistent fd cannot be obtained, falls back to a per-call open (same behaviour as before).
(self)
| 309 | |
| 310 | @contextlib.contextmanager |
| 311 | def _lock(self): |
| 312 | """ |
| 313 | Cross-platform exclusive file lock. |
| 314 | |
| 315 | The lock file fd is kept open persistently to avoid re-opening it on |
| 316 | every call. If the persistent fd cannot be obtained, falls back to a |
| 317 | per-call open (same behaviour as before). |
| 318 | """ |
| 319 | lock_f = self._lock_fd_open() |
| 320 | if lock_f is None: |
| 321 | # Fallback: open per-call |
| 322 | os.makedirs(os.path.dirname(self._lock_path), exist_ok=True) |
| 323 | with salt.utils.files.fopen(self._lock_path, "w") as _f: |
| 324 | yield |
| 325 | return |
| 326 | |
| 327 | fd = lock_f.fileno() |
| 328 | if salt.utils.platform.is_windows(): |
| 329 | if msvcrt: |
| 330 | try: |
| 331 | msvcrt.locking(fd, msvcrt.LK_LOCK, 1) |
| 332 | yield |
| 333 | finally: |
| 334 | try: |
| 335 | msvcrt.locking(fd, msvcrt.LK_UNLCK, 1) |
| 336 | except OSError: |
| 337 | pass |
| 338 | else: |
| 339 | yield |
| 340 | else: |
| 341 | if fcntl: |
| 342 | fcntl.flock(fd, fcntl.LOCK_EX) |
| 343 | try: |
| 344 | yield |
| 345 | finally: |
| 346 | fcntl.flock(fd, fcntl.LOCK_UN) |
| 347 | else: |
| 348 | yield |
| 349 | |
| 350 | def _flush_index_mm(self): |
| 351 | """Flush index mmap and sync the backing file (ordering vs heap/roster).""" |