Skip to content

Commit ba2b82f

Browse files
committed
Fix a threading bug
1 parent a7574e5 commit ba2b82f

5 files changed

Lines changed: 28 additions & 13 deletions

File tree

include/luna/lunaTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#ifdef __cplusplus
99
extern "C"
1010
{
11+
// ReSharper disable CppVariableCanBeMadeConstexpr
1112
// NOLINTBEGIN(*-macro-usage, *-enum-size, *-use-using)
1213
#else
1314
#include <stdbool.h>

src/Buffer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static bool sortBufferRegionsByOffsetAscending(const Buffer::BufferRegion &a, co
4343

4444
namespace luna
4545
{
46-
void BufferRegionIndex::destroyBuffer(Buffer *buffer)
46+
void BufferRegionIndex::destroyBuffer_(Buffer *buffer)
4747
{
4848
buffer->shouldBeDestroyed_ = true;
4949
vkDeviceWaitIdle(device);

src/Image.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -202,24 +202,22 @@ VkResult Image::write(const LunaImageWriteInfo &writeInfo) const
202202
CommandBuffer &commandBuffer = device.commandPools().graphics.commandBuffer(1);
203203
CHECK_RESULT_RETURN(commandBuffer.ensureIsRecording(luna::device, true));
204204

205-
const BufferRegionIndex *stagingBufferRegionIndex = stagingBuffer;
206-
if (stagingBufferRegionIndex == nullptr || stagingBufferRegionIndex->size() < writeInfo.bytes)
205+
if (stagingBuffer == nullptr || stagingBuffer->size() < writeInfo.bytes)
207206
{
208-
if (stagingBufferRegionIndex != nullptr)
207+
if (stagingBuffer != nullptr)
209208
{
210-
lunaDestroyBuffer(stagingBufferRegionIndex);
209+
lunaDestroyBuffer(stagingBuffer);
211210
}
212211
const LunaBufferCreationInfo bufferCreationInfo = {
213212
.size = writeInfo.bytes,
214213
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
215214
};
216215
LunaBuffer stagingBufferHandle = stagingBuffer;
217216
CHECK_RESULT_RETURN(lunaCreateBuffer(&bufferCreationInfo, &stagingBufferHandle));
218-
stagingBufferRegionIndex = stagingBuffer;
217+
stagingBuffer = static_cast<const BufferRegionIndex *>(stagingBufferHandle);
219218
}
220219

221-
stagingBufferRegionIndex->bufferRegion()->copyToBuffer(static_cast<const uint8_t *>(writeInfo.pixels),
222-
writeInfo.bytes);
220+
stagingBuffer->bufferRegion()->copyToBuffer(static_cast<const uint8_t *>(writeInfo.pixels), writeInfo.bytes);
223221
const uint32_t mipmapLevels = writeInfo.mipmapLevels == 0 ? 1 : writeInfo.mipmapLevels;
224222
const VkImageSubresourceRange subresourceRange = {
225223
.aspectMask = aspectMask_,
@@ -265,7 +263,7 @@ VkResult Image::write(const LunaImageWriteInfo &writeInfo) const
265263
.imageExtent = extent,
266264
};
267265
vkCmdCopyBufferToImage(commandBuffer,
268-
*stagingBufferRegionIndex->buffer(),
266+
*stagingBuffer->buffer(),
269267
image_,
270268
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
271269
1,

src/Instance.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,10 @@ VkResult lunaCreateInstance(const LunaInstanceCreationInfo *creationInfo)
322322
VkResult lunaDestroyInstance()
323323
{
324324
using namespace luna;
325+
if (Buffer::BufferRegion::BufferRegionIndex::cleanupThread_.joinable())
326+
{
327+
Buffer::BufferRegion::BufferRegionIndex::cleanupThread_.join();
328+
}
325329
CHECK_RESULT_RETURN(vkDeviceWaitIdle(device));
326330

327331

@@ -375,6 +379,10 @@ VkResult lunaDestroyInstance()
375379
descriptorSets.clear();
376380

377381
bufferRegionIndices.clear();
382+
if (Buffer::BufferRegion::BufferRegionIndex::cleanupThread_.joinable())
383+
{
384+
Buffer::BufferRegion::BufferRegionIndex::cleanupThread_.join();
385+
}
378386
buffers.clear();
379387
stagingBuffer = nullptr;
380388

src/headers/Buffer.hpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#include <cstddef>
99
#include <cstdint>
1010
#include <list>
11+
#include <luna/lunaInstance.h>
1112
#include <luna/lunaTypes.h>
13+
#include <thread>
1214
#include <vk_mem_alloc.h>
1315
#include <vulkan/vulkan_core.h>
1416

@@ -29,8 +31,12 @@ class Buffer
2931
public: // BufferRegion public types
3032
class BufferRegionIndex
3133
{
34+
friend VkResult(::lunaDestroyInstance());
35+
3236
private: // BufferRegionIndex private static
33-
static void destroyBuffer(Buffer *buffer);
37+
static void destroyBuffer_(Buffer *buffer);
38+
39+
static inline std::thread cleanupThread_{};
3440

3541
public: // BufferRegionIndex public members
3642
BufferRegionIndex() = delete;
@@ -114,7 +120,6 @@ using BufferRegionIndex = Buffer::BufferRegion::BufferRegionIndex;
114120

115121
#include <algorithm>
116122
#include <cassert>
117-
#include <thread>
118123

119124
namespace luna
120125
{
@@ -167,8 +172,11 @@ inline BufferRegionIndex::~BufferRegionIndex()
167172
}
168173
if (buffer_->regions_.empty())
169174
{
170-
std::thread cleanupThread(destroyBuffer, buffer_);
171-
cleanupThread.detach();
175+
if (cleanupThread_.joinable())
176+
{
177+
cleanupThread_.join();
178+
}
179+
cleanupThread_ = std::thread(destroyBuffer_, buffer_);
172180
}
173181
}
174182

0 commit comments

Comments
 (0)