Only allow the mining thread to be cancelled when it is not within driver code, making for cleaner shutdown and allowing us to pthread_join the miner threads on kill_work().
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
diff --git a/cgminer.c b/cgminer.c
index 3b7a387..3037e6d 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -2801,21 +2801,13 @@ static void __kill_work(void)
thr = &control_thr[watchdog_thr_id];
thr_info_cancel(thr);
- applog(LOG_DEBUG, "Stopping mining threads");
- /* Stop the mining threads*/
- for (i = 0; i < mining_threads; i++) {
- thr = get_thread(i);
- thr_info_freeze(thr);
- thr->pause = true;
- }
-
- nmsleep(1000);
-
applog(LOG_DEBUG, "Killing off mining threads");
/* Kill the mining threads*/
for (i = 0; i < mining_threads; i++) {
thr = get_thread(i);
thr_info_cancel(thr);
+ if (thr && thr->pth)
+ pthread_join(thr->pth, NULL);
}
applog(LOG_DEBUG, "Killing off stage thread");
@@ -5653,8 +5645,13 @@ static void hash_sole_work(struct thr_info *mythr)
cgtime(&(work->tv_work_start));
thread_reportin(mythr);
+ /* Only allow the mining thread to be cancelled when
+ * it is not in the driver code. */
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
hashes = drv->scanhash(mythr, work, work->blk.nonce + max_nonce);
thread_reportin(mythr);
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ pthread_testcancel();
/* tv_end is == &getwork_start */
cgtime(&getwork_start);
@@ -5909,8 +5906,6 @@ void *miner_thread(void *userdata)
struct device_drv *drv = cgpu->drv;
char threadname[24];
- pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
-
snprintf(threadname, 24, "miner/%d", thr_id);
RenameThread(threadname);