Skip to content

Commit 058fa5b

Browse files
committed
Move claiming of transferred memos into a separate function
1 parent 1806467 commit 058fa5b

File tree

1 file changed

+71
-54
lines changed

1 file changed

+71
-54
lines changed

src/function/sync.rs

Lines changed: 71 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use rustc_hash::FxHashMap;
2+
use std::collections::hash_map::OccupiedEntry;
23

34
use crate::key::DatabaseKeyIndex;
4-
use crate::runtime::{BlockResult, ClaimTransferredResult, Running, WaitResult};
5+
use crate::runtime::{BlockResult, ClaimTransferredResult, OtherThread, Running, WaitResult};
56
use crate::sync::thread::{self};
67
use crate::sync::Mutex;
78
use crate::tracing;
@@ -54,64 +55,23 @@ impl SyncTable {
5455
) -> ClaimResult<'me> {
5556
let mut write = self.syncs.lock();
5657
match write.entry(key_index) {
57-
std::collections::hash_map::Entry::Occupied(mut occupied_entry) => {
58+
std::collections::hash_map::Entry::Occupied(occupied_entry) => {
5859
let id = occupied_entry.get().id;
5960

6061
let id = match id {
6162
SyncOwnerId::Thread(id) => id,
6263
SyncOwnerId::Transferred => {
63-
let current_id = thread::current().id();
64-
let database_key_index = DatabaseKeyIndex::new(self.ingredient, key_index);
65-
66-
return match zalsa
67-
.runtime()
68-
.claim_transferred(database_key_index, allow_reentry)
69-
{
70-
ClaimTransferredResult::ClaimedBy(other_thread) => {
71-
occupied_entry.get_mut().anyone_waiting = true;
72-
73-
match other_thread.block(write) {
74-
BlockResult::Cycle => ClaimResult::Cycle { inner: false },
75-
BlockResult::Running(running) => ClaimResult::Running(running),
76-
}
77-
}
78-
ClaimTransferredResult::Reentrant => {
79-
let SyncState {
80-
id, claimed_twice, ..
81-
} = occupied_entry.into_mut();
82-
83-
if *claimed_twice {
84-
return ClaimResult::Cycle { inner: false };
85-
}
86-
87-
*id = SyncOwnerId::Thread(current_id);
88-
*claimed_twice = true;
89-
90-
ClaimResult::Claimed(ClaimGuard {
91-
key_index,
92-
zalsa,
93-
sync_table: self,
94-
mode: ReleaseMode::SelfOnly,
95-
})
96-
}
97-
ClaimTransferredResult::Cycle { inner: nested } => {
98-
ClaimResult::Cycle { inner: nested }
99-
}
100-
ClaimTransferredResult::Released => {
101-
occupied_entry.insert(SyncState {
102-
id: SyncOwnerId::Thread(thread::current().id()),
103-
anyone_waiting: false,
104-
is_transfer_target: false,
105-
claimed_twice: false,
106-
});
107-
ClaimResult::Claimed(ClaimGuard {
108-
key_index,
109-
zalsa,
110-
sync_table: self,
111-
mode: ReleaseMode::Default,
112-
})
113-
}
114-
};
64+
return match self.try_claim_transferred(
65+
zalsa,
66+
occupied_entry,
67+
allow_reentry,
68+
) {
69+
Ok(claimed) => claimed,
70+
Err(other_thread) => match other_thread.block(write) {
71+
BlockResult::Cycle => ClaimResult::Cycle { inner: false },
72+
BlockResult::Running(running) => ClaimResult::Running(running),
73+
},
74+
}
11575
}
11676
};
11777

@@ -153,6 +113,63 @@ impl SyncTable {
153113
}
154114
}
155115

116+
#[cold]
117+
fn try_claim_transferred<'me>(
118+
&'me self,
119+
zalsa: &'me Zalsa,
120+
mut entry: OccupiedEntry<Id, SyncState>,
121+
allow_reentry: bool,
122+
) -> Result<ClaimResult<'me>, OtherThread<'me>> {
123+
let key_index = *entry.key();
124+
let database_key_index = DatabaseKeyIndex::new(self.ingredient, key_index);
125+
126+
match zalsa
127+
.runtime()
128+
.claim_transferred(database_key_index, allow_reentry)
129+
{
130+
ClaimTransferredResult::ClaimedBy(other_thread) => {
131+
entry.get_mut().anyone_waiting = true;
132+
Err(other_thread)
133+
}
134+
ClaimTransferredResult::Reentrant => {
135+
let SyncState {
136+
id, claimed_twice, ..
137+
} = entry.into_mut();
138+
139+
if *claimed_twice {
140+
return Ok(ClaimResult::Cycle { inner: false });
141+
}
142+
143+
*id = SyncOwnerId::Thread(thread::current().id());
144+
*claimed_twice = true;
145+
146+
Ok(ClaimResult::Claimed(ClaimGuard {
147+
key_index,
148+
zalsa,
149+
sync_table: self,
150+
mode: ReleaseMode::SelfOnly,
151+
}))
152+
}
153+
ClaimTransferredResult::Cycle { inner: nested } => {
154+
Ok(ClaimResult::Cycle { inner: nested })
155+
}
156+
ClaimTransferredResult::Released => {
157+
entry.insert(SyncState {
158+
id: SyncOwnerId::Thread(thread::current().id()),
159+
anyone_waiting: false,
160+
is_transfer_target: false,
161+
claimed_twice: false,
162+
});
163+
Ok(ClaimResult::Claimed(ClaimGuard {
164+
key_index,
165+
zalsa,
166+
sync_table: self,
167+
mode: ReleaseMode::Default,
168+
}))
169+
}
170+
}
171+
}
172+
156173
fn make_transfer_target(&self, key_index: Id) -> Option<SyncOwnerId> {
157174
let mut syncs = self.syncs.lock();
158175
syncs.get_mut(&key_index).map(|state| {

0 commit comments

Comments
 (0)