Index: trunk/Ohana/src/opihi/pcontrol/JobOps.c
===================================================================
--- trunk/Ohana/src/opihi/pcontrol/JobOps.c	(revision 7917)
+++ trunk/Ohana/src/opihi/pcontrol/JobOps.c	(revision 8296)
@@ -4,4 +4,5 @@
 Stack *JobPool_Busy;
 Stack *JobPool_Done;
+Stack *JobPool_Kill;
 Stack *JobPool_Exit;
 Stack *JobPool_Crash;
@@ -9,8 +10,9 @@
 void InitJobStacks () {
   JobPool_Pending = InitStack ();
-  JobPool_Busy = InitStack ();
-  JobPool_Done = InitStack ();
-  JobPool_Exit = InitStack ();
-  JobPool_Crash = InitStack ();
+  JobPool_Busy    = InitStack ();
+  JobPool_Done    = InitStack ();
+  JobPool_Kill    = InitStack ();
+  JobPool_Exit    = InitStack ();
+  JobPool_Crash   = InitStack ();
 }
 
@@ -23,4 +25,6 @@
     case PCONTROL_JOB_DONE:
       return (JobPool_Done);
+    case PCONTROL_JOB_KILL:
+      return (JobPool_Kill);
     case PCONTROL_JOB_EXIT:
       return (JobPool_Exit);
@@ -37,40 +41,13 @@
 Stack *GetJobStackByName (char *name) {
 
-  if (!strcasecmp (name, "pending")) 
-    return (JobPool_Pending);
-  if (!strcasecmp (name, "busy")) 
-    return (JobPool_Busy);
-  if (!strcasecmp (name, "done")) 
-    return (JobPool_Done);
-  if (!strcasecmp (name, "exit")) 
-    return (JobPool_Exit);
-  if (!strcasecmp (name, "crash")) 
-    return (JobPool_Crash);
+  if (!strcasecmp (name, "pending")) return (JobPool_Pending);
+  if (!strcasecmp (name, "busy"))    return (JobPool_Busy);
+  if (!strcasecmp (name, "done"))    return (JobPool_Done);
+  if (!strcasecmp (name, "exit"))    return (JobPool_Exit);
+  if (!strcasecmp (name, "crash"))   return (JobPool_Crash);
   return (NULL);
 }
 
-Job *FindJobStack (IDtype JobID) {
-
-  Job *job;
-
-  job = FindJobPtr (JobID, PCONTROL_JOB_PENDING);
-  if (job != NULL) return (job);
-
-  job = FindJobPtr (JobID, PCONTROL_JOB_BUSY);
-  if (job != NULL) return (job);
-
-  job = FindJobPtr (JobID, PCONTROL_JOB_EXIT);
-  if (job != NULL) return (job);
-
-  job = FindJobPtr (JobID, PCONTROL_JOB_CRASH);
-  if (job != NULL) return (job);
-
-  job = FindJobPtr (JobID, PCONTROL_JOB_DONE);
-  if (job != NULL) return (job);
-
-  return (NULL);
-}
-
-/* add job to position in stack */
+/* add job to position in stack, use StackID as default state */
 int PutJob (Job *job, int StackID, int where) {
 
@@ -81,14 +58,62 @@
   if (stack == NULL) return (FALSE);
 
-  /* be default, these are both the same - to override, set state after PutJob */
+  /* by default, these are both the same - to override, use PutJobSetState */
   job[0].state = StackID;
   job[0].stack = StackID;
-  stat = PutStack (stack, where, job);
-  /* status (0, NULL); */
+  stat = PushStack (stack, where, job, job[0].JobID, job[0].argv[0]);
+  // XXX need to handle the error conditions, or we drop the host & leak memory
   return (stat);
 }
   
+/* add job to position in stack.  set state to 'state' */
+int PutJobSetState (Job *job, int StackID, int where, int state) {
+
+  int stat;
+  Stack *stack;
+
+  stack = GetJobStack (StackID);
+  if (stack == NULL) return (FALSE);
+
+  /* alternate state specified by user */
+  job[0].state = state;
+  job[0].stack = StackID;
+  stat = PushStack (stack, where, job, job[0].JobID, job[0].argv[0]);
+  // XXX need to handle the error conditions, or we drop the host & leak memory
+  return (stat);
+}
+  
+Job *PullJobByID (IDtype JobID, int *StackID) {
+
+  Job *job;
+
+  *StackID = PCONTROL_JOB_PENDING;
+  job = PullJobFromStackByID (*StackID, JobID);
+  if (job != NULL) return (job);
+
+  *StackID = PCONTROL_JOB_BUSY;
+  job = PullJobFromStackByID (*StackID, JobID);
+  if (job != NULL) return (job);
+
+  *StackID = PCONTROL_JOB_EXIT;
+  job = PullJobFromStackByID (*StackID, JobID);
+  if (job != NULL) return (job);
+
+  *StackID = PCONTROL_JOB_CRASH;
+  job = PullJobFromStackByID (*StackID, JobID);
+  if (job != NULL) return (job);
+
+  *StackID = PCONTROL_JOB_DONE;
+  job = PullJobFromStackByID (*StackID, JobID);
+  if (job != NULL) return (job);
+
+  *StackID = PCONTROL_JOB_KILL;
+  job = PullJobFromStackByID (*StackID, JobID);
+  if (job != NULL) return (job);
+
+  return (NULL);
+}
+
 /* remove job from position in stack */
