Skip to content

stdlib: fix data race compiling a shared ModuleImpl - #268

Open
drew-512 wants to merge 1 commit into
go-python:mainfrom
drew-512:stdlib-module-code-race
Open

drew-512 wants to merge 1 commit into
go-python:mainfrom
drew-512:stdlib-module-code-race

Conversation

@drew-512

@drew-512 drew-512 commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

ModuleInit compiles ModuleImpl.CodeSrc (or unmarshals CodeBuf) into ModuleImpl.Code on first use, without any locking. A registered ModuleImpl is shared by every py.Context, so when several contexts import such a module for the first time at once they race on impl.Code and on the py.Code still being built. go test -race with 8 contexts importing one CodeSrc module reports 25–26 races per run on main.

The code is now prepared in a small moduleCode helper under a package-level mutex. It is still compiled once and then shared, since a built py.Code is read-only (the multi-context example already relies on that). The mutex is only held while checking or building impl.Code.

Tests:

  • new stdlib/moduleinit_test.go: 8 contexts import a registered CodeSrc module at the same time and call into it. Fails under -race on main, 0 races in 60 runs on this branch.
  • go test -race ./... passes on Go 1.18, 1.19 and 1.27.

Fixes #266.

ModuleInit compiled ModuleImpl.CodeSrc (or unmarshalled CodeBuf) into
ModuleImpl.Code without synchronization. A registered ModuleImpl is
shared by every Context, so contexts importing such a module for the
first time at the same time raced on impl.Code and on the py.Code
being built.

Prepare the code under a package-level mutex. It is still compiled
once and then shared, since a built py.Code is read-only.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

stdlib: data race importing a CodeSrc module from several contexts

1 participant