Files
MapLibreParticleLab/include/mbgl/util/thread.hpp
Konstantin Käfer bd531b9e08 guarantee that Object stays around
Adds more documentation, and guarantees that the Object in the managed thread stays around until the Thread<> destructor is called. This might happen if .start() returns before .stop() is called, e.g. when a run loop in Object() terminates prematurely.
2015-04-10 15:52:02 +02:00

64 lines
1.6 KiB
C++

#ifndef MBGL_UTIL_THREAD
#define MBGL_UTIL_THREAD
#include <future>
#include <thread>
namespace mbgl {
namespace util {
// Manages a thread with Object.
// Upon creation of this object, it launches a thread, creates an object of type Object in that
// thread, and then calls .start(); on that object. When the Thread<> object is destructed, the
// Object's .stop() function is called, and the destructor waits for thread termination. The
// Thread<> constructor blocks until the thread and the Object are fully created, so after the
// object creation, it's safe to obtain the Object stored in this thread.
template <class Object>
class Thread {
public:
template <class... Args>
Thread(Args&&... args);
Thread(const Thread&) = delete;
Thread(Thread&&) = delete;
Thread& operator=(const Thread&) = delete;
Thread& operator=(Thread&&) = delete;
~Thread();
inline Object* operator->() const { return &object; }
inline operator Object*() const { return &object; }
private:
std::thread thread;
std::promise<void> joinable;
Object& object;
};
template <class Object>
template <class... Args>
Thread<Object>::Thread(Args&&... args)
: object([&]() -> Object& {
std::promise<Object&> promise;
thread = std::thread([&] {
Object context(::std::forward<Args>(args)...);
promise.set_value(context);
context.start();
joinable.get_future().get();
});
return promise.get_future().get();
}()) {
}
template <class Object>
Thread<Object>::~Thread() {
object.stop();
joinable.set_value();
thread.join();
}
}
}
#endif