-Job *GetJob (int StackID, int where) {
+Job *PullJobFromStackByID (int StackID, int ID) {
 
   Job *job;
@@ -98,31 +123,40 @@
   if (stack == NULL) return (NULL);
 
-  job = GetStack (stack, where);
+  job = PullStackByID (stack, ID);
   return (job);
 }
   
-/* return stack position of job */
-int FindJob (IDtype JobID, int StackID) {
-
-  int i;
-  Job *job;
-  Stack *stack;
-
-  stack = GetJobStack (StackID);
-  if (stack == NULL) return (-2);
-
-  for (i = 0; i < stack[0].Nobject; i++) {
-    job = (Job *) stack[0].object[i];
-    if (job[0].JobID == JobID) {
-      return (i);
-    }
-  }
-  return (-1);
-}
-
-/* return pointer to job */
-Job *FindJobPtr (IDtype JobID, int StackID) {
-
-  int i;
+/* the Find functions are not thread-safe: DROP */
+# if (0)
+Job *FindJobByID (IDtype JobID, int *StackID) {
+
+  Job *job;
+
+  *StackID = PCONTROL_JOB_PENDING;
+  job = FindJobInStackByID (*StackID, JobID);
+  if (job != NULL) return (job);
+
+  *StackID = PCONTROL_JOB_BUSY;
+  job = FindJobInStackByID (*StackID, JobID);
+  if (job != NULL) return (job);
+
+  *StackID = PCONTROL_JOB_EXIT;
+  job = FindJobInStackByID (*StackID, JobID);
+  if (job != NULL) return (job);
+
+  *StackID = PCONTROL_JOB_CRASH;
+  job = FindJobInStackByID (*StackID, JobID);
+  if (job != NULL) return (job);
+
+  *StackID = PCONTROL_JOB_DONE;
+  job = FindJobInStackByID (*StackID, JobID);
+  if (job != NULL) return (job);
+
+  return (NULL);
+}
+
+/* remove job from position in stack */
+Job *FindJobInStackByID (int StackID, int ID) {
+
   Job *job;
   Stack *stack;
@@ -131,32 +165,12 @@
   if (stack == NULL) return (NULL);
 
-  for (i = 0; i < stack[0].Nobject; i++) {
-    job = (Job *) stack[0].object[i];
-    if (job[0].JobID == JobID) {
-      return (job);
-    }
-  }
-  return (NULL);
-}
-
-/* remove job from stack, return pointer */
-Job *PullJob (IDtype JobID, int StackID) {
-  
-  int N;
-  Job *job;
-
-  N = FindJob (JobID, StackID);
-  if (N < 0) return (NULL);
-
-  job = GetJob (StackID, N);
-  if (job == NULL) {
-    gprint (GP_ERR, "programming error! job missing from stack\n");
-    exit (1);
-  }
+  job = FindStackByID (stack, ID);
   return (job);
 }
+# endif
 
 IDtype AddJob (char *hostname, JobMode mode, int timeout, int argc, char **argv) {
 
+  int JobID;
   Job *job;
 
@@ -175,7 +189,8 @@
   InitIOBuffer (&job[0].stderr, 0x1000);
 
+  JobID = job[0].JobID;
   PutJob (job, PCONTROL_JOB_PENDING, STACK_BOTTOM);
   gprint (GP_ERR, "added new job\n");
-  return (job[0].JobID);
+  return (JobID);
 }
 
@@ -212,5 +227,6 @@
   
   /* remove host from correct stack */
-  if (PullHost (host[0].HostID, host[0].stack) == NULL) {
+  XXXX does this step asuume the host is in this stack??
+  if (PullHostFromStackByID (host[0].stack, host[0].HostID) == NULL) {
     gprint (GP_ERR, "programming error: host is not found in current stack\n");
     exit (2);
@@ -218,14 +234,2 @@
   return (host);
 }
-
-void LinkJobAndHost (Job *job, Host *host) {
-
-  job[0].host = (struct Host *) host;
-  host[0].job = (struct Job *) job;
-
-  /* remove job from correct stack */
-  if (PullJob (job[0].JobID, job[0].stack) == NULL) {
-    gprint (GP_ERR, "programming error: job is not found in current stack\n");
-    exit (2);
-  }
-}
