Skip to content

Commit 27d2d73

Browse files
committed
fix a bug where marking a task a completed causes a panic when reading the output
1 parent caa595e commit 27d2d73

File tree

2 files changed

+29
-13
lines changed

2 files changed

+29
-13
lines changed

turbopack/crates/turbo-tasks-backend/src/backend/mod.rs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -455,11 +455,11 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
455455
Some(Ok(Err(listen_to_done_event(this, reader, done_event))))
456456
}
457457
Some(InProgressState::InProgress(box InProgressStateInner {
458-
marked_as_completed,
458+
completed,
459459
done_event,
460460
..
461461
})) => {
462-
if !*marked_as_completed {
462+
if !*completed {
463463
Some(Ok(Err(listen_to_done_event(this, reader, done_event))))
464464
} else {
465465
None
@@ -604,10 +604,22 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
604604
};
605605

606606
// Output doesn't exist. We need to schedule the task to compute it.
607-
let (item, listener) =
608-
CachedDataItem::new_scheduled_with_listener(self.get_task_desc_fn(task_id), note);
609-
task.add_new(item);
610-
turbo_tasks.schedule(task_id);
607+
let listener = if let Some(in_progress) = get_mut!(task, InProgress) {
608+
let InProgressState::InProgress(box InProgressStateInner {
609+
done_event, stale, ..
610+
}) = in_progress
611+
else {
612+
unreachable!();
613+
};
614+
*stale = true;
615+
done_event.listen_with_note(note)
616+
} else {
617+
let (item, listener) =
618+
CachedDataItem::new_scheduled_with_listener(self.get_task_desc_fn(task_id), note);
619+
task.add_new(item);
620+
turbo_tasks.schedule(task_id);
621+
listener
622+
};
611623

612624
Ok(Err(listener))
613625
}
@@ -1135,6 +1147,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
11351147
done_event,
11361148
session_dependent: false,
11371149
marked_as_completed: false,
1150+
completed: false,
11381151
new_children: Default::default(),
11391152
})),
11401153
});
@@ -1277,7 +1290,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
12771290
};
12781291
let &mut InProgressState::InProgress(box InProgressStateInner {
12791292
stale,
1280-
ref mut marked_as_completed,
1293+
ref mut completed,
12811294
ref done_event,
12821295
ref mut new_children,
12831296
..
@@ -1318,10 +1331,8 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
13181331
}
13191332

13201333
// mark the task as completed, so dependent tasks can continue working
1321-
if !*marked_as_completed {
1322-
*marked_as_completed = true;
1323-
done_event.notify(usize::MAX);
1324-
}
1334+
*completed = true;
1335+
done_event.notify(usize::MAX);
13251336

13261337
// take the children from the task to process them
13271338
let mut new_children = take(new_children);
@@ -1498,6 +1509,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
14981509
once_task: _,
14991510
stale,
15001511
session_dependent,
1512+
completed: _,
15011513
marked_as_completed: _,
15021514
new_children,
15031515
}) = in_progress
@@ -1882,12 +1894,10 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
18821894
let mut task = ctx.task(task, TaskDataCategory::Data);
18831895
if let Some(InProgressState::InProgress(box InProgressStateInner {
18841896
marked_as_completed,
1885-
done_event,
18861897
..
18871898
})) = get_mut!(task, InProgress)
18881899
{
18891900
*marked_as_completed = true;
1890-
done_event.notify(usize::MAX);
18911901
// TODO this should remove the dirty state (also check session_dependent)
18921902
// but this would break some assumptions for strongly consistent reads.
18931903
// Client tasks are not connected yet, so we wouldn't wait for them.

turbopack/crates/turbo-tasks-backend/src/data.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,13 @@ pub struct InProgressStateInner {
309309
#[allow(dead_code)]
310310
pub once_task: bool,
311311
pub session_dependent: bool,
312+
/// Early marking as completed. This is set before the output is available and will ignore full
313+
/// task completion of the task for strongly consistent reads.
312314
pub marked_as_completed: bool,
315+
/// Task execution has completed and the output is available.
316+
pub completed: bool,
317+
/// Event that is triggered when the task output is available (completed flag set).
318+
/// This is used to wait for completion when reading the task output before it's available.
313319
pub done_event: Event,
314320
/// Children that should be connected to the task and have their active_count decremented
315321
/// once the task completes.

0 commit comments

Comments
 (0)