Commit fe22d483915caba0af63afeadb7e6512a47fff6f

ckolivas 2014-06-28T13:37:28

Fix deref

diff --git a/cgminer.c b/cgminer.c
index 7864d60..da38b65 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -7492,14 +7492,10 @@ void __add_queued(struct cgpu_info *cgpu, struct work *work)
 	HASH_ADD_INT(cgpu->queued_work, id, work);
 }
 
-/* This function is for retrieving one work item from the unqueued pointer and
- * adding it to the hashtable of queued work. Code using this function must be
- * able to handle NULL as a return which implies there is no work available. */
-struct work *get_queued(struct cgpu_info *cgpu)
+struct work *__get_queued(struct cgpu_info *cgpu)
 {
 	struct work *work = NULL;
 
-	wr_lock(&cgpu->qlock);
 	if (cgpu->unqueued_work) {
 		work = cgpu->unqueued_work;
 		if (unlikely(stale_work(work, false))) {
@@ -7509,6 +7505,19 @@ struct work *get_queued(struct cgpu_info *cgpu)
 			__add_queued(cgpu, work);
 		cgpu->unqueued_work = NULL;
 	}
+
+	return work;
+}
+
+/* This function is for retrieving one work item from the unqueued pointer and
+ * adding it to the hashtable of queued work. Code using this function must be
+ * able to handle NULL as a return which implies there is no work available. */
+struct work *get_queued(struct cgpu_info *cgpu)
+{
+	struct work *work;
+
+	wr_lock(&cgpu->qlock);
+	work = __get_queued(cgpu);
 	wr_unlock(&cgpu->qlock);
 
 	return work;
diff --git a/driver-bflsc.c b/driver-bflsc.c
index 5ff706f..f87b456 100644
--- a/driver-bflsc.c
+++ b/driver-bflsc.c
@@ -1730,10 +1730,14 @@ static bool bflsc28_queue_full(struct cgpu_info *bflsc)
 	if (bflsc->usbinfo.nodev)
 		return true;
 
-	base_work = get_queued(bflsc);
+	wr_lock(&bflsc->qlock);
+	base_work = __get_queued(bflsc);
+	if (likely(base_work))
+		__work_completed(bflsc, base_work);
+	wr_unlock(&bflsc->qlock);
+
 	if (unlikely(!base_work))
 		return ret;
-	work_completed(bflsc, base_work);
 	created = 1;
 
 	create = 9;
diff --git a/miner.h b/miner.h
index d9d5da1..2d93659 100644
--- a/miner.h
+++ b/miner.h
@@ -1431,6 +1431,7 @@ extern int share_work_tdiff(struct cgpu_info *cgpu);
 extern struct work *get_work(struct thr_info *thr, const int thr_id);
 extern void __add_queued(struct cgpu_info *cgpu, struct work *work);
 extern struct work *get_queued(struct cgpu_info *cgpu);
+extern struct work *__get_queued(struct cgpu_info *cgpu);
 extern void add_queued(struct cgpu_info *cgpu, struct work *work);
 extern struct work *get_queue_work(struct thr_info *thr, struct cgpu_info *cgpu, int thr_id);
 extern struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);