Skip to content

Commit

Permalink
monitor: avoid dangling references to old monitors being undestroyed
Browse files Browse the repository at this point in the history
ref #7414
  • Loading branch information
vaxerski committed Aug 19, 2024
1 parent 272d904 commit c86db7b
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 33 deletions.
3 changes: 1 addition & 2 deletions src/Compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2935,7 +2935,7 @@ PHLWINDOW CCompositor::windowForCPointer(CWindow* pWindow) {

void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) {
// add it to real
auto PNEWMONITOR = g_pCompositor->m_vRealMonitors.emplace_back(makeShared<CMonitor>());
auto PNEWMONITOR = g_pCompositor->m_vRealMonitors.emplace_back(makeShared<CMonitor>(output));
if (std::string("HEADLESS-1") == output->name) {
g_pCompositor->m_pUnsafeOutput = PNEWMONITOR.get();
output->name = "FALLBACK"; // we are allowed to do this :)
Expand All @@ -2944,7 +2944,6 @@ void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) {
Debug::log(LOG, "New output with name {}", output->name);

PNEWMONITOR->szName = output->name;
PNEWMONITOR->output = output;
PNEWMONITOR->self = PNEWMONITOR;
const bool FALLBACK = g_pCompositor->m_pUnsafeOutput ? output == g_pCompositor->m_pUnsafeOutput->output : false;
PNEWMONITOR->ID = FALLBACK ? MONITOR_INVALID : g_pCompositor->getNextAvailableMonitorID(output->name);
Expand Down
1 change: 0 additions & 1 deletion src/events/Events.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ namespace Events {

// Monitor part 2 the sequel
DYNLISTENFUNC(monitorFrame);
DYNLISTENFUNC(monitorDestroy);
DYNLISTENFUNC(monitorStateRequest);
DYNLISTENFUNC(monitorDamage);
DYNLISTENFUNC(monitorNeedsFrame);
Expand Down
25 changes: 0 additions & 25 deletions src/events/Monitors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,31 +85,6 @@ void Events::listener_monitorFrame(void* owner, void* data) {
}
}

void Events::listener_monitorDestroy(void* owner, void* data) {
CMonitor* pMonitor = (CMonitor*)owner;

for (auto& m : g_pCompositor->m_vRealMonitors) {
if (m->output == pMonitor->output) {
pMonitor = m.get();
break;
}
}

if (!pMonitor)
return;

Debug::log(LOG, "Destroy called for monitor {}", pMonitor->szName);

pMonitor->onDisconnect(true);

pMonitor->output = nullptr;
pMonitor->m_bRenderingInitPassed = false;

Debug::log(LOG, "Removing monitor {} from realMonitors", pMonitor->szName);

std::erase_if(g_pCompositor->m_vRealMonitors, [&](SP<CMonitor>& el) { return el.get() == pMonitor; });
}

void Events::listener_monitorNeedsFrame(void* owner, void* data) {
const auto PMONITOR = (CMonitor*)owner;

Expand Down
21 changes: 17 additions & 4 deletions src/helpers/Monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ int ratHandler(void* data) {
return 1;
}

CMonitor::CMonitor() : state(this) {
CMonitor::CMonitor(SP<Aquamarine::IOutput> output_) : state(this), output(output_) {
;
}

Expand All @@ -40,16 +40,29 @@ void CMonitor::onConnect(bool noRule) {
outTimeline = CSyncTimeline::create(output->getBackend()->drmFD());
}

listeners.frame = output->events.frame.registerListener([this](std::any d) { Events::listener_monitorFrame(this, nullptr); });
listeners.destroy = output->events.destroy.registerListener([this](std::any d) { Events::listener_monitorDestroy(this, nullptr); });
listeners.commit = output->events.commit.registerListener([this](std::any d) { Events::listener_monitorCommit(this, nullptr); });
listeners.frame = output->events.frame.registerListener([this](std::any d) { Events::listener_monitorFrame(this, nullptr); });
listeners.commit = output->events.commit.registerListener([this](std::any d) { Events::listener_monitorCommit(this, nullptr); });
listeners.needsFrame =
output->events.needsFrame.registerListener([this](std::any d) { g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); });

listeners.presented = output->events.present.registerListener([this](std::any d) {
auto E = std::any_cast<Aquamarine::IOutput::SPresentEvent>(d);
PROTO::presentation->onPresented(this, E.when, E.refresh, E.seq, E.flags);
});

listeners.destroy = output->events.destroy.registerListener([this](std::any d) {
Debug::log(LOG, "Destroy called for monitor {}", szName);

onDisconnect(true);

output = nullptr;
m_bRenderingInitPassed = false;

Debug::log(LOG, "Removing monitor {} from realMonitors", szName);

std::erase_if(g_pCompositor->m_vRealMonitors, [&](SP<CMonitor>& el) { return el.get() == this; });
});

listeners.state = output->events.state.registerListener([this](std::any d) {
auto E = std::any_cast<Aquamarine::IOutput::SStateEvent>(d);

Expand Down
2 changes: 1 addition & 1 deletion src/helpers/Monitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class CMonitorState {

class CMonitor {
public:
CMonitor();
CMonitor(SP<Aquamarine::IOutput> output);
~CMonitor();

Vector2D vecPosition = Vector2D(-1, -1); // means unset
Expand Down

0 comments on commit c86db7b

Please sign in to comment.