mercredi 2 mars 2016

Trying to access an object that is being destroyed

I have an object which contains a thread which indirectly accesses this object like so:

#include <iostream>
#include <thread>
#include <atomic>

class A;

class Manager
{
public:
    Manager(void) = default;
    void StartA(void)
    {
        a = std::make_unique<A>(*this);
    }
    void StopA(void)
    {
        a = nullptr;
    }
    A& GetA(void)
    {
        return *a;
    }
private:
    std::unique_ptr<A> a;
};

class A
{
public:
    A(Manager& manager)
        : manager{manager},
        shouldwork{true},
        thread{[&]{ this->Run(); }}
    {
    }
    ~A(void)
    {
        shouldwork = false;
        thread.join();
    }
private:
    Manager& manager;
    std::atomic<bool> shouldwork;
    std::thread thread;
    void Run(void)
    {
        while (shouldwork)
        {
            // Here goes a lot of code which calls manager.GetA().
            auto& a = manager.GetA();
        }
    }
};

int main(int argc, char* argv[])
try
{
    Manager man;
    man.StartA();
    man.StopA();
}
catch (std::exception& e)
{
    std::cerr << "Exception caught: " << e.what() << '\n';
}
catch (...)
{
    std::cerr << "Unknown exception.\n";
}

The problem is that when one thread calls Manager::StopA and enters destructor of A, the thread inside A segfaults at Manager::GetA.

Aucun commentaire:

Enregistrer un commentaire