1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 04:07:44 +00:00

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.
This commit is contained in:
Andreas Kling 2019-01-18 05:26:45 +01:00
parent a01e119e05
commit dff5051905
4 changed files with 24 additions and 7 deletions

View file

@ -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();
}

View file

@ -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))

View file

@ -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(&params);
memory_barrier();
if (rc < 0) {

View file

@ -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));