Index: /trunk/src/VBox/ValidationKit/testdriver/base.py
===================================================================
--- /trunk/src/VBox/ValidationKit/testdriver/base.py	(revision 79244)
+++ /trunk/src/VBox/ValidationKit/testdriver/base.py	(revision 79245)
@@ -409,12 +409,17 @@
     """
 
-    def __init__(self, sCaller):
-        self.sDbgCreated    = '%s: %s' % (utils.getTimePrefix(), sCaller);
-        self.fSignalled     = False;
-        self.__oRLock       = threading.RLock();
-        self.oCv            = threading.Condition(self.__oRLock);
-        self.oOwner         = None;
-        self.msStart        = timestampMilli();
-        self.oLocker        = None;
+    def __init__(self, sCaller, fnProcessEvents = None):
+        self.sDbgCreated        = '%s: %s' % (utils.getTimePrefix(), sCaller);
+        self.fSignalled         = False;
+        self.__oRLock           = threading.RLock();
+        self.oCv                = threading.Condition(self.__oRLock);
+        self.oOwner             = None;
+        self.msStart            = timestampMilli();
+        self.oLocker            = None;
+
+        ## Callback function that takes no parameters and will not be called holding the lock.
+        ## It is a hack to work the XPCOM and COM event queues, so we won't hold back events
+        ## that could block task progress (i.e. hangs VM).
+        self.fnProcessEvents    = fnProcessEvents;
 
     def __del__(self):
@@ -540,9 +545,12 @@
         Overriable.
         """
+        if self.fnProcessEvents:
+            self.fnProcessEvents();
+
         self.lockTask();
 
         fState = self.pollTask(True);
         if not fState:
-            # Don't wait more than 1s.  This allow lazy state polling.
+            # Don't wait more than 1s.  This allow lazy state polling and avoid event processing trouble.
             msStart = timestampMilli();
             while not fState:
@@ -558,8 +566,18 @@
                 except:
                     pass;
+
+                if self.fnProcessEvents:
+                    self.unlockTask();
+                    self.fnProcessEvents();
+                    self.lockTask();
+
                 reporter.doPollWork('TdTaskBase.waitForTask');
                 fState = self.pollTask(True);
 
         self.unlockTask();
+
+        if self.fnProcessEvents:
+            self.fnProcessEvents();
+
         return fState;
 
Index: /trunk/src/VBox/ValidationKit/testdriver/txsclient.py
===================================================================
--- /trunk/src/VBox/ValidationKit/testdriver/txsclient.py	(revision 79244)
+++ /trunk/src/VBox/ValidationKit/testdriver/txsclient.py	(revision 79245)
@@ -386,5 +386,5 @@
     """
 
-    def __init__(self, oTransport, cMsTimeout, cMsIdleFudge, fTryConnect = False):
+    def __init__(self, oTransport, cMsTimeout, cMsIdleFudge, fTryConnect = False, fnProcessEvents = None):
         """
         Construct a TXS session.
@@ -393,5 +393,5 @@
         when connected or the timeout has been reached.
         """
-        TdTaskBase.__init__(self, utils.getCallerName());
+        TdTaskBase.__init__(self, utils.getCallerName(), fnProcessEvents);
         self.oTransport     = oTransport;
         self.sStatus        = "";
@@ -2104,13 +2104,16 @@
 
 
-def openTcpSession(cMsTimeout, sHostname, uPort = None, fReversedSetup = False, cMsIdleFudge = 0):
+def openTcpSession(cMsTimeout, sHostname, uPort = None, fReversedSetup = False, cMsIdleFudge = 0, fnProcessEvents = None):
     """
     Opens a connection to a Test Execution Service via TCP, given its name.
+
+    The optional fnProcessEvents callback should be set to vbox.processPendingEvents
+    or similar.
     """
-    reporter.log2('openTcpSession(%s, %s, %s, %s, %s)' % \
+    reporter.log2('openTcpSession(%s, %s, %s, %s, %s)' %
                   (cMsTimeout, sHostname, uPort, fReversedSetup, cMsIdleFudge));
     try:
         oTransport = TransportTcp(sHostname, uPort, fReversedSetup);
-        oSession = Session(oTransport, cMsTimeout, cMsIdleFudge);
+        oSession = Session(oTransport, cMsTimeout, cMsIdleFudge, fnProcessEvents = fnProcessEvents);
     except:
         reporter.errorXcpt(None, 15);
@@ -2119,5 +2122,5 @@
 
 
-def tryOpenTcpSession(cMsTimeout, sHostname, uPort = None, fReversedSetup = False, cMsIdleFudge = 0):
+def tryOpenTcpSession(cMsTimeout, sHostname, uPort = None, fReversedSetup = False, cMsIdleFudge = 0, fnProcessEvents = None):
     """
     Tries to open a connection to a Test Execution Service via TCP, given its name.
