|
|
|
@ -3834,17 +3834,29 @@ out:
@@ -3834,17 +3834,29 @@ out:
|
|
|
|
|
|
|
|
|
|
static struct work *hash_pop(const struct timespec *abstime) |
|
|
|
|
{ |
|
|
|
|
struct work *work = NULL; |
|
|
|
|
struct work *work = NULL, *worka, *workb; |
|
|
|
|
int rc = 0; |
|
|
|
|
|
|
|
|
|
mutex_lock(stgd_lock); |
|
|
|
|
while (!getq->frozen && !HASH_COUNT(staged_work) && !rc) |
|
|
|
|
rc = pthread_cond_timedwait(&getq->cond, stgd_lock, abstime); |
|
|
|
|
|
|
|
|
|
if (HASH_COUNT(staged_work)) { |
|
|
|
|
work = staged_work; |
|
|
|
|
HASH_DEL(staged_work, work); |
|
|
|
|
if (unlikely(!HASH_COUNT(staged_work))) |
|
|
|
|
goto out_unlock; |
|
|
|
|
|
|
|
|
|
/* Look for cloned work first since original work can be used to
|
|
|
|
|
* generate further clones */ |
|
|
|
|
HASH_ITER(hh, staged_work, worka, workb) { |
|
|
|
|
if (worka->clone) { |
|
|
|
|
HASH_DEL(staged_work, worka); |
|
|
|
|
work = worka; |
|
|
|
|
goto out_unlock; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
work = staged_work; |
|
|
|
|
HASH_DEL(staged_work, work); |
|
|
|
|
out_unlock: |
|
|
|
|
mutex_unlock(stgd_lock); |
|
|
|
|
|
|
|
|
|
queue_request(NULL, false); |
|
|
|
|