In our program, we have a class FooLogger which logs specific events (strings). We use the FooLogger as a unique_ptr.
We have two threads which use this unique_ptr instance:
- Thread 1 logs the latest event to file in a while loop, first checking if the instance is not
nullptr - Thread 2 deallocates the
FooLoggerunique_ptrinstance when the program has reached a certain point (set tonullptr)
However, due to bad interleaving, it is possible that, while logging, the member variables of FooLogger are deallocated, resulting in an EXC_BAD_ACCESS error.
class FooLogger {
public:
FooLogger() {};
void Log(const std::string& event="") {
const float32_t time_step_s = timer_.Elapsed() - runtime_s_; // Can get EXC_BAD_ACCESS on timer_
runtime_s_ += time_step_s;
std::cout << time_step_s << runtime_s_ << event << std::endl;
}
private:
Timer timer_; // Timer is a custom class
float32_t runtime_s_ = 0.0;
};
int main() {
auto foo_logger = std::make_unique<FooLogger>();
std::thread foo_logger_thread([&] {
while(true) {
if (foo_logger)
foo_logger->Log("some event");
else
break;
}
});
SleepMs(50); // pseudo code
foo_logger = nullptr;
foo_logger_thread.join();
}
Is it possible, using some sort of thread synchronisation/locks etc. to ensure that the foo_logger instance is not deallocated while logging? If not, are there any good ways of handling this case?