@@ -2128,5 +2131,5 @@
     try:
         oTransport = TransportTcp(sHostname, uPort, fReversedSetup);
-        oSession = Session(oTransport, cMsTimeout, cMsIdleFudge, fTryConnect = True);
+        oSession = Session(oTransport, cMsTimeout, cMsIdleFudge, fTryConnect = True, fnProcessEvents = fnProcessEvents);
     except:
         reporter.errorXcpt(None, 15);
Index: /trunk/src/VBox/ValidationKit/testdriver/vboxwrappers.py
===================================================================
--- /trunk/src/VBox/ValidationKit/testdriver/vboxwrappers.py	(revision 79244)
+++ /trunk/src/VBox/ValidationKit/testdriver/vboxwrappers.py	(revision 79245)
@@ -237,4 +237,6 @@
             except KeyboardInterrupt: raise;
             except: pass;
+            if self.fnProcessEvents:
+                self.fnProcessEvents();
             reporter.doPollWork('ProgressWrapper.waitForTask');
             fState = self.pollTask(False);
@@ -696,4 +698,6 @@
             except KeyboardInterrupt: raise;
             except: pass;
+            if self.fnProcessEvents:
+                self.fnProcessEvents();
             reporter.doPollWork('SessionWrapper.waitForTask');
             fState = self.pollTask(False);
@@ -2978,5 +2982,6 @@
         # Kick off the task.
         try:
-            oTask = TxsConnectTask(self, cMsTimeout, sIpAddr, sMacAddr, fReversedSetup);
+            oTask = TxsConnectTask(self, cMsTimeout, sIpAddr, sMacAddr, fReversedSetup,
+                                   fnProcessEvents = self.oTstDrv.processPendingEvents);
         except:
             reporter.errorXcpt();
@@ -2998,5 +3003,6 @@
 
         oTxsSession = txsclient.tryOpenTcpSession(cMsTimeout, sHostname, fReversedSetup = fReversed,
-                                                  cMsIdleFudge = cMsTimeout // 2);
+                                                  cMsIdleFudge = cMsTimeout // 2,
+                                                  fnProcessEvents = self.oTstDrv.processPendingEvents);
         if oTxsSession is None:
             return False;
@@ -3046,7 +3052,8 @@
 
 
-    def __init__(self, oSession, cMsTimeout, sIpAddr, sMacAddr, fReversedSetup):
+    def __init__(self, oSession, cMsTimeout, sIpAddr, sMacAddr, fReversedSetup, fnProcessEvents = None):
         TdTaskBase.__init__(self, utils.getCallerName());
         self.cMsTimeout         = cMsTimeout;
+        self.fnProcessEvents    = fnProcessEvents;
         self.sIpAddr            = None;
         self.sNextIpAddr        = None;
@@ -3147,9 +3154,9 @@
         self.oCv.acquire();
         if self.oTxsSession is None:
-            reporter.log2('_openTcpSession: sIpAddr=%s, uPort=%d, fReversedSetup=%s' % \
+            reporter.log2('_openTcpSession: sIpAddr=%s, uPort=%d, fReversedSetup=%s' %
                           (sIpAddr, uPort if uPort is not None else 0, fReversedSetup));
             self.sIpAddr     = sIpAddr;
-            self.oTxsSession = txsclient.openTcpSession(self.cMsTimeout, sIpAddr, uPort, \
-                                                        fReversedSetup, cMsIdleFudge);
+            self.oTxsSession = txsclient.openTcpSession(self.cMsTimeout, sIpAddr, uPort, fReversedSetup,
+                                                        cMsIdleFudge, fnProcessEvents = self.fnProcessEvents);
             self.oTxsSession.setTaskOwner(self);
         else:
