So the release pool is like a garbage collector, working on the message thread on a timer.
Are you asking if a lock is required for changing the modules array? I think it depends on how you are updating it and from which thread. But presumably you need a non-blocking solution (so the audio doesn’t stop) for changing it when the user makes changes?
As with most other problems in computer science, you can solve it with another layer of indirection. If you always load your array through a pointer, you can swap the array the pointer is pointing at. Doing it this way is completely lock-free and you don’t even have to use shared pointers.
However, it will only work in a SPSC model. As for the problem of deleting the memory, it can be proven that its safe to delete an old object IFF the new object has been used by the consumer.