FIXES 2498
CheckHost() sets the HOSTDELETED flag on a host, does its
touch, calls H_UNLOCK at the end of its function;
AddCallBCal1 in a different thread grabs the lock, does its
thing. Gets to GetSomeSpace_r(), which calls
h_Enumerate_r; the host in question isn't held, so
h_Enumerate_r calls h_Hold_r and h_Release_r on the host
that CheckHost() set the HOSTDELETED flag on; h_Release_r
sees the HOSTDELETED flag and calls h_TossStuff_r, poof, we
have our broken host entry for ClearHostCallbacks_r to trip
}
static struct host *lih_host;
+static int lih_host_held = 0;
static int
lih_r(register struct host *host, register int held,
register struct host *hostp)
{
+ lih_host_held = 0;
if (host->cblist
&& ((hostp && host != hostp) || (!held && !h_OtherHolds_r(host)))
&& (!lih_host || host->ActiveCall < lih_host->ActiveCall)) {
lih_host = host;
}
+ if (!held) {
+ held = 1;
+ lih_host_held = 1;
+ }
return held;
}
hp = lih_host;
if (hp) {
cbstuff.GSS4++;
- if (!ClearHostCallbacks_r(hp, 0 /* not locked or held */ ))
+ if (!ClearHostCallbacks_r(hp, 0 /* not locked or held */ )) {
+ if (lih_host_held)
+ h_Release_r(hp);
return 0;
+ }
+ if (lih_host_held)
+ h_Release_r(hp);
hp2 = hp->next;
} else {
hp2 = hostList;