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