Index: trunk/Ohana/src/opihi/pcontrol/CheckIdleHost.c
===================================================================
--- trunk/Ohana/src/opihi/pcontrol/CheckIdleHost.c	(revision 7917)
+++ trunk/Ohana/src/opihi/pcontrol/CheckIdleHost.c	(revision 8296)
@@ -1,4 +1,5 @@
 # include "pcontrol.h"
 
+/* the supplied host is not on a stack: it cannot be taken by the other thread */
 int CheckIdleHost (Host *host) {
 
@@ -7,5 +8,7 @@
   Job *job;
 
+  /* search the JOB_PENDING stack for an appropriate job */
   stack = GetJobStack (PCONTROL_JOB_PENDING);
+  LockStack (stack);
   
   /* look for first NEEDHOST matching this host */
@@ -18,5 +21,12 @@
     }
     if (strcasecmp (job[0].hostname, host[0].hostname)) continue;
-    LinkJobAndHost (job, host);
+
+    /* we have found an appropriate job; link it to the host and send to StartJob */
+    job[0].host = (struct Host *) host;
+    host[0].job = (struct Job *) job;
+
+    /* take the job off the stack and unlock the stack */
+    RemoveStackEntry (stack, i);
+    UnlockStack (stack);
     StartJob (job);
     return (TRUE);
@@ -26,5 +36,4 @@
   for (i = 0; i < stack[0].Nobject; i++) {
     job = (Job *) stack[0].object[i];
-    /*** this currently never runs WANTHOST jobs on any other machines ***/
     if (job[0].mode != PCONTROL_JOB_WANTHOST) continue;
     if (job[0].hostname == NULL) {
@@ -33,5 +42,12 @@
     }
     if (strcasecmp (job[0].hostname, host[0].hostname)) continue;
-    LinkJobAndHost (job, host);
+
+    /* we have found an appropriate job; link it to the host and send to StartJob */
+    job[0].host = (struct Host *) host;
+    host[0].job = (struct Job *) job;
+
+    /* take the job off the stack and unlock the stack */
+    RemoveStackEntry (stack, i);
+    UnlockStack (stack);
     StartJob (job);
     return (TRUE);
@@ -42,9 +58,37 @@
     job = (Job *) stack[0].object[i];
     if (job[0].mode != PCONTROL_JOB_ANYHOST) continue;
-    LinkJobAndHost (job, host);
+
+    /* we have found an appropriate job; link it to the host and send to StartJob */
+    job[0].host = (struct Host *) host;
+    host[0].job = (struct Job *) job;
+
+    /* take the job off the stack and unlock the stack */
+    RemoveStackEntry (stack, i);
+    UnlockStack (stack);
     StartJob (job);
-    return (TRUE);
+   return (TRUE);
   }
-  /* no jobs for host, but back on IDLE stack */
+
+  /* no ANYHOST entry, look for first WANTHOST with old time */
+  /* XXX perhaps I should add this to the conditions for ANYHOST instead of
+     running a separate loop?  ie, WANTHOST && time > X == ANYHOST */
+  for (i = 0; i < stack[0].Nobject; i++) {
+    job = (Job *) stack[0].object[i];
+    if (job[0].mode != PCONTROL_JOB_WANTHOST) continue;
+    // test the job age and skip if too young
+
+    /* we have found an appropriate job; link it to the host and send to StartJob */
+    job[0].host = (struct Host *) host;
+    host[0].job = (struct Job *) job;
+
+    /* take the job off the stack and unlock the stack */
+    RemoveStackEntry (stack, i);
+    UnlockStack (stack);
+    StartJob (job);
+   return (TRUE);
+  }
+  UnlockStack (stack);
+
+  /* no jobs for host, put it back on IDLE stack */
   PutHost (host, PCONTROL_HOST_IDLE, STACK_BOTTOM);
   return (TRUE);
