Use the stratum thread to detect when a stratum pool has died based on no message for 2 minutes.
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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
diff --git a/cgminer.c b/cgminer.c
index 3e19028..a486bac 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -4134,6 +4134,8 @@ out:
return ret;
}
+static void pool_resus(struct pool *pool);
+
/* One stratum thread per pool that has stratum waits on the socket checking
* for new messages and for the integrity of the socket connection. We reset
* the connection based on the integrity of the receive side only as the send
@@ -4145,24 +4147,36 @@ static void *stratum_thread(void *userdata)
pthread_detach(pthread_self());
while (42) {
+ struct timeval timeout;
fd_set rd;
char *s;
+ if (unlikely(pool->removed))
+ break;
+
FD_ZERO(&rd);
FD_SET(pool->sock, &rd);
-
- if (select(pool->sock + 1, &rd, NULL, NULL, NULL) < 0) {
- pool->stratum_active = false;
- applog(LOG_WARNING, "Stratum connection to pool %d interrupted", pool->pool_no);
+ timeout.tv_sec = 120;
+ timeout.tv_usec = 0;
+
+ /* The protocol specifies that notify messages should be sent
+ * every minute so if we fail to receive any for 2 minutes we
+ * assume the connection has been dropped and treat this pool
+ * as dead */
+ if (select(pool->sock + 1, &rd, NULL, NULL, &timeout) < 1) {
+ applog(LOG_INFO, "Stratum connection to pool %d interrupted", pool->pool_no);
pool->getfail_occasions++;
total_go++;
+
+ pool_died(pool);
while (!initiate_stratum(pool) || !auth_stratum(pool)) {
- if (!pool->idle)
- pool_died(pool);
if (pool->removed)
goto out;
sleep(5);
}
+ applog(LOG_INFO, "Stratum connection to pool %d resumed", pool->pool_no);
+ pool_resus(pool);
+ continue;
}
s = recv_line(pool);
if (unlikely(!s))
@@ -4188,10 +4202,6 @@ static void *stratum_thread(void *userdata)
applog(LOG_NOTICE, "Stratum from pool %d detected new block", pool->pool_no);
}
- if (unlikely(pool->removed)) {
- CLOSESOCKET(pool->sock);
- goto out;
- }
}
out:
@@ -4241,6 +4251,7 @@ retry_stratum:
return false;
if (!auth_stratum(pool))
return false;
+ pool->idle = false;
init_stratum_thread(pool);
return true;
}
@@ -4527,6 +4538,9 @@ static void set_work_target(struct work *work, int diff)
memcpy(work->target, target, 32);
}
+/* Generates stratum based work based on the most recent notify information
+ * from the pool. This will keep generating work while a pool is down so we use
+ * other means to detect when the pool has died in stratum_thread */
static void gen_stratum_work(struct pool *pool, struct work *work)
{
unsigned char *coinbase, merkle_root[33], merkle_sha[65], *merkle_hash;
@@ -5256,7 +5270,8 @@ static void *watchpool_thread(void __maybe_unused *userdata)
if (!opt_benchmark)
reap_curl(pool);
- if (pool->enabled == POOL_DISABLED)
+
+ if (pool->enabled == POOL_DISABLED || pool->has_stratum)
continue;
/* Test pool is idle once every minute */