Skip to content

Commit

Permalink
steamcompmgr, rendervulkan: prevent segfault that occured when closin…
Browse files Browse the repository at this point in the history
…g gamescope, due to a race condition between present thread @ present_wait_thread_func & compositor thread @ steamcompmgr_exit
  • Loading branch information
sharkautarch committed May 30, 2024
1 parent 35f5ba8 commit 61392a9
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/rendervulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2669,7 +2669,8 @@ bool acquire_next_image( void )
}


static std::atomic<uint64_t> g_currentPresentWaitId = {0u};
inline std::atomic<uint64_t> g_currentPresentWaitId = {0u};
inline std::atomic<bool> g_presentThreadShouldExit = {false};
static std::mutex present_wait_lock;

extern void mangoapp_output_update( uint64_t vblanktime );
Expand All @@ -2693,6 +2694,10 @@ static void present_wait_thread_func( void )
uint64_t vblanktime = get_time_in_nanos();
GetVBlankTimer().MarkVBlank( vblanktime, true );
mangoapp_output_update( vblanktime );
} else if ( g_presentThreadShouldExit.load(std::memory_order_acquire)) {
g_presentThreadShouldExit = 0;
g_presentThreadShouldExit.notify_all();
return;
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/rendervulkan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ enum EStreamColorspace : int
#include <vulkan/vulkan.h>
#include <drm_fourcc.h>

extern std::atomic<uint64_t> g_currentPresentWaitId;

extern std::atomic<bool> g_presentThreadShouldExit;

struct VulkanRenderer_t
{
struct wlr_renderer base;
Expand Down
8 changes: 8 additions & 0 deletions src/steamcompmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5840,6 +5840,14 @@ steamcompmgr_exit(void)
}
}

//request the present_wait thread to exit
//needed to avoid getting a segfault at exit due to race condition:
g_presentThreadShouldExit.store(true, std::memory_order_release);
g_currentPresentWaitId = 0; //present thread will check if it should exit if this is zero
g_currentPresentWaitId.notify_all();
g_presentThreadShouldExit.wait(true); //present thread will toggle this atomic when it sees the exit request
//this allows us to wait for present thread to close before deleting the backend

gamescope::IBackend::Set( nullptr );

wlserver_lock();
Expand Down

0 comments on commit 61392a9

Please sign in to comment.