Skip to content

Commit 08fae23

Browse files
committed
fix
1 parent 4ecc650 commit 08fae23

5 files changed

Lines changed: 830 additions & 110 deletions

File tree

examples/src/hello_world/greeter_client_v5_default.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,12 @@ async fn main() {
4646
const SIZES: [usize; 3] = [25, 64 << 10, 512 << 10];
4747
const ROUNDS: usize = 90;
4848

49-
// Nothing calls `release_previous_read`: a block goes back to its owner as soon as its
50-
// last byte is read. Whether that actually happens is what the numbers below show — a
51-
// segment that never took anything back would climb without bound instead of settling.
49+
// Nothing calls `release_previous_read`: a block goes back to its owner once its last byte
50+
// has been read and the reader has dropped what the read handed it, which is what the
51+
// `drop(body)` below is. A read of shared memory is a borrow of the peer's block rather
52+
// than a copy of it, so holding on to one holds the block. Whether the blocks come back at
53+
// all is what the numbers below show — a segment that never took anything back would climb
54+
// without bound instead of settling.
5255
for round in 1..=ROUNDS {
5356
let size = SIZES[round % SIZES.len()];
5457
let payload = vec![b'x'; size];

src/buffer/buf.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,28 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use std::{borrow::Borrow, cmp, fmt, hash, ops::Deref};
15+
use std::{borrow::Borrow, cmp, fmt, hash, ops::Deref, sync::Arc};
1616

1717
use bytes::Bytes;
1818

19-
use super::linked::PinLease;
19+
use super::{linked::SlicePinState, v5::V5PinState};
20+
21+
/// What holds the memory a [`ShmBuf`] borrows in place for as long as the borrow lives.
22+
///
23+
/// A lease is never read: it is a drop guard, and it is the last one dropped that hands the
24+
/// memory back. What that means differs by buffer — a V4 slice goes to the buffer manager it
25+
/// was allocated from, a V5 block goes onto the peer's release queue — so each buffer keeps
26+
/// its own state behind its own `Drop` and this only says which.
27+
#[allow(
28+
dead_code,
29+
reason = "holding the state is the whole of a lease's job; nothing ever reads it"
30+
)]
31+
pub(crate) enum PinLease {
32+
/// One slice of a V4 [`LinkedBuffer`](super::LinkedBuffer).
33+
Slice(Arc<SlicePinState>),
34+
/// One block of the peer's V5 segment.
35+
Block(Arc<V5PinState>),
36+
}
2037

2138
pub struct ShmBuf<'shm> {
2239
buf: &'shm [u8],
@@ -35,8 +52,10 @@ impl<'shm> ShmBuf<'shm> {
3552
}
3653

3754
fn into_bytes(self) -> Bytes {
38-
// The lease keeps both the mapping and the retired BufferSlice alive until the final
39-
// Bytes clone is dropped, so erasing the borrow lifetime here is sound.
55+
// The lease keeps the mapping alive, along with whatever inside it the bytes were read
56+
// out of — a retired BufferSlice, or a block of the peer's segment that is kept off
57+
// the release queue — until the final Bytes clone is dropped, so erasing the borrow
58+
// lifetime here is sound.
4059
let owner: ShmBuf<'static> = unsafe { std::mem::transmute(self) };
4160
Bytes::from_owner(owner)
4261
}

src/buffer/linked.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use tokio::io::ReadBuf;
2222

2323
use super::{
2424
BufferReader, BufferWriter,
25-
buf::{Buf, ShmBuf},
25+
buf::{Buf, PinLease, ShmBuf},
2626
};
2727
use crate::{
2828
buffer::{
@@ -66,7 +66,7 @@ impl PinRegistry {
6666
});
6767
state
6868
};
69-
PinLease { _state: state }
69+
PinLease::Slice(state)
7070
}
7171

7272
fn is_pinned(&self, slice: &BufferSlice) -> bool {
@@ -110,8 +110,13 @@ impl PinRegistry {
110110
}
111111
}
112112

113+
/// Keeps one V4 slice alive while a zero-copy read still borrows from it.
114+
///
115+
/// The slice is retired into here when the buffer is done with it, and reclaimed when the last
116+
/// [`PinLease`] over it is dropped — the counterpart on the V5 side is
117+
/// [`V5PinState`](super::v5::V5PinState).
113118
#[derive(Debug)]
114-
struct SlicePinState {
119+
pub(crate) struct SlicePinState {
115120
buffer_manager: Arc<BufferManager>,
116121
retired_slice: Mutex<Option<BufferSlice>>,
117122
}
@@ -152,10 +157,6 @@ fn reclaim_slice(buffer_manager: &BufferManager, slice: BufferSlice) {
152157
}
153158
}
154159

155-
pub(crate) struct PinLease {
156-
_state: Arc<SlicePinState>,
157-
}
158-
159160
#[derive(Debug)]
160161
pub struct LinkedBuffer {
161162
slice_list: SliceList,

0 commit comments

Comments
 (0)