Code Monkey home page Code Monkey logo

Comments (2)

wmedrano avatar wmedrano commented on May 27, 2024

Makes sense, to make safe, I want to ensure

  1. Low runtime impact for normal callbacks
  2. Allow for debugging of code that would panic
  3. Define behavior for when a rust panic would happen, deactivate client perhaps?

from rust-jack.

HadrienG2 avatar HadrienG2 commented on May 27, 2024

In my application, I maintain an AtomicBool that indicates if the audio thread is alive in the shared state between the audio threads and other application threads:

    // Check if the audio thread is alive
    fn is_alive(&self) -> bool {
        self.0.alive.load(Ordering::Relaxed)
    }

    // Mark the audio thread as dead
    fn mark_dead(&self) {
        self.0.alive.store(false, Ordering::Relaxed);
    }

Then I wrap all my JACK callbacks with the following...

    fn callback_guard<F>(&self, callback: F) -> Control
        where F: FnMut() -> Control + panic::UnwindSafe
    {
        if !self.is_alive() { return Control::Quit; }
        let result = panic::catch_unwind(callback);
        // FIXME: Store error somewhere so it can be processed, something based
        //        on AtomicPtr could do the trick and be async signal safe.
        let output = result.unwrap_or(Control::Quit);
        if output == Control::Quit { self.mark_dead(); }
        output
    }

...which ensures the following properties:

  • Unhandled panics and Control::Quit returns mark the audio thread dead and stop audio work
  • If the JACK callback supports it, JACK is notified by bubbling up a Control::Quit
  • If the JACK callback does not support it, then the output can be ignored
  • Application can poll is_alive() periodically to check audio thread health

This has the minor drawback of adding a Control return where there is none in the JACK API, which could be fixed by making another version of callback_guard for functions that don't return Control.

Another thing that could be improved is to differentiate Control::Quit returns from panics so that JACK callbacks continue to be processed normally during a graceful exit. This would require using an AtomicU8 instead of an AtomicBool in order to discriminate between a "working" state, a "panicked" state, and a "graceful exit" state when needed.

Maybe some variant of this design could be useful to you, and upstreamed as the official solution?

from rust-jack.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.