Index: /trunk/src/VBox/ValidationKit/testmanager/core/schedulerbase.py
===================================================================
--- /trunk/src/VBox/ValidationKit/testmanager/core/schedulerbase.py	(revision 65032)
+++ /trunk/src/VBox/ValidationKit/testmanager/core/schedulerbase.py	(revision 65033)
@@ -1301,4 +1301,5 @@
               and oSchedGroup.idSchedGroup not in dIgnoreSchedGroupIds:
                 return (oSchedGroup, 0);
+            iWorkItem = 0;
 
         elif len(oTestBoxDataEx.aoInSchedGroups) > 0:
@@ -1340,7 +1341,9 @@
                 if aoFlat[iWorkItem].idSchedGroup not in dIgnoreSchedGroupIds:
                     return (aoFlat[iWorkItem], iWorkItem);
+        else:
+            iWorkItem = 0;
 
         # No active group.
-        return (None, 0);
+        return (None, iWorkItem);
 
     @staticmethod
@@ -1381,4 +1384,5 @@
 
                 # We may have to skip scheduling groups that are out of work (e.g. 'No build').
+                iInitialWorkItem     = iWorkItem;
                 dIgnoreSchedGroupIds = [];
                 while True:
@@ -1396,5 +1400,17 @@
                         oDb.commit();
                         return dResponse;
+
+                    # Check out the next work item?
+                    if oScheduler.getElapsedSecs() > config.g_kcSecMaxNewTask:
+                        break;
                     dIgnoreSchedGroupIds[oSchedGroup.idSchedGroup] = oSchedGroup;
+
+                # No luck, but best if we update the work item if we've made progress.
+                # Note! In case of a config.g_kcSecMaxNewTask timeout, this may accidentally skip
+                #       a work item with actually work to do.  But that's a small price to pay.
+                if iWorkItem != iInitialWorkItem:
+                    oTBStatusLogic.updateWorkItem(oTestBoxDataEx.idTestBox, iWorkItem);
+                    oDb.commit();
+                    return None;
         except:
             oDb.rollback();
