dev: Protect PollEvent processing when running in parallel mode
authorAndreas Sandberg <andreas@sandberg.pp.se>
Wed, 9 Apr 2014 14:01:43 +0000 (16:01 +0200)
committerAndreas Sandberg <andreas@sandberg.pp.se>
Wed, 9 Apr 2014 14:01:43 +0000 (16:01 +0200)
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
src/dev/ethertap.cc
src/dev/terminal.cc

index debf82014394aa6126488c2ce26ce9a5770963a4..9ca575915d1dd91933b7d47d9aca784106d2d004 100644 (file)
@@ -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());
 
index 94e381a8ed228b6a70bc8369479d336f84388e71..e14fd90c215aa361cd7cdf83b1ac8667f912ebf7 100644 (file)
@@ -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!");
 
index a11d45554eaa4716b159946410d3f2d3d51c5497..e70a8775fd9029c02e6e5a5aa7a17b49ad3abd1d 100644 (file)
@@ -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)