egui icon indicating copy to clipboard operation
egui copied to clipboard

Instant crash. Something to do with my std::thread implementation

Open NotAF0e opened this issue 2 years ago • 5 comments

Describe the bug Application crashes instantly with no errors

To Reproduce Open application

Expected behaviour Application does not crash and runs fine

I'm on win11

This has something to do with my threading code as the app was just ok before I added threading to decouple my program's calculations and rendering.

NotAF0e avatar Jan 05 '23 19:01 NotAF0e

There doesn't appear to be enough information for this report to be actionable. A minimal reproduction is the best way for anyone to figure out how to fix it.

Since I'm left with no other options, I could take a wild guess that you might be running into issues with reentrancy on the internal lock within egui::Context. This issue is trivial to create and leads to deadlock. It isn't a "crash" in any sense other than the application freezes when this condition occurs.

parasyte avatar Jan 05 '23 22:01 parasyte

I'm not sure I would be able to create a minimal repo as just refactoring the code to work with a second thread had me contacting many people and failing twice.

NotAF0e avatar Jan 06 '23 09:01 NotAF0e

I will attempt to show what part may be causing issues later without minimal repo

NotAF0e avatar Jan 06 '23 10:01 NotAF0e

let sim_data_arc = Arc::clone(&app.sim_data);
    let checks_arc = Arc::clone(&app.checks);

    // Does simulation calculations
    thread::spawn(move || {
        let mut sim_data_lock = sim_data_arc.lock().unwrap();
        let mut checks_arc_lock = checks_arc.lock().unwrap();

        //loop {
        // Creates Adam and Eve
        if *&checks_arc_lock.data[0] == 0 {
            for _ in 0..1 { // Manually change amount of people at start here
                let john: Person = sim_data_lock.create_person(Sex::Male);
                let john2: Person = sim_data_lock.create_person(Sex::Female);
                sim_data_lock.people.push(john);
                sim_data_lock.people.push(john2);
            }

            checks_arc_lock.data[0] = 1;
        }

        if *&checks_arc_lock.data[1] != 0 {
            sim_data_lock.update_sim();
            sim_data_lock.update_details();
            let pop = &mut sim_data_lock;
            let pop_len = &mut pop.people.len();
            // Graph data pushing
            pop.graph_data.push([
                *&checks_arc_lock.start_months as f64 - *&checks_arc_lock.data[1] as f64,
                *pop_len as f64]);

            sim_data_lock.people.retain(|person| person.age != -1);
            checks_arc_lock.data[1] -= 1;
        }
        thread::sleep(Duration::from_secs(1));
        //}
    });

This is what i believe is causing problems

NotAF0e avatar Jan 06 '23 10:01 NotAF0e

I can't see all of the types in that code, but which part is relevant to egui?

I speculate the locks that this thread holds reference state that the GUI will draw. If that is the case, you need to drop the lock guards before you sleep the thread. With the structure of your code, the locks will be held over the sleep and that will starve the GUI thread while it attempts to acquire the lock.

But this is again just speculation, and I do not know exactly how this code relates to egui.

parasyte avatar Jan 06 '23 19:01 parasyte