Siteshwar Vashisht 009518
From 354efb96f1e4574f458e994163bbe31c76769573 Mon Sep 17 00:00:00 2001
Siteshwar Vashisht 009518
From: Chet Ramey <chet.ramey@case.edu>
Siteshwar Vashisht 009518
Date: Fri, 1 Jun 2018 10:19:56 -0400
Siteshwar Vashisht 009518
Subject: [PATCH] saved background process status hash table loop fixes
Siteshwar Vashisht 009518
Siteshwar Vashisht 009518
---
Siteshwar Vashisht 009518
 jobs.c       | 62 +++++++++++++++++++++++++++++++++++++++++++++++-------------
Siteshwar Vashisht 009518
 patchlevel.h |  2 +-
Siteshwar Vashisht 009518
 2 files changed, 50 insertions(+), 14 deletions(-)
Siteshwar Vashisht 009518
Siteshwar Vashisht 009518
diff --git a/jobs.c b/jobs.c
Siteshwar Vashisht 009518
index fc966036..2684632d 100644
Siteshwar Vashisht 009518
--- a/jobs.c
Siteshwar Vashisht 009518
+++ b/jobs.c
Siteshwar Vashisht 009518
@@ -812,8 +812,22 @@ bgp_add (pid, status)
Siteshwar Vashisht 009518
   ps_index_t *bucket, psi;
Siteshwar Vashisht 009518
   struct pidstat *ps;
Siteshwar Vashisht 009518
 
Siteshwar Vashisht 009518
-  bucket = pshash_getbucket (pid);
Siteshwar Vashisht 009518
-  psi = bgp_getindex ();
Siteshwar Vashisht 009518
+  /* bucket == existing chain of pids hashing to same value
Siteshwar Vashisht 009518
+     psi = where were going to put this pid/status */
Siteshwar Vashisht 009518
+
Siteshwar Vashisht 009518
+  bucket = pshash_getbucket (pid);	/* index into pidstat_table */
Siteshwar Vashisht 009518
+  psi = bgp_getindex ();		/* bgpids.head, index into storage */
Siteshwar Vashisht 009518
+
Siteshwar Vashisht 009518
+  /* XXX - what if psi == *bucket? */
Siteshwar Vashisht 009518
+  if (psi == *bucket)
Siteshwar Vashisht 009518
+    {
Siteshwar Vashisht 009518
+#ifdef DEBUG
Siteshwar Vashisht 009518
+      internal_warning ("hashed pid %d (pid %d) collides with bgpids.head, skipping", psi, pid);
Siteshwar Vashisht 009518
+#endif
Siteshwar Vashisht 009518
+      bgpids.storage[psi].pid = NO_PID;		/* make sure */
Siteshwar Vashisht 009518
+      psi = bgp_getindex ();			/* skip to next one */
Siteshwar Vashisht 009518
+    }
Siteshwar Vashisht 009518
+
Siteshwar Vashisht 009518
   ps = &bgpids.storage[psi];
Siteshwar Vashisht 009518
 
Siteshwar Vashisht 009518
   ps->pid = pid;
Siteshwar Vashisht 009518
@@ -841,32 +855,47 @@ pshash_delindex (psi)
Siteshwar Vashisht 009518
      ps_index_t psi;
Siteshwar Vashisht 009518
 {
Siteshwar Vashisht 009518
   struct pidstat *ps;
Siteshwar Vashisht 009518
+  ps_index_t *bucket;
Siteshwar Vashisht 009518
 
Siteshwar Vashisht 009518
   ps = &bgpids.storage[psi];
Siteshwar Vashisht 009518
   if (ps->pid == NO_PID)
Siteshwar Vashisht 009518
     return;
Siteshwar Vashisht 009518
 
Siteshwar Vashisht 009518
-  if (ps->bucket_next != NO_PID)
Siteshwar Vashisht 009518
+  if (ps->bucket_next != NO_PIDSTAT)
Siteshwar Vashisht 009518
     bgpids.storage[ps->bucket_next].bucket_prev = ps->bucket_prev;
Siteshwar Vashisht 009518
-  if (ps->bucket_prev != NO_PID)
Siteshwar Vashisht 009518
+  if (ps->bucket_prev != NO_PIDSTAT)
Siteshwar Vashisht 009518
     bgpids.storage[ps->bucket_prev].bucket_next = ps->bucket_next;
Siteshwar Vashisht 009518
   else
Siteshwar Vashisht 009518
-    *(pshash_getbucket (ps->pid)) = ps->bucket_next;
Siteshwar Vashisht 009518
+    {
Siteshwar Vashisht 009518
+      bucket = pshash_getbucket (ps->pid);
Siteshwar Vashisht 009518
+      *bucket = ps->bucket_next;	/* deleting chain head in hash table */
Siteshwar Vashisht 009518
+    }
Siteshwar Vashisht 009518
+
Siteshwar Vashisht 009518
+  /* clear out this cell, just in case */
Siteshwar Vashisht 009518
+  ps->pid = NO_PID;
Siteshwar Vashisht 009518
+  ps->bucket_next = ps->bucket_prev = NO_PIDSTAT;
Siteshwar Vashisht 009518
 }
Siteshwar Vashisht 009518
 
Siteshwar Vashisht 009518
 static int
Siteshwar Vashisht 009518
 bgp_delete (pid)
