@@ -26,6 +26,11 @@ CEventLoopManager::~CEventLoopManager() {
26
26
wl_event_source_remove (eventSourceData.eventSource );
27
27
}
28
28
29
+ for (auto const & w : m_vReadableWaiters) {
30
+ if (w->source != nullptr )
31
+ wl_event_source_remove (w->source );
32
+ }
33
+
29
34
if (m_sWayland.eventSource )
30
35
wl_event_source_remove (m_sWayland.eventSource );
31
36
if (m_sIdle.eventSource )
@@ -50,6 +55,33 @@ static int configWatcherWrite(int fd, uint32_t mask, void* data) {
50
55
return 0 ;
51
56
}
52
57
58
+ static int handleWaiterFD (int fd, uint32_t mask, void * data) {
59
+ if (mask & (WL_EVENT_HANGUP | WL_EVENT_ERROR)) {
60
+ Debug::log (ERR, " handleWaiterFD: readable waiter error" );
61
+ return 0 ;
62
+ }
63
+
64
+ if (mask & WL_EVENT_READABLE)
65
+ g_pEventLoopManager->onFdReadable ((CEventLoopManager::SReadableWaiter*)data);
66
+
67
+ return 0 ;
68
+ }
69
+
70
+ void CEventLoopManager::onFdReadable (SReadableWaiter* waiter) {
71
+ auto it = std::ranges::find_if (m_vReadableWaiters, [waiter](const UP<SReadableWaiter>& w) { return waiter == w.get () && w->fd == waiter->fd && w->source == waiter->source ; });
72
+
73
+ if (waiter->source ) {
74
+ wl_event_source_remove (waiter->source );
75
+ waiter->source = nullptr ;
76
+ }
77
+
78
+ if (waiter->fn )
79
+ waiter->fn ();
80
+
81
+ if (it != m_vReadableWaiters.end ())
82
+ m_vReadableWaiters.erase (it);
83
+ }
84
+
53
85
void CEventLoopManager::enterLoop () {
54
86
m_sWayland.eventSource = wl_event_loop_add_fd (m_sWayland.loop , m_sTimers.timerfd .get (), WL_EVENT_READABLE, timerWrite, nullptr );
55
87
@@ -143,6 +175,16 @@ void CEventLoopManager::doLater(const std::function<void()>& fn) {
143
175
&m_sIdle);
144
176
}
145
177
178
+ void CEventLoopManager::doOnReadable (CFileDescriptor fd, const std::function<void ()>& fn) {
179
+ if (!fd.isValid () || fd.isReadable ()) {
180
+ fn ();
181
+ return ;
182
+ }
183
+
184
+ auto & waiter = m_vReadableWaiters.emplace_back (makeUnique<SReadableWaiter>(nullptr , std::move (fd), fn));
185
+ waiter->source = wl_event_loop_add_fd (g_pEventLoopManager->m_sWayland .loop , waiter->fd .get (), WL_EVENT_READABLE, ::handleWaiterFD, waiter.get ());
186
+ }
187
+
146
188
void CEventLoopManager::syncPollFDs () {
147
189
auto aqPollFDs = g_pCompositor->m_pAqBackend ->getPollFDs ();
148
190
0 commit comments