From 221f4f232ae79b8123e7ce28d26a873e1ba9f9dc Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Wed, 9 Apr 2014 16:01:43 +0200 Subject: [PATCH] dev: Protect PollEvent processing when running in parallel mode The calling thread is undefined when the PollQueue services events. This implies that PollEvents need to handle the case where they are processed from a different thread than the thread that created the event. This changeset adds temporary event queue migrations to the VNC server, the ethernet tap device, and the terminal to protect them from inter-thread calls. --- src/base/vnc/vncserver.cc | 5 +++++ src/dev/ethertap.cc | 5 +++++ src/dev/terminal.cc | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/src/base/vnc/vncserver.cc b/src/base/vnc/vncserver.cc index debf820143..9ca575915d 100644 --- a/src/base/vnc/vncserver.cc +++ b/src/base/vnc/vncserver.cc @@ -174,6 +174,11 @@ VncServer::listen(int port) void VncServer::accept() { + // As a consequence of being called from the PollQueue, we might + // have been called from a different thread. Migrate to "our" + // thread. + EventQueue::ScopedMigration migrate(eventQueue()); + if (!listener.islistening()) panic("%s: cannot accept a connection if not listening!", name()); diff --git a/src/dev/ethertap.cc b/src/dev/ethertap.cc index 94e381a8ed..e14fd90c21 100644 --- a/src/dev/ethertap.cc +++ b/src/dev/ethertap.cc @@ -106,6 +106,11 @@ TapListener::listen() void TapListener::accept() { + // As a consequence of being called from the PollQueue, we might + // have been called from a different thread. Migrate to "our" + // thread. + EventQueue::ScopedMigration migrate(tap->eventQueue()); + if (!listener.islistening()) panic("TapListener(accept): cannot accept if we're not listening!"); diff --git a/src/dev/terminal.cc b/src/dev/terminal.cc index a11d45554e..e70a8775fd 100644 --- a/src/dev/terminal.cc +++ b/src/dev/terminal.cc @@ -84,6 +84,11 @@ Terminal::DataEvent::DataEvent(Terminal *t, int fd, int e) void Terminal::DataEvent::process(int revent) { + // As a consequence of being called from the PollQueue, we might + // have been called from a different thread. Migrate to "our" + // thread. + EventQueue::ScopedMigration migrate(term->eventQueue()); + if (revent & POLLIN) term->data(); else if (revent & POLLNVAL)