Siteshwar Vashisht 009518
      pid_t pid;
Siteshwar Vashisht 009518
 {
Siteshwar Vashisht 009518
-  ps_index_t psi;
Siteshwar Vashisht 009518
+  ps_index_t psi, orig_psi;
Siteshwar Vashisht 009518
 
Siteshwar Vashisht 009518
   if (bgpids.storage == 0 || bgpids.nalloc == 0 || bgpids.npid == 0)
Siteshwar Vashisht 009518
     return 0;
Siteshwar Vashisht 009518
 
Siteshwar Vashisht 009518
   /* Search chain using hash to find bucket in pidstat_table */
Siteshwar Vashisht 009518
-  for (psi = *(pshash_getbucket (pid)); psi != NO_PIDSTAT; psi = bgpids.storage[psi].bucket_next)
Siteshwar Vashisht 009518
-    if (bgpids.storage[psi].pid == pid)
Siteshwar Vashisht 009518
-      break;
Siteshwar Vashisht 009518
+  for (orig_psi = psi = *(pshash_getbucket (pid)); psi != NO_PIDSTAT; psi = bgpids.storage[psi].bucket_next)
Siteshwar Vashisht 009518
+    {
Siteshwar Vashisht 009518
+      if (bgpids.storage[psi].pid == pid)
Siteshwar Vashisht 009518
+	break;
Siteshwar Vashisht 009518
+      if (orig_psi == bgpids.storage[psi].bucket_next)	/* catch reported bug */
Siteshwar Vashisht 009518
+	{
Siteshwar Vashisht 009518
+	  internal_warning ("bgp_delete: LOOP: psi (%d) == storage[psi].bucket_next", psi);
Siteshwar Vashisht 009518
+	  return 0;
Siteshwar Vashisht 009518
+	}
Siteshwar Vashisht 009518
+    }
Siteshwar Vashisht 009518
 
Siteshwar Vashisht 009518
   if (psi == NO_PIDSTAT)
Siteshwar Vashisht 009518
     return 0;		/* not found */
Siteshwar Vashisht 009518
@@ -904,15 +933,22 @@ static int
Siteshwar Vashisht 009518
 bgp_search (pid)
Siteshwar Vashisht 009518
      pid_t pid;
Siteshwar Vashisht 009518
 {
Siteshwar Vashisht 009518
-  ps_index_t psi;
Siteshwar Vashisht 009518
+  ps_index_t psi, orig_psi;
Siteshwar Vashisht 009518
 
Siteshwar Vashisht 009518
   if (bgpids.storage == 0 || bgpids.nalloc == 0 || bgpids.npid == 0)
Siteshwar Vashisht 009518
     return -1;
Siteshwar Vashisht 009518
 
Siteshwar Vashisht 009518
   /* Search chain using hash to find bucket in pidstat_table */
Siteshwar Vashisht 009518
-  for (psi = *(pshash_getbucket (pid)); psi != NO_PIDSTAT; psi = bgpids.storage[psi].bucket_next)
Siteshwar Vashisht 009518
-    if (bgpids.storage[psi].pid == pid)
Siteshwar Vashisht 009518
-      return (bgpids.storage[psi].status);
Siteshwar Vashisht 009518
+  for (orig_psi = psi = *(pshash_getbucket (pid)); psi != NO_PIDSTAT; psi = bgpids.storage[psi].bucket_next)
Siteshwar Vashisht 009518
+    {
Siteshwar Vashisht 009518
+      if (bgpids.storage[psi].pid == pid)
Siteshwar Vashisht 009518
+	return (bgpids.storage[psi].status);
Siteshwar Vashisht 009518
+      if (orig_psi == bgpids.storage[psi].bucket_next)	/* catch reported bug */
Siteshwar Vashisht 009518
+	{
Siteshwar Vashisht 009518
+	  internal_warning ("bgp_search: LOOP: psi (%d) == storage[psi].bucket_next", psi);
Siteshwar Vashisht 009518
+	  return -1;
Siteshwar Vashisht 009518
+	}
Siteshwar Vashisht 009518
+    }
Siteshwar Vashisht 009518
 
Siteshwar Vashisht 009518
   return -1;
Siteshwar Vashisht 009518
 }
Siteshwar Vashisht 009518
diff --git a/patchlevel.h b/patchlevel.h
Siteshwar Vashisht 009518
index a711c495..4a65dc0f 100644
Siteshwar Vashisht 009518
--- a/patchlevel.h
Siteshwar Vashisht 009518
+++ b/patchlevel.h
Siteshwar Vashisht 009518
@@ -25,6 +25,6 @@
Siteshwar Vashisht 009518
    regexp `^#define[ 	]*PATCHLEVEL', since that's what support/mkversion.sh
Siteshwar Vashisht 009518
    looks for to find the patch level (for the sccs version string). */
Siteshwar Vashisht 009518
 
Siteshwar Vashisht 009518
-#define PATCHLEVEL 19
Siteshwar Vashisht 009518
+#define PATCHLEVEL 20
Siteshwar Vashisht 009518
 
Siteshwar Vashisht 009518
 #endif /* _PATCHLEVEL_H_ */
Siteshwar Vashisht 009518
-- 
Siteshwar Vashisht 009518
2.14.4
Siteshwar Vashisht 009518