Skip to content

Commit

Permalink
Fix linking bug which causes a stack overflow on a thread when actors…
Browse files Browse the repository at this point in the history
… are bi-directionally linked (#168)

Related #167
  • Loading branch information
slawlor authored Sep 22, 2023
1 parent 000fbb6 commit bb33d4f
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 8 deletions.
2 changes: 1 addition & 1 deletion ractor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ractor"
version = "0.9.0"
version = "0.9.1"
authors = ["Sean Lawlor", "Evan Au", "Dillon George"]
description = "A actor framework for Rust"
documentation = "https://docs.rs/ractor"
Expand Down
16 changes: 11 additions & 5 deletions ractor/src/actor/supervision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,18 @@ impl SupervisionTree {
/// from the supervision tree since the supervisor is shutting down
/// and can't deal with superivison events anyways
pub fn terminate_all_children(&self) {
for kvp in self.children.iter() {
let child = &kvp.value().1;
child.terminate();
child.clear_supervisor();
}
let cells = self
.children
.iter()
.map(|r| r.1.clone())
.collect::<Vec<_>>();
// wipe local children to prevent double-link problems
self.children.clear();

for cell in cells {
cell.terminate();
cell.clear_supervisor();
}
}

/// Determine if the specified actor is a parent of this actor
Expand Down
42 changes: 42 additions & 0 deletions ractor/src/actor/tests/supervisor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1104,3 +1104,45 @@ async fn test_supervisor_captures_dead_childs_state() {

// TODO: Still to be tested
// 1. terminate_children_after()

#[crate::concurrency::test]
#[tracing_test::traced_test]
async fn test_supervisor_double_link() {
struct Who;

#[crate::async_trait]
impl Actor for Who {
type Msg = ();
type State = ();
type Arguments = ();

async fn pre_start(
&self,
_: ActorRef<Self::Msg>,
_: Self::Arguments,
) -> Result<Self::State, ActorProcessingErr> {
Ok(())
}
}

let (a, ah) = Actor::spawn(None, Who, ())
.await
.expect("Failed to start a");
let (b, bh) = Actor::spawn(None, Who, ())
.await
.expect("Failed to start b");

a.link(b.get_cell());
b.link(a.get_cell());

crate::concurrency::sleep(Duration::from_millis(100)).await;

// stopping b should kill a since they're linked (or vice-versa)
b.stop(None);

// This panics if double-link, unlinking fails
crate::concurrency::sleep(Duration::from_millis(100)).await;

ah.await.unwrap();
bh.await.unwrap();
}
2 changes: 1 addition & 1 deletion ractor_cluster/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ractor_cluster"
version = "0.9.0"
version = "0.9.1"
authors = ["Sean Lawlor", "Evan Au", "Dillon George"]
description = "Distributed cluster environment of Ractor actors"
documentation = "https://docs.rs/ractor"
Expand Down
2 changes: 1 addition & 1 deletion ractor_cluster_derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ractor_cluster_derive"
version = "0.9.0"
version = "0.9.1"
authors = ["Sean Lawlor <[email protected]>"]
description = "Derives for ractor_cluster"
license = "MIT"
Expand Down

0 comments on commit bb33d4f

Please sign in to comment.