Skip to content

Race condition in NotificationHandler callbacks #222

@iitalics

Description

@iitalics

I have a very simple JACK app that creates MIDI in/audio out ports, and I noticed getting interleaved logs which indicate that the NotificationHandler API is not properly thread safe.

struct AppNotificationHandler;

impl jack::NotificationHandler for AppNotificationHandler {
    fn thread_init(&self, client: &jack::Client) {
        info!(client_name = client.name(), "Thread init");
        let port_list = client.ports(None, None, jack::PortFlags::empty());
        for (i, port) in port_list.into_iter().enumerate() {
            debug!(i, ?port, "Port list");
        }
    }

    fn port_registration(
        &mut self,
        client: &jack::Client,
        port: jack::PortId,
        is_registered: bool,
    ) {
        debug!("port_registration");
        let port = client.port_by_id(port).unwrap();
        if !client.is_mine(&port) {
            return;
        }
        let port_name = port.name();
        let port_name = port_name.as_deref().unwrap_or("(port)");
        debug!(port=?port_name, is_registered);
    }
}

example logging output:

2025-08-21T01:49:03.248280Z DEBUG beeps: port_registration
2025-08-21T01:49:03.248292Z DEBUG beeps: port="beeps_app:input" is_registered=true
2025-08-21T01:49:03.248299Z DEBUG beeps: port_registration
2025-08-21T01:49:03.248300Z  INFO beeps: Thread init client_name="beeps_app"
2025-08-21T01:49:03.248301Z DEBUG beeps: port="beeps_app:output" is_registered=true
2025-08-21T01:49:03.248315Z DEBUG beeps: Port list i=0 port="Built-in Audio Analog Stereo:capture_FL"
2025-08-21T01:49:03.248320Z DEBUG beeps: Port list i=1 port="Built-in Audio Analog Stereo:capture_FR"

it should be impossible for port_registration() and thread_init() to become interleaved since the former takes &mut self which should give exclusive access to the referenced object

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions