You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit b75bcbb
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/free-threading.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -56,7 +56,7 @@ the ticket, plus what the free-threaded CI lane surfaced and sites added since:
56
56
|`backends/cachekitio/session.py` header cache |`threading.local`| Safe — per-thread state; its only cross-thread hazard was the session-identity publication above |
57
57
|`decorators/stats_context.py`|`contextvars.ContextVar`| Safe by construction |
58
58
|`decorators/wrapper.py` L1/SWR + L2/SWR single-flight (`_l1_swr_*`, `_l2_swr_*`) |`BoundedSemaphore` slots + in-flight `set` + PID-owner swap | Safe. The check-then-add on the in-flight set was already documented as benign (worst case one duplicate refresh, absorbed by last-write-wins / the backend lease); builtin `set`/`dict` single ops are atomic under free-threading's per-object locking. The fork-detection wholesale swap races are the same documented-benign shape |
59
-
| `l1_cache.py` `L1CacheManager._take_over_if_forked` + `_reset_cache_locks_after_fork` (LAB-4772) | Owner-PID fast path; on a PID change one thread takes over under a lock fetched by `dict.setdefault(pid, Lock())`. An `os.register_at_fork` hook repairs cache locks orphaned at fork before the child's first `get()`; fork mechanics and the uWSGI limit are in the `_take_over_if_forked` docstring | Safe. `setdefault` is atomic under per-object locking, so every thread in a new child gets the same fresh lock, which no parent thread can have held at fork; the rest block on it and re-check. The fast path gates on `_owner_pid` alone, so a weak-memory reader may still see the inherited manager lock once: the same benign fork-swap race as the SWR row, since that lock is unheld unless a parent thread held it at fork. The hook runs while the child is single-threaded, so its non-blocking probe (`timeout=0`) is exact, and it starts no thread. Once it has run, the take-over skips its own timed cache-lock probe, which could otherwise clear a cache under a live child thread |
59
+
| `l1_cache.py` `L1CacheManager._take_over_if_forked` + `_reset_cache_locks_after_fork` (LAB-4772) | Owner-PID fast path; on a PID change one thread takes over under a lock fetched by `dict.setdefault(pid, Lock())`. An `os.register_at_fork` hook repairs cache locks orphaned at fork before the child's first `get()`; fork mechanics and the uWSGI limit are in the `_take_over_if_forked` docstring | Safe. `setdefault` is atomic under per-object locking, so every thread in a new child gets the same fresh lock, which no parent thread can have held at fork; the rest block on it and re-check. The fast path gates on `_owner_pid` alone, so a weak-memory reader may still see the inherited manager lock once: the same benign fork-swap race as the SWR row, since that lock is unheld unless a parent thread held it at fork. The hook runs while the child is single-threaded, so its non-blocking probe (`timeout=0`) is exact, and it starts no thread. It repairs a cache before logging that cache's drop warning, and carries on past a log call that raises, so every cache is repaired. Once it has run, the take-over skips its own timed cache-lock probe, which could otherwise clear a cache under a live child thread |
60
60
|`decorators/wrapper.py``_cached_keys`| Builtin `set`, snapshot-copied before iteration in invalidation | Safe — single ops atomic; a copy racing an add can only miss a concurrently-written key, which invalidate-all semantics tolerate |
61
61
|`object_cache.py``ObjectCache`|`RLock` on every public method | Safe |
62
62
|`reliability/metrics_collection.py``get_async_metrics_collector`| Double-checked module-global singleton | Safe — single-assignment publication of a fully-constructed object; worst case a benign duplicate worker-restart check |
0 commit comments