Skip to content

Commit

Permalink
steamcompmgr: attempt to fix the OTHER hang at exit
Browse files Browse the repository at this point in the history
  • Loading branch information
sharkautarch committed Dec 8, 2024
1 parent fff553f commit 0f5789f
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 3 deletions.
66 changes: 66 additions & 0 deletions src/Utils/Lock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#pragma once
#include "Utils/NonCopyable.h"
#include <memory>
#include <mutex>
#include <optional>
#include <cassert>

namespace gamescope
{
class CGlobalLockReference;
template <CGlobalLockReference const&>
class ReferencedLock;
class CGlobalLockReference : public NonCopyable
{
template <CGlobalLockReference const&>
friend class ReferencedLock;
public:
inline std::optional<std::unique_lock<std::mutex>> popLock() const;
CGlobalLockReference() = default;
CGlobalLockReference(CGlobalLockReference&&) = delete;
CGlobalLockReference(CGlobalLockReference const&&) = delete;
protected:
mutable std::optional<std::unique_lock<std::mutex>>* m_pLock;
mutable std::thread::id m_owningThreadID;
};

template <CGlobalLockReference const& StaticGlobLoc> //a reference to a static object is actually constexpr, which is nice, because putting the reference-to-static in the template param means this class takes up a bit less space
class ReferencedLock : public NonCopyable
{
using T = std::unique_lock<std::mutex>;
friend class CGlobalLockReference;
public:
explicit ReferencedLock(std::mutex& mut) : m_lock{std::in_place_t{}, std::unique_lock{mut}}
{
StaticGlobLoc.m_pLock = &(this->m_lock);
StaticGlobLoc.m_owningThreadID = std::this_thread::get_id();
}

//should still be able to move ReferencedLock when move elision can be done,
//but otherwise don't want to risk messing something up
ReferencedLock(ReferencedLock&&) = delete;
ReferencedLock(ReferencedLock const&&) = delete;

~ReferencedLock() {
if (m_lock.has_value()) {
StaticGlobLoc.m_pLock = nullptr;
}
}
inline std::optional<T> popLock() {
StaticGlobLoc.m_pLock = nullptr;
return std::move(m_lock);
}
protected:
mutable std::optional<T> m_lock;
};

std::optional<std::unique_lock<std::mutex>> CGlobalLockReference::popLock() const {
assert(m_owningThreadID == std::this_thread::get_id());

if (m_pLock) {
return std::move(*std::exchange(m_pLock,nullptr));
} else {
return std::nullopt;
}
}
}
11 changes: 8 additions & 3 deletions src/steamcompmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
#include "BufferMemo.h"
#include "Utils/Process.h"
#include "Utils/Algorithm.h"
#include "Utils/Lock.h"

#include "wlr_begin.hpp"
#include "wlr/types/wlr_pointer_constraints_v1.h"
Expand Down Expand Up @@ -5895,6 +5896,10 @@ error(Display *dpy, XErrorEvent *ev)
return 0;
}


static const gamescope::CGlobalLockReference s_xwlLockReference{};
using XwlLock = gamescope::ReferencedLock<s_xwlLockReference>;

[[noreturn]] static void
steamcompmgr_exit(std::optional<std::unique_lock<std::mutex>> lock = std::nullopt)
{
Expand Down Expand Up @@ -5962,7 +5967,7 @@ static int
handle_io_error(Display *dpy)
{
xwm_log.errorf("X11 I/O error");
steamcompmgr_exit();
steamcompmgr_exit( s_xwlLockReference.popLock() );
}

static bool
Expand Down Expand Up @@ -7512,7 +7517,7 @@ steamcompmgr_main(int argc, char **argv)

init_runtime_info();

std::unique_lock<std::mutex> xwayland_server_guard(g_SteamCompMgrXWaylandServerMutex);
XwlLock xwayland_server_guard(g_SteamCompMgrXWaylandServerMutex);

// Initialize any xwayland ctxs we have
{
Expand Down Expand Up @@ -8060,7 +8065,7 @@ steamcompmgr_main(int argc, char **argv)
vblank = false;
}

steamcompmgr_exit(std::optional<std::unique_lock<std::mutex>> {std::in_place_t{}, std::move(xwayland_server_guard)} );
steamcompmgr_exit( xwayland_server_guard.popLock() );
}

void steamcompmgr_send_frame_done_to_focus_window()
Expand Down

0 comments on commit 0f5789f

Please sign in to comment.