Yep! So as predicted, GetRealOwner(WindowC) is WindowC, and the exit condition will never be satisfied, it's stuck!
This was the first time I've encountered this bug while using IDA, and I haven't been able to reproduce it since, so I suspect there is some subtle race condition to blame. Thankfully I was able to recover my idb with minimal lost work, but the question remains, is it the developer's responsibility to guarantee they don't create cycles, or Microsofts?
I've mailed a testcase to Microsoft, but I'm not sure what they'll say.