diff --git a/meta/lib/oeqa/core/tests/test_concurrency.py b/meta/lib/oeqa/core/tests/test_concurrency.py
index b44c006d532..f7b1f554c96 100644
--- a/meta/lib/oeqa/core/tests/test_concurrency.py
+++ b/meta/lib/oeqa/core/tests/test_concurrency.py
@@ -6,6 +6,7 @@
 #
 
 import os
+import sys
 import unittest
 from unittest import mock
 
@@ -53,5 +54,15 @@ class TestConcurrency(TestBase):
             for other in {1, 2, 3} - {n}:
                 self.assertNotIn("testStreams%d" % other, output)
 
+    def test_concurrent_streams_restored(self):
+        # Each process' results are read in a separate thread; after running,
+        # sys.stdout and sys.stderr must be the original streams again. Any
+        # problem here is a race, so run several times.
+        stdout, stderr = sys.stdout, sys.stderr
+        for i in range(50):
+            self._run(['results'], processes=2)
+            self.assertIs(sys.stdout, stdout)
+            self.assertIs(sys.stderr, stderr)
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/meta/lib/oeqa/core/utils/concurrencytest.py b/meta/lib/oeqa/core/utils/concurrencytest.py
index 455b70faff2..24b391cdb96 100644
--- a/meta/lib/oeqa/core/utils/concurrencytest.py
+++ b/meta/lib/oeqa/core/utils/concurrencytest.py
@@ -55,7 +55,9 @@ class BBThreadsafeForwardingResult(ThreadsafeForwardingResult):
         self.threadnum = threadnum
         self.totalinprocess = totalinprocess
         self.totaltests = totaltests
-        self.buffer = True
+        # Don't set self.buffer, the output comes through outputbuf. Buffering
+        # here would swap sys.stdout/stderr in each reader thread, unlocked,
+        # and could leave them replaced after the tests have run.
         self.outputbuf = output
         # The process' output accumulates in outputbuf; this is how much of
         # it was given to earlier results
