From dff5051905e4b83f7f1c94453105bb51be743763 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 18 Jan 2019 05:26:45 +0100 Subject: [PATCH] Support polling with select() by using a zero timeout. Use this in WindowServer to avoid getting blocked in select() when there are pending injected events. --- Kernel/Process.cpp | 6 +++--- Kernel/ProcessGUI.cpp | 11 +++++++++-- WindowServer/WSEventLoop.cpp | 6 +++++- WindowServer/WSWindowManager.cpp | 8 +++++++- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 0a24ebebfa..ca81c7dfd8 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1939,7 +1939,7 @@ int Process::sys$select(const Syscall::SC_select_params* params) ASSERT(!exceptfds); // FIXME: Implement timeout support. - ASSERT(!timeout); + ASSERT(!timeout || (!timeout->tv_sec && !timeout->tv_usec)); if (nfds < 0) return -EINVAL; @@ -1963,10 +1963,10 @@ int Process::sys$select(const Syscall::SC_select_params* params) transfer_fds(readfds, m_select_read_fds); #ifdef DEBUG_IO - dbgprintf("%s<%u> selecting on (read:%u, write:%u)\n", name().characters(), pid(), m_select_read_fds.size(), m_select_write_fds.size()); + dbgprintf("%s<%u> selecting on (read:%u, write:%u), wakeup_req:%u, timeout=%p\n", name().characters(), pid(), m_select_read_fds.size(), m_select_write_fds.size(), m_wakeup_requested, timeout); #endif - if (!m_wakeup_requested) { + if (!m_wakeup_requested && (!timeout || (timeout->tv_sec || timeout->tv_usec))) { block(BlockedSelect); Scheduler::yield(); } diff --git a/Kernel/ProcessGUI.cpp b/Kernel/ProcessGUI.cpp index 417dac360e..d1e53d2baa 100644 --- a/Kernel/ProcessGUI.cpp +++ b/Kernel/ProcessGUI.cpp @@ -64,14 +64,17 @@ int Process::gui$create_window(const GUI_CreateWindowParameters* user_params) window->set_rect(rect); m_windows.set(window_id, move(window)); +#ifdef LOG_GUI_SYSCALLS dbgprintf("%s<%u> gui$create_window: %d with rect {%d,%d %dx%d}\n", name().characters(), pid(), window_id, rect.x(), rect.y(), rect.width(), rect.height()); - +#endif return window_id; } int Process::gui$destroy_window(int window_id) { +#ifdef LOG_GUI_SYSCALLS dbgprintf("%s<%u> gui$destroy_window (window_id=%d)\n", name().characters(), pid(), window_id); +#endif if (window_id < 0) return -EINVAL; auto it = m_windows.find(window_id); @@ -83,7 +86,9 @@ int Process::gui$destroy_window(int window_id) int Process::gui$get_window_backing_store(int window_id, GUI_WindowBackingStoreInfo* info) { +#ifdef LOG_GUI_SYSCALLS dbgprintf("%s<%u> gui$get_window_backing_store (window_id=%d, info=%p)\n", name().characters(), pid(), window_id, info); +#endif if (!validate_write_typed(info)) return -EFAULT; if (window_id < 0) @@ -101,7 +106,9 @@ int Process::gui$get_window_backing_store(int window_id, GUI_WindowBackingStoreI int Process::gui$invalidate_window(int window_id, const GUI_Rect* rect) { - dbgprintf("%s<%u> gui$invalidate_window (window_id=%d)\n", name().characters(), pid(), window_id); +#ifdef LOG_GUI_SYSCALLS + dbgprintf("%s<%u> gui$invalidate_window (window_id=%d, rect=%p)\n", name().characters(), pid(), window_id, rect); +#endif if (window_id < 0) return -EINVAL; if (rect && !validate_read_typed(rect)) diff --git a/WindowServer/WSEventLoop.cpp b/WindowServer/WSEventLoop.cpp index d860af4ff7..26c2d219da 100644 --- a/WindowServer/WSEventLoop.cpp +++ b/WindowServer/WSEventLoop.cpp @@ -110,7 +110,11 @@ void WSEventLoop::wait_for_event() params.readfds = &rfds; params.writefds = nullptr; params.exceptfds = nullptr; - params.timeout = nullptr; + struct timeval timeout = { 0, 0 }; + if (m_queued_events.is_empty()) + params.timeout = nullptr; + else + params.timeout = &timeout; int rc = m_server_process->sys$select(¶ms); memory_barrier(); if (rc < 0) { diff --git a/WindowServer/WSWindowManager.cpp b/WindowServer/WSWindowManager.cpp index 325863802f..6303dd6a3a 100644 --- a/WindowServer/WSWindowManager.cpp +++ b/WindowServer/WSWindowManager.cpp @@ -212,7 +212,9 @@ void WSWindowManager::notifyRectChanged(WSWindow& window, const Rect& old_rect, void WSWindowManager::handleTitleBarMouseEvent(WSWindow& window, MouseEvent& event) { if (event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left) { +#ifdef DRAG_DEBUG printf("[WM] Begin dragging WSWindow{%p}\n", &window); +#endif m_dragWindow = window.makeWeakPtr();; m_dragOrigin = event.position(); m_dragWindowOrigin = window.position(); @@ -226,7 +228,9 @@ void WSWindowManager::processMouseEvent(MouseEvent& event) { if (event.type() == WSEvent::MouseUp && event.button() == MouseButton::Left) { if (m_dragWindow) { +#ifdef DRAG_DEBUG printf("[WM] Finish dragging WSWindow{%p}\n", m_dragWindow.ptr()); +#endif invalidate(m_dragStartRect); invalidate(*m_dragWindow); m_dragWindow->set_is_being_dragged(false); @@ -240,7 +244,9 @@ void WSWindowManager::processMouseEvent(MouseEvent& event) if (m_dragWindow) { auto old_window_rect = m_dragWindow->rect(); Point pos = m_dragWindowOrigin; - printf("[WM] Dragging [origin: %d,%d] now: %d,%d\n", m_dragOrigin.x(), m_dragOrigin.y(), event.x(), event.y()); +#ifdef DRAG_DEBUG + dbgprintf("[WM] Dragging [origin: %d,%d] now: %d,%d\n", m_dragOrigin.x(), m_dragOrigin.y(), event.x(), event.y()); +#endif pos.move_by(event.x() - m_dragOrigin.x(), event.y() - m_dragOrigin.y()); m_dragWindow->set_position_without_repaint(pos); invalidate(outerRectForWindow(old_window_rect));