Provide a funcion that looks up queued work by midstate and then removes it from the device hash database.
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 47 48 49 50 51 52 53 54 55 56 57 58
diff --git a/cgminer.c b/cgminer.c
index 196e5ae..1f5eb2c 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -6139,19 +6139,38 @@ struct work *clone_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate
return ret;
}
+static void __work_completed(struct cgpu_info *cgpu, struct work *work)
+{
+ if (work->queued)
+ cgpu->queued_count--;
+ HASH_DEL(cgpu->queued_work, work);
+}
/* This function should be used by queued device drivers when they're sure
* the work struct is no longer in use. */
void work_completed(struct cgpu_info *cgpu, struct work *work)
{
wr_lock(&cgpu->qlock);
- if (work->queued)
- cgpu->queued_count--;
- HASH_DEL(cgpu->queued_work, work);
+ __work_completed(cgpu, work);
wr_unlock(&cgpu->qlock);
free_work(work);
}
+/* Combines find_queued_work_bymidstate and work_completed in one function
+ * withOUT destroying the work so the driver must free it. */
+struct work *take_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen)
+{
+ struct work *work;
+
+ rd_lock(&cgpu->qlock);
+ work = __find_work_bymidstate(cgpu->queued_work, midstate, midstatelen, data, offset, datalen);
+ if (work)
+ __work_completed(cgpu, work);
+ rd_unlock(&cgpu->qlock);
+
+ return work;
+}
+
static void flush_queue(struct cgpu_info *cgpu)
{
struct work *work, *tmp;
diff --git a/miner.h b/miner.h
index ab59cba..0f28e72 100644
--- a/miner.h
+++ b/miner.h
@@ -1341,6 +1341,7 @@ extern struct work *__find_work_bymidstate(struct work *que, char *midstate, siz
extern struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
extern struct work *clone_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
extern void work_completed(struct cgpu_info *cgpu, struct work *work);
+extern struct work *take_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
extern void hash_queued_work(struct thr_info *mythr);
extern void _wlog(const char *str);
extern void _wlogprint(const char *str);