app/internal/window: (Wayland) handle EAGAIN from wl_display_flush

Fixes gio#50

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-10-28 22:35:14 +01:00
parent f353c8c780
commit 3f66d34599
+12 -6
View File
@@ -762,21 +762,27 @@ func (w *window) loop() {
{Fd: int32(dispfd), Events: syscall.POLLIN | syscall.POLLERR}, {Fd: int32(dispfd), Events: syscall.POLLIN | syscall.POLLERR},
{Fd: int32(w.notify.read), Events: syscall.POLLIN | syscall.POLLERR}, {Fd: int32(w.notify.read), Events: syscall.POLLIN | syscall.POLLERR},
} }
dispEvents := &pollfds[0].Revents dispFd := &pollfds[0]
// Plenty of room for a backlog of notifications. // Plenty of room for a backlog of notifications.
var buf = make([]byte, 100) var buf = make([]byte, 100)
loop: loop:
for { for {
C.wl_display_dispatch_pending(conn.disp) C.wl_display_dispatch_pending(conn.disp)
if ret := C.wl_display_flush(conn.disp); ret < 0 { dispFd.Events &^= syscall.POLLOUT
break if _, err := C.wl_display_flush(conn.disp); err != nil {
if err != syscall.EAGAIN {
break
}
// EAGAIN means the output buffer was full. Poll for
// POLLOUT to know when we can write again.
dispFd.Events |= syscall.POLLOUT
} }
if w.dead { if w.dead {
w.w.Event(system.DestroyEvent{Err: w.pendingErr}) w.w.Event(system.DestroyEvent{Err: w.pendingErr})
break break
} }
// Clear poll events. // Clear poll events.
*dispEvents = 0 dispFd.Revents = 0
if _, err := syscall.Ppoll(pollfds, nil, nil); err != nil && err != syscall.EINTR { if _, err := syscall.Ppoll(pollfds, nil, nil); err != nil && err != syscall.EINTR {
panic(fmt.Errorf("ppoll failed: %v", err)) panic(fmt.Errorf("ppoll failed: %v", err))
} }
@@ -794,11 +800,11 @@ loop:
} }
// Handle events // Handle events
switch { switch {
case *dispEvents&syscall.POLLIN != 0: case dispFd.Revents&syscall.POLLIN != 0:
if ret := C.wl_display_dispatch(conn.disp); ret < 0 { if ret := C.wl_display_dispatch(conn.disp); ret < 0 {
break loop break loop
} }
case *dispEvents&(syscall.POLLERR|syscall.POLLHUP) != 0: case dispFd.Revents&(syscall.POLLERR|syscall.POLLHUP) != 0:
break loop break loop
} }
conn.repeat.Repeat() conn.repeat.Repeat()