microsoft/bocpy v0.3.0
microsoft/bocpy
Captured source
source ↗v0.3.0
Repository: microsoft/bocpy
Tag: v0.3.0
Published: 2026-04-01T22:42:20Z
Prerelease: no
Release notes: Improvements
- Added
CownCapsule.disown()— abandons a cown's value without
serializing it and resets ownership to NO_OWNER. Used during worker cleanup to safely discard orphan cowns before the owning interpreter is destroyed, preventing dangling Python object references.
- Rewrote
receiveto use a two-phase spin-then-park strategy for
single-tag untimed receives. Phase 1 spins for BOC_SPIN_COUNT iterations; Phase 2 parks the thread on a per-queue condvar, eliminating busy-wait CPU burn. Timed receives and multi-tag receives use spin-then-backoff with exponential sleep (1 µs → 1 ms cap).
- Added platform-abstracted condvar primitives (
BOCParkMutex/
BOCParkCond) with implementations for Windows (SRWLOCK / CONDITION_VARIABLE), macOS (pthreads), and Linux (C11 threads).
- Each
BOCQueuenow carries awaiterscounter,park_mutex, and
park_cond. Producers signal parked receivers after enqueue; drain and set_tags broadcast to wake all parked threads.
- Replaced the fixed
thrd_sleepinsendwith asched_yield/
SwitchToThread, reducing send-side latency.
- Refactored the monolithic
_core_receiveintoreceive_single_tag
and receive_multi_tag, each with its own backoff/parking logic.
- Moved the
BOC_QUEUE_DISABLEDcheck earlier inget_queue_for_tag
so callers skip disabled queues instead of returning NULL after tag resolution.
- Added Windows-compatible
atomic_load_explicit/
atomic_fetch_add_explicit / atomic_fetch_sub_explicit macros using InterlockedExchangeAdd64.
- Declared
Py_mod_gil = Py_MOD_GIL_NOT_USEDin both_coreand
_math C extensions so that importing bocpy on a free-threaded Python build (3.13t+) does not re-enable the GIL.
- Replaced
PyDict_GetItem(borrowed reference) with
PyDict_GetItemRef (strong reference) in BOCRecycleQueue_recycle on Python 3.13+, improving forward-compatibility with free-threaded builds.
Bug Fixes
- Fixed a deadlock when the same cown is passed multiple times to
@when
(e.g. @when(c, c)). Duplicate requests for the same cown caused the MCS-queue-based two-phase locking to spin-wait on itself. Requests are now deduplicated by target cown in Behavior.__init__, with compensating resolve_one calls to maintain the behavior count invariant.
Tests
TestLostWakeStress: single-producer random delays, bursty producer,
and repeated single-message wake to detect lost-wake races.
TestMultiTagBackoff: multi-tag receive correctness — second-tag hit,
delayed arrival, per-tag FIFO ordering, timeout, and interleaved producers.
TestTimeoutAccuracy: lower-bound / upper-bound wall-clock checks and
zero-timeout immediacy.
- Added tests for duplicate cowns in
@when: same cown twice, thrice,
non-adjacent duplicates, duplicates within a group, and mutation aliasing semantics.
CI
- Added a
free-threadedCI job that tests against Python 3.13t and
3.14t on Linux, with explicit assertions that the GIL remains disabled after import.
Full Changelog: https://github.com/microsoft/bocpy/compare/v0.2.2...v0.3.0