Skip to content

Commit a7c19d7

Browse files
committed
fix deadlock
1 parent 78d6069 commit a7c19d7

File tree

3 files changed

+20
-13
lines changed

3 files changed

+20
-13
lines changed

pumpkin-world/src/level.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,11 @@ impl Level {
139139
///
140140
/// Note: The order of the output chunks will almost never be in the same order as the order of input chunks
141141
142-
pub fn fetch_chunks(&self, chunks: &[Vector2<i32>], channel: mpsc::Sender<Arc<ChunkData>>) {
142+
pub fn fetch_chunks(
143+
&self,
144+
chunks: &[Vector2<i32>],
145+
channel: mpsc::UnboundedSender<Arc<ChunkData>>,
146+
) {
143147
chunks.into_par_iter().for_each(|at| {
144148
let channel = channel.clone();
145149

@@ -160,6 +164,8 @@ impl Level {
160164
) => {
161165
// This chunk was not generated yet.
162166
let chunk = Arc::new(self.world_gen.generate_chunk(*at));
167+
let mut loaded_chunks = self.loaded_chunks.write();
168+
loaded_chunks.insert(*at, chunk.clone());
163169
Ok(chunk)
164170
}
165171
Err(err) => Err(err),
@@ -168,6 +174,8 @@ impl Level {
168174
None => {
169175
// There is no savefile yet -> generate the chunks
170176
let chunk = Arc::new(self.world_gen.generate_chunk(*at));
177+
let mut loaded_chunks = self.loaded_chunks.write();
178+
loaded_chunks.insert(*at, chunk.clone());
171179
Ok(chunk)
172180
}
173181
};
@@ -182,9 +190,9 @@ impl Level {
182190
});
183191
match maybe_chunk {
184192
Some(chunk) => {
185-
channel
186-
.blocking_send(chunk.clone())
187-
.expect("Failed sending ChunkData.");
193+
let _ = channel
194+
.send(chunk)
195+
.inspect_err(|err| log::error!("unable to send chunk to channel: {}", err));
188196
}
189197
None => {
190198
log::error!("Unable to send chunk {:?}!", at);

pumpkin/src/world/mod.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -255,12 +255,7 @@ impl World {
255255
level.mark_chunk_as_newly_watched(chunks);
256256
}
257257

258-
async fn spawn_world_chunks(
259-
&self,
260-
client: Arc<Client>,
261-
chunks: Vec<Vector2<i32>>,
262-
distance: i32,
263-
) {
258+
async fn spawn_world_chunks(&self, client: Arc<Client>, chunks: Vec<Vector2<i32>>) {
264259
if client.closed.load(std::sync::atomic::Ordering::Relaxed) {
265260
log::info!(
266261
"The connection with {} has closed before world chunks were spawned",
@@ -269,7 +264,11 @@ impl World {
269264
return;
270265
}
271266
let inst = std::time::Instant::now();
272-
let (sender, mut chunk_receiver) = mpsc::channel(distance as usize);
267+
268+
// level.fetch_chunks is synchronous
269+
// if level.fetch_chunks is spawned before the chunk sender is spawned,
270+
// can block as the channel capacity is reached
271+
let (sender, mut chunk_receiver) = mpsc::unbounded_channel();
273272

274273
let level = self.level.clone();
275274
let chunks = Arc::new(chunks);

pumpkin/src/world/player_chunker.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub async fn player_join(world: &World, player: Arc<Player>) {
5858
if !loading_chunks.is_empty() {
5959
world.mark_chunks_as_watched(&loading_chunks).await;
6060
world
61-
.spawn_world_chunks(player.client.clone(), loading_chunks, view_distance)
61+
.spawn_world_chunks(player.client.clone(), loading_chunks)
6262
.await;
6363
}
6464

@@ -122,7 +122,7 @@ pub async fn update_position(player: &Player) {
122122
entity.world.mark_chunks_as_watched(&loading_chunks).await;
123123
entity
124124
.world
125-
.spawn_world_chunks(player.client.clone(), loading_chunks, view_distance)
125+
.spawn_world_chunks(player.client.clone(), loading_chunks)
126126
.await;
127127
}
128128

0 commit comments

Comments
 (0)