AVAudioEngine Hangs/Locks Apps After Call to -connect:to:format:

Periodically when testing I am running into a situation where the app hangs and beach balls forever when using AVAudioEngine.

This seems to log out when this affect happens:

Now when this happens if I pause the debugger it's hanging at a call to:

  [engine connect:playerNode
                 to:engine.mainMixerNode
             format:buffer.format];

#0 0x000000019391ca9c in __psynch_mutexwait () #1 0x0000000104d49100 in _pthread_mutex_firstfit_lock_wait () #2 0x0000000104d49014 in _pthread_mutex_firstfit_lock_slow () #3 0x00000001938928ec in std::__1::recursive_mutex::lock () #4 0x00000001ef80e988 in CADeprecated::RealtimeMessenger::_PerformPendingMessages () #5 0x00000001ef818868 in AVAudioNodeTap::Uninitialize () #6 0x00000001ef7fdc68 in AUGraphNodeBase::Uninitialize () #7 0x00000001ef884f38 in AVAudioEngineGraph::PerformCommand () #8 0x00000001ef88e780 in AVAudioEngineGraph::_Connect () #9 0x00000001ef8b7e70 in AVAudioEngineImpl::Connect () #10 0x00000001ef8bc05c in -[AVAudioEngine connect:to:format:] ()

Current all my audio engine related calls are on the main queue (though I am curious about this https://forums.developer.apple.com/forums/thread/123540?answerId=816827022#816827022).

In any case, anyone know where I'm going wrong here?

I think the problem is that I called -connect:to:format: on the player node multiple times (already connected). So I'll just connect the player node to the main mixer node once and leave it. I think when I connect the player node multiple times it tears down a bunch of stuff as a side effect which looks like can cause a deadlock. Perhaps something related to the fact that I have a tap block?

Assuming this resolves the issue (need to test it more), is there any point where I should reconnect the player node to the main mixer node (as a part of error handling or a configuration change)?

So, I think the way to go is to make sure the engine isn't running before I connect the player node to the main mixer node. I will need to reconnect if the engine is paused/stopped before restarting the engine though, so I'm checking if (!isRunning) before connecting.

I think my mistake was accidentally connecting on the engine when it was already running (and was already connected).

AVAudioEngine Hangs/Locks Apps After Call to -connect:to:format:
 
 
Q