Я написал класс Resource ниже для асинхронного менеджера ресурсов. Во время загрузки объект Resource создается с ресурсом по умолчанию (например, черной текстурой), поэтому основной поток, который будет использовать этот ресурс, не должен ждать, даже если он является пустым ресурсом. Как только загрузка закончится, поток загрузчика вызовет setResource () и установит базовый ресурс для вновь загруженного. Но есть и право собственности. Таким образом, когда загрузка будет завершена, вновь назначенный ресурс будет принадлежать классу Resource, чтобы его можно было освободить при уничтожении Resource или при вызове другого setResource, поскольку файл на диске изменился и нуждается в перезагрузке.
template <typename T>
class Resource {
protected:
// Underlying object
std::atomic<T*> resource;
// Do I own resource
bool isOwner;
// Id of resource for faster mapping
uint64_t id;
// Name
std::string name;
public:
Resource(T* res) : resource(res), isOwner(false), id(0), name("non") {}
Resource(std::unique_ptr<T>&& res)
: resource(res.release()), isOwner(true), id(0), name("non") {}
~Resource() {
if (isOwner) delete resource.load(std::memory_order_acquire);
}
Resource(Resource&&) = default;
Resource(const Resource&) = delete;
Resource& operator=(const Resource&) = delete;
T* getResource() {
return resource.load(std::memory_order_acquire);
}
void setResource(T* res, bool own = false) {
if (isOwner) {
delete resource.load(std::memory_order_acquire);
}
isOwner = own;
resource.store(res, std::memory_order_release);
}
void setResource(std::unique_ptr<T>&& res) {
if (isOwner) {
delete resource.load(std::memory_order_acquire);
}
isOwner = true;
resource.store(res.release(), std::memory_order_release);
}
void setId(uint64_t idd) { id = idd; }
};
Есть ли гонка данных на isOwner или в этом случае atomic.store () выступает в качестве ограждения? Или я должен изменить весь подход к владению и просто использовать std::atomic<std::shared_ptr<T>>
, который я не знаю, выполнимо ли?