Fix race condition in get_subpat_names()

A race condition in get_subpat_names() would have caused occasional
incorrect match results and memory leakage. Build the array in a
temporary variable and then atomically swap it in to the shared entry,
instead of overwriting the shared pointer and then progressively building
the array while the cache is in a broken state.

Replace the const_cast with a mutable, since the const_cast is what made
me realise something fishy was going on here. Also make the return value
const, since it points to shared memory, so callers should not modify it
without access to the std::atomic.

Split from D25515 per Bertrand's request.