Skip to content

Commit 74020a0

Browse files
authored
Merge pull request #31 from benoitc/feature/own-gil-context
Add OWN_GIL mode for true parallel Python execution
2 parents 96da149 + 3dcec6f commit 74020a0

25 files changed

+6264
-423
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ jobs:
2323
otp: "27.0"
2424
python: "3.13"
2525
# macOS
26-
- os: macos-14
26+
- os: macos-15
2727
otp: "27"
2828
python: "3.12"
29-
- os: macos-14
29+
- os: macos-15
3030
otp: "27"
3131
python: "3.13"
3232

@@ -69,7 +69,7 @@ jobs:
6969
7070
- name: Clean and compile
7171
run: |
72-
rebar3 clean
72+
rm -rf _build
7373
rebar3 compile
7474
7575
- name: Run tests
@@ -162,7 +162,7 @@ jobs:
162162
env:
163163
PYTHON_GIL: "0"
164164
run: |
165-
rebar3 clean
165+
rm -rf _build
166166
rebar3 compile
167167
168168
- name: Run tests
@@ -223,7 +223,7 @@ jobs:
223223
224224
- name: Clean and compile with ASan
225225
run: |
226-
rm -rf _build/cmake
226+
rm -rf _build
227227
mkdir -p _build/cmake
228228
cd _build/cmake
229229
cmake ../../c_src -DENABLE_ASAN=ON -DENABLE_UBSAN=ON

CHANGELOG.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,21 @@
22

33
## 2.2.0 (unreleased)
44

5+
### Fixed
6+
7+
- **OWN_GIL Safety Fixes** - Critical fixes for OWN_GIL subinterpreter mode
8+
- **Mutex leak in erlang module** - `async_futures_mutex` now always destroyed in
9+
`erlang_module_free()` regardless of `pipe_initialized` flag
10+
- **ABBA deadlock prevention** - Fixed lock ordering in `event_loop_down()` and
11+
`event_loop_destructor()` to acquire GIL before `namespaces_mutex`, matching the
12+
normal execution path and preventing deadlocks
13+
- **Dangling env pointer detection** - Added `interp_id` validation in
14+
`owngil_execute_*_with_env()` functions to detect and reject env resources
15+
created by a different interpreter, returning `{error, env_wrong_interpreter}`
16+
- **OWN_GIL callback documentation** - Documented that `erlang.call()` from OWN_GIL
17+
contexts uses `thread_worker_call()` rather than suspension/resume protocol;
18+
re-entrant calls to the same OWN_GIL context are not supported
19+
520
### Added
621

722
- **PyBuffer API** - Zero-copy WSGI input buffer for streaming HTTP bodies
@@ -52,6 +67,44 @@
5267
- `examples/bench_async_task.erl` - Erlang benchmark runner
5368
- `priv/test_async_task.py` - Python async task implementation
5469

70+
- **OWN_GIL Context Mode** - True parallel Python execution (Python 3.12+)
71+
- `py_context:start_link(Id, owngil)` - Create context with dedicated pthread and GIL
72+
- Each OWN_GIL context runs in its own thread with independent Python GIL
73+
- Enables true CPU parallelism across multiple Python contexts
74+
- Full feature support: channels, buffers, callbacks, PIDs, reactor, async tasks
75+
- `py_context:get_nif_ref/1` - Get NIF reference for low-level operations
76+
- New benchmark: `examples/bench_owngil.erl` comparing SHARED_GIL vs OWN_GIL
77+
- See [OWN_GIL Internals](docs/owngil_internals.md) for architecture details
78+
79+
- **Process-Local Environments for OWN_GIL** - Namespace isolation within shared contexts
80+
- `py_context:create_local_env/1` - Create isolated Python namespace for calling process
81+
- `py_nif:context_exec(Ref, Code, Env)` - Execute with process-local environment
82+
- `py_nif:context_eval(Ref, Expr, Locals, Env)` - Evaluate with process-local environment
83+
- `py_nif:context_call(Ref, Mod, Func, Args, Kwargs, Env)` - Call with process-local environment
84+
- Multiple Erlang processes can share an OWN_GIL context with isolated namespaces
85+
- Interpreter ID validation prevents cross-interpreter env usage
86+
87+
- **Per-Process Event Loop Namespaces** - Process isolation for event loop API
88+
- `py_nif:event_loop_exec/2` - Execute code in calling process's namespace
89+
- `py_nif:event_loop_eval/2` - Evaluate expression in calling process's namespace
90+
- Functions defined via exec callable via `create_task` with `__main__` module
91+
- Automatic cleanup when Erlang process exits
92+
93+
- **OWN_GIL Test Suites** - Feature verification
94+
- `py_context_owngil_SUITE` - Core OWN_GIL functionality (15 tests)
95+
- `py_owngil_features_SUITE` - Feature integration (44 tests covering channels,
96+
buffers, callbacks, PIDs, reactor, async tasks, asyncio, local envs)
97+
98+
### Changed
99+
100+
- **Event Loop Lock Ordering** - GIL acquired before `namespaces_mutex` in cleanup paths
101+
to prevent ABBA deadlocks with normal execution path
102+
103+
- **Asyncio Compatibility** - Fixed for Python 3.12+ with subinterpreters
104+
- Thread-local event loop context in `process_ready_tasks`
105+
- Eager task execution handling for Python 3.12+
106+
- Deprecation warning fix: use `erlang.run()` instead of `erlang.install()`
107+
55108
## 2.1.0 (2026-03-12)
56109

57110
### Added

0 commit comments

Comments
 (0)