Fix OOM issue
authorNormunds Rieksts <normunds.rieksts@arm.com>
Mon, 8 Nov 2021 17:53:12 +0000 (17:53 +0000)
committerMatteo Franchin <matteo.franchin@arm.com>
Thu, 11 Nov 2021 18:27:31 +0000 (18:27 +0000)
Fixes an issue where there was a chance that an exception would be
thrown when out of memory rather than returning an
appropriate VkResult code.

Additionally introduces a noncopyable utility class that can be used to
mark classes that should not have copy semantics

Change-Id: I1f84dc9bb1ea96db2a88a90d56adbee78b17c5e3
Signed-off-by: Normunds Rieksts <normunds.rieksts@arm.com>
util/custom_allocator.hpp
util/extension_list.hpp
util/file_descriptor.hpp
util/helpers.hpp
util/optional.hpp
util/timed_semaphore.hpp
util/unordered_map.hpp
util/unordered_set.hpp
wsi/wayland/swapchain.cpp
wsi/wayland/swapchain.hpp

index 829c798c285616bd29bb6ca05055f55deaa4adcc..070c82bef282af81a4d9547eb01db93ce9f9491c 100644 (file)
@@ -30,6 +30,8 @@
 
 #include <vulkan/vulkan.h>
 
+#include "helpers.hpp"
+
 #pragma once
 
 namespace util
@@ -280,7 +282,7 @@ util::unique_ptr<T> allocator::make_unique(Args &&...args) const noexcept
  *   vector.
  */
 template <typename T>
