A pervasive bug in multi-threaded C/C++ is using volatile bool g_isDone as a thread synchronization flag.
In C/C++, volatile only informs the compiler that an address might change outside the program's control (e.g. Memory-Mapped I/O hardware register). It tells the compiler not to optimize away reads/writes.
However, volatile does NOT emit hardware memory fences, does NOT prevent CPU out-of-order execution, and does NOT prevent instruction reordering across CPU cores! Always use std::atomic<bool> for inter-thread synchronization.