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
feat(bytesbuf)!: make MemoryShared thread-aware (#539)
## Summary
Makes the `bytesbuf` `MemoryShared` abstraction thread-aware, closing a
design gap where our thread-mobile (`Send`) memory providers were
expected to be thread-aware but the abstraction did not require or
express it. A provider now owns the decision of how and when to be
thread-aware, and any adapter around it simply forwards relocation
rather than imposing its own strategy.
## Changes
- `MemoryShared` now has `ThreadAware` as a supertrait, so the
abstraction requires and expresses thread-awareness. This makes it
possible to relocate erased/abstract memory providers correctly across
threads.
- `MemoryShared` gains an object-safe `clone_boxed` method,
blanket-provided for any `Clone` provider, so a type-erased provider can
be duplicated without knowing its concrete type. Every `MemoryShared`
provider is therefore required to be `Clone`.
- Redesigned `CallbackMemory` into a single `CallbackMemory<D>` provider
that pairs thread-aware `data: D` with a bare `reserve_fn: fn(&D, usize)
-> BytesBuf`. Because the reserve function is a bare function pointer it
cannot capture anything, so all reservation state must live in `data`,
which is `ThreadAware` and is relocated together with the provider.
`CallbackMemory::new(data, reserve_fn)` constructs one; `data` is
typically the wrapped inner memory provider, but can be any thread-aware
value (e.g. a tuple pairing the provider with configuration).
- Reworked `OpaqueMemory` to own a `Box<dyn MemoryShared>`, forwarding
both cloning (via `clone_boxed`) and `ThreadAware` relocation to the
wrapped provider. It imposes no thread-awareness strategy of its own,
leaving that decision entirely to the wrapped provider (e.g.
`GlobalPool`, which already manages per-core state internally), and each
clone is an independent provider.
- Gave the test providers `TransparentMemory` and `FixedBlockMemory`
no-op `ThreadAware` impls, since they hold no thread-affine mutable
state.
- Downstream: `http_extensions` drops its now-unnecessary `Unaware`
wrapper around `OpaqueMemory`; `bytesbuf_io` test providers migrate to
the new `CallbackMemory` constructor.
## Breaking changes
- `MemoryShared` gained `ThreadAware` as a supertrait and a new
`clone_boxed` method, so implementors must now also be `ThreadAware`
(and `Clone`, which the blanket impl requires).
- `CallbackMemory`'s constructor changed from taking a capturing
`Fn(usize) -> BytesBuf` closure to taking thread-aware `data` plus a
bare `fn(&D, usize) -> BytesBuf`. State that a closure would previously
have captured must now be passed as `data`.
## Validation
- `just format`, `just readme`, and `just spellcheck` all clean.
- Tests pass for `bytesbuf`, `bytesbuf_io`, and `http_extensions` (unit
+ doctests), including new tests covering
`CallbackMemory`/`OpaqueMemory` relocation forwarding, non-`Debug`
callback data, and the no-op `relocate` on the test providers.
- Clippy `-D warnings` clean; all remaining dependents build.
- Mutation testing of the changed logic (`cargo mutants --in-diff`)
leaves no surviving mutants.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@@ -471,7 +470,7 @@ See the `mem::testing` module for details (requires `test-util` Cargo feature).
471
470
This crate was developed as part of <ahref="../..">The Oxidizer Project</a>. Browse this crate's <ahref="https://github.com/microsoft/oxidizer/tree/main/crates/bytesbuf">source code</a>.
0 commit comments