-class vector : public std::vector<T, custom_allocator<T>>
+class vector : public std::vector<T, custom_allocator<T>>, private noncopyable
 {
 public:
    using base = std::vector<T, custom_allocator<T>>;
index 366cfd2969e1f06ac50cab55415c2e524ba15666..a71888e5bea75381a382f365a189ce23580ddd14 100644 (file)
@@ -23,7 +23,8 @@
  */
 #pragma once
 
-#include "util/custom_allocator.hpp"
+#include "custom_allocator.hpp"
+#include "helpers.hpp"
 
 #include <vector>
 #include <algorithm>
@@ -38,14 +39,11 @@ namespace util
  *
  * @note This class does not store the extension versions.
  */
-class extension_list
+class extension_list : private noncopyable
 {
 public:
    extension_list(const util::allocator& allocator);
 
-   extension_list(const extension_list &rhs) = delete;
-   const extension_list &operator=(const extension_list &rhs) = delete;
-
    /**
     * @brief Get the allocator used to manage the memory of this object.
     */
index f762f99237bbf1667d74aaa5215debc6023303b4..664848f98c4ef7cb6a367034427889a1c0fd02ae 100644 (file)
 #include <unistd.h>
 #include <utility>
 
+#include "helpers.hpp"
+
 namespace util
 {
 
 /**
  * Manages a POSIX file descriptor.
  */
-class fd_owner
+class fd_owner : private noncopyable
 {
 public:
 
@@ -49,9 +51,6 @@ public:
    {
    }
 
-   fd_owner(const fd_owner &) = delete;
-   fd_owner &operator=(const fd_owner &) = delete;
-
    fd_owner(fd_owner &&rhs)
    {
       *this = std::move(rhs);
index 1dff400d373afdc7be21a0896371e45749595192..9b5932e1a6c510b8db7c5e2325ac0d630a39d90f 100644 (file)
@@ -44,4 +44,15 @@ const T *find_extension(VkStructureType sType, const void *pNext)
    }
    return reinterpret_cast<const T *>(entry);
 }
+
+class noncopyable
+{
+protected:
+   noncopyable() = default;
+   ~noncopyable() = default;
+
+private:
+   noncopyable(const noncopyable &) = delete;
+   noncopyable& operator=(const noncopyable &) = delete;
+};
 } // namespace util
index cf3fa52bf44645e691fd0f2ce62c0331c1a75785..469dbf17157110aacbf6d45647aa54bdf514c33e 100644 (file)
 
 #pragma once
 #include <cassert>
+#include "helpers.hpp"
 
 namespace util
 {
 template <typename T>
-class optional
+class optional : private noncopyable
 {
 public:
    using value_type = T;
 
-   optional(const optional &) = delete;
-   optional &operator=(const optional &) = delete;
-
    /**
     * @brief Construct an empty optional object.
     */
index 5988550fa56f338b094f2abb291a7402b7d91551..9f5b86739ab33ed1c51d8e367dbc4b6e410c6ce8 100644 (file)
@@ -45,6 +45,7 @@ extern "C"
 }
 
 #include <vulkan/vulkan.h>
+#include "helpers.hpp"
 
 namespace util
 {
@@ -61,13 +62,9 @@ namespace util
  *
  * This code does not use the C++ standard library to avoid exceptions.
  */
-class timed_semaphore
+class timed_semaphore : private noncopyable
 {
 public:
-   /* copying not implemented */
-   timed_semaphore &operator=(const timed_semaphore &) = delete;
-   timed_semaphore(const timed_semaphore &) = delete;
-
    ~timed_semaphore();
    timed_semaphore()
       : initialized(false){};
index 90c8c9aad4421ad8378b2eefa569da800d4c9d87..daf64c2e8bf7da2c9ca38369d3ecea3ffde7bf5d 100644 (file)
@@ -26,6 +26,7 @@
 #include <unordered_map>
 #include "custom_allocator.hpp"
 #include "optional.hpp"
+#include "helpers.hpp"
 
 namespace util
 {
@@ -39,7 +40,7 @@ template <typename Key, typename Value,
        typename Hash = std::hash<Key>,
        typename Comparator = std::equal_to<Key>,
        typename Allocator = util::custom_allocator<std::pair<const Key, Value>>>
-class unordered_map : public std::unordered_map<Key, Value, Hash, Comparator, Allocator>
+class unordered_map : public std::unordered_map<Key, Value, Hash, Comparator, Allocator>, private noncopyable
 {
    using base = std::unordered_map<Key, Value, Hash, Comparator, Allocator>;
    using size_type = typename base::size_type;
@@ -52,9 +53,6 @@ public:
    Value &operator[](const Key &key) = delete;
    Value &operator[](Key &&key) = delete;
 
-   unordered_map(const unordered_map &) = delete;
-   unordered_map &operator=(const unordered_map &) = delete;
-
    void insert() = delete;
    void emplace() = delete;
    void emplace_hint() = delete;
index 3fa603525587acabbb634608f0caac482bce868f..c07ffa5de6ff7542efee9f836cce429e0c3027e7 100644 (file)
@@ -26,6 +26,7 @@
 #include <unordered_set>
 #include "custom_allocator.hpp"
 #include "optional.hpp"
+#include "helpers.hpp"
 
 namespace util
 {
@@ -39,7 +40,7 @@ template <typename Key,
    typename Hash = std::hash<Key>,
    typename Comparator = std::equal_to<Key>,
    typename Allocator = util::custom_allocator<Key>>
-class unordered_set : public std::unordered_set<Key, Hash, Comparator, Allocator>
+class unordered_set : public std::unordered_set<Key, Hash, Comparator, Allocator>, private noncopyable
 {
    using value_type = Key;
    using base = std::unordered_set<Key, Hash, Comparator, Allocator>;
@@ -50,9 +51,6 @@ public:
    /**
     * Delete all member functions that can cause allocation failure by throwing std::bad_alloc.
     */
-   unordered_set(const unordered_set &) = delete;
-   unordered_set &operator=(const unordered_set &) = delete;
-
    void insert() = delete;
    void emplace() = delete;
    void emplace_hint() = delete;
index 8f33da330c410a7fd667442b1c8fa06ca6eeb277..5b56cc45ac44fafa9a803a0fa7a28ba28850d72d 100644 (file)
@@ -399,8 +399,8 @@ VkResult swapchain::create_aliased_image_handle(const VkImageCreateInfo *image_c
                                          get_allocation_callbacks(), image);
 }
 
-VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayland_image_data *image_data,
-                                      util::vector<wsialloc_format> importable_formats,
+VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayland_image_data &image_data,
+                                      util::vector<wsialloc_format> &importable_formats,
                                       wsialloc_format *allocated_format)
 {
    bool is_protected_memory = (image_create_info.flags & VK_IMAGE_CREATE_PROTECTED_BIT) != 0;
@@ -408,8 +408,8 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayl
    wsialloc_allocate_info alloc_info = { importable_formats.data(), static_cast<unsigned>(importable_formats.size()),
                                        image_create_info.extent.width, image_create_info.extent.height,
                                        allocation_flags };
-   const auto res = wsialloc_alloc(m_wsi_allocator, &alloc_info, allocated_format, image_data->stride,
-                                   image_data->buffer_fd, image_data->offset);
+   const auto res = wsialloc_alloc(m_wsi_allocator, &alloc_info, allocated_format, image_data.stride,
+                                   image_data.buffer_fd, image_data.offset);
    if (res != WSIALLOC_ERROR_NONE)
    {
       WSI_LOG_ERROR("Failed allocation of DMA Buffer. WSI error: %d", static_cast<int>(res));
@@ -443,7 +443,7 @@ VkResult swapchain::allocate_image(VkImageCreateInfo &image_create_info, wayland
       {
          return VK_ERROR_OUT_OF_HOST_MEMORY;
       }
-      VkResult result = allocate_wsialloc(m_image_create_info, image_data, importable_formats, &m_allocated_format);
+      VkResult result = allocate_wsialloc(m_image_create_info, *image_data, importable_formats, &m_allocated_format);
       if (result != VK_SUCCESS)
       {
          return result;
@@ -474,7 +474,7 @@ VkResult swapchain::allocate_image(VkImageCreateInfo &image_create_info, wayland
       }
 
       wsialloc_format allocated_format = { 0 };
-      result = allocate_wsialloc(image_create_info, image_data, importable_formats, &allocated_format);
+      result = allocate_wsialloc(image_create_info, *image_data, importable_formats, &allocated_format);
       if (result != VK_SUCCESS)
       {
          return result;
index d9dc3b15a937967e01c7f3ec9bc0738a5d4e80e8..c5fcfd23911e1170cc05a972b15850983e19358d 100644 (file)
@@ -163,8 +163,8 @@ private:
    struct wayland_image_data;
 
    VkResult allocate_image(VkImageCreateInfo &image_create_info, wayland_image_data *image_data, VkImage *image);
-   VkResult allocate_wsialloc(VkImageCreateInfo &image_create_info, wayland_image_data *image_data,
-                              util::vector<wsialloc_format> importable_formats, wsialloc_format *allocated_format);
+   VkResult allocate_wsialloc(VkImageCreateInfo &image_create_info, wayland_image_data &image_data,
+                              util::vector<wsialloc_format> &importable_formats, wsialloc_format *allocated_format);
    VkResult internal_bind_swapchain_image(VkDevice &device, wayland_image_data *swapchain_image,
                                           const VkImage &image);