It turns out pa_mainloop_prepare was treating the msec timeout as usec in PulseAudio versions before 13.0, so the value actually passed to ppoll() was very short indeed. This is fixed in 13.0 and the result was to make it quite hard for the suspend/resume thread to acquire the loop mutex, which was almost always contended. Fix this by adding a couple of yields, and lowering the timeout drastically, since it obviously worked fine with a much lower effective value anyway.
bqaudioio ========= A small library wrapping various audio record / playback APIs in C++. C++ standard required: C++11 Copyright 2007-2017 Particular Programs Ltd. Under a permissive BSD/MIT-style licence: see the file COPYING for details.