[server] Better split flushing events and dispatch events

Running real world applications (Xwayland) showed that it doesn't like
at all that we do a dispatch when we are going to flush. This caused
in a very reliable manner a "Connection closed" error in XWayland, taking
down the client and in return the (xwayland-enabled) server.
This commit is contained in:
Martin Gräßlin 2015-04-21 08:56:19 +02:00
parent 260c33e75d
commit d28f95f603
5 changed files with 14 additions and 3 deletions

View file

@ -358,7 +358,7 @@ void TestWaylandSurface::testAttachBuffer()
QVERIFY(!buffer2->isReferenced());
delete buffer2;
// TODO: we should have a signal on when the Buffer gets released
QTest::qWait(100);
QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
QVERIFY(redBuffer.data()->isReleased());
KWayland::Server::BufferInterface *buffer3 = serverSurface->buffer();

View file

@ -46,6 +46,7 @@ class Display::Private
public:
Private(Display *q);
void flush();
void dispatch();
void setRunning(bool running);
void installSocketNotifier();
@ -77,7 +78,7 @@ void Display::Private::installSocketNotifier()
return;
}
QSocketNotifier *m_notifier = new QSocketNotifier(fd, QSocketNotifier::Read, q);
QObject::connect(m_notifier, &QSocketNotifier::activated, q, [this] { flush(); } );
QObject::connect(m_notifier, &QSocketNotifier::activated, q, [this] { dispatch(); } );
QObject::connect(QThread::currentThread()->eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, q, [this] { flush(); });
setRunning(true);
}
@ -94,6 +95,14 @@ Display::~Display()
}
void Display::Private::flush()
{
if (!display || !loop) {
return;
}
wl_display_flush_clients(display);
}
void Display::Private::dispatch()
{
if (!display || !loop) {
return;
@ -101,7 +110,6 @@ void Display::Private::flush()
if (wl_event_loop_dispatch(loop, 0) != 0) {
qCWarning(KWAYLAND_SERVER) << "Error on dispatching Wayland event loop";
}
wl_display_flush_clients(display);
}
void Display::setSocketName(const QString &name)

View file

@ -143,6 +143,7 @@ void KeyboardInterface::setFocusedSurface(SurfaceInterface *surface, quint32 ser
wl_array_release(&keys);
d->sendModifiers();
d->client->flush();
}
void KeyboardInterface::keyPressed(quint32 key, quint32 serial)

View file

@ -135,6 +135,7 @@ void PointerInterface::setFocusedSurface(SurfaceInterface *surface, quint32 seri
wl_pointer_send_enter(d->resource, serial,
d->focusedSurface->resource(),
wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y()));
d->client->flush();
}
void PointerInterface::buttonPressed(quint32 button, quint32 serial)

View file

@ -181,6 +181,7 @@ void BufferInterface::unref()
if (d->refCount == 0) {
if (d->buffer) {
wl_buffer_send_release(d->buffer);
wl_client_flush(wl_resource_get_client(d->buffer));
}
deleteLater();
}