Invalidating work after longpoll made hash_pop return no work giving a false positive for dead pool. Rework hash_pop to retry while finds no staged work until the abstime timeout really expires.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
diff --git a/main.c b/main.c
index a12a0ee..1706e9a 100644
--- a/main.c
+++ b/main.c
@@ -4087,31 +4087,23 @@ static bool queue_request(struct thr_info *thr, bool needed)
return true;
}
-struct work *hash_pop(const struct timespec *abstime)
+static struct work *hash_pop(const struct timespec *abstime)
{
struct work *work = NULL;
- int rc;
+ int rc = 0;
mutex_lock(stgd_lock);
- if (HASH_COUNT(staged_work))
- goto pop;
-
- if (abstime)
+ while (!getq->frozen && !HASH_COUNT(staged_work) && !rc)
rc = pthread_cond_timedwait(&getq->cond, stgd_lock, abstime);
- else
- rc = pthread_cond_wait(&getq->cond, stgd_lock);
- if (rc)
- goto out;
- if (!HASH_COUNT(staged_work))
- goto out;
-pop:
- work = staged_work;
- HASH_DEL(staged_work, work);
- if (work->clone)
- --staged_clones;
-out:
+ if (HASH_COUNT(staged_work)) {
+ work = staged_work;
+ HASH_DEL(staged_work, work);
+ if (work->clone)
+ --staged_clones;
+ }
mutex_unlock(stgd_lock);
+
return work;
}