| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
getLogger() returns existing loggers through a lock-free fast path that reads loggerDict without the lock (added in pythonGH-150825). The slow path inserted a freshly created logger into loggerDict before _fixupParents() assigned its parent, so a concurrent caller could fetch a logger whose parent was still None and see it detached from the hierarchy: getEffectiveLevel() returns NOTSET and records do not propagate until the creating thread finishes. Publish the logger only after its parent and children are wired. Neither _fixupParents() nor _fixupChildren() reads loggerDict[name], so the reorder is safe; the fast path is unchanged and confined to the locked creation path taken once per logger.
|
The new test is failing under Emscripten/WASI due to an inability to start a new thread - I'm not sure if this a transient problem or a platform restriction of those environments. It may be an idea to skip that test in those environments, at least for now. |
Sorry, something went wrong.
WASI and Emscripten have no working threading, so guard the regression test with requires_working_threading(), matching the other thread-using tests in test_logging.
|
@vsajip not sure if that backport landed but if it did we either need to backport this too, or back out the backports 🤔 |
Sorry, something went wrong.
|
No, as per discussion on d.p.o, the backport PRs were closed. Thanks for this! I took my eye off the ball a bit with the original PR. |
Sorry, something went wrong.
My bad for introducing the thread safety regression 😊 |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
The lock-free fast path added in GH-150825 reads loggerDict without the lock and returns any non-placeholder logger it finds. The slow path, however, inserted a freshly created logger into loggerDict before calling _fixupParents(), which assigns its parent. A caller hitting the fast path during that window receives a logger whose parent is still None: getEffectiveLevel() returns NOTSET and records do not propagate to ancestors until the creating thread finishes.
Both slow-path branches now publish the logger to loggerDict only after _fixupParents() (and _fixupChildren() for the placeholder case) have wired it. Neither helper reads loggerDict[name], so the move is safe, and the fast path is unchanged.
The added regression test forces the publish/wire interleaving deterministically and fails without this change.
The reorder is confined to the locked creation path, so the fast path is unaffected. Median of 5 runs against GH-150825 as merged (PGO build, same interpreter, swapping Lib/logging/__init__.py):
The difference is within the run-to-run noise floor (base 2.66-2.76 us, patched 2.64-2.65 us); pyperf compare_to reports it as not significant.
Benchmark (pyperf)Base is Lib/logging/__init__.py at GH-150825; patched swaps in this PR's version on the same interpreter. Run base vs patched with pyperf compare_to base.json patched.json.
Thanks to @methane for catching this in review of GH-150825.