Prune old stratum shares that we've seen no response for over 2 minutes to avoid memory leaks for pools that don't respond about some shares.
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 cccb18f..0685d50 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -7411,6 +7411,34 @@ static void reap_curl(struct pool *pool)
applog(LOG_DEBUG, "Reaped %d curl%s from pool %d", reaped, reaped > 1 ? "s" : "", pool->pool_no);
}
+/* Prune old shares we haven't had a response about for over 2 minutes in case
+ * the pool never plans to respond and we're just leaking memory. If we get a
+ * response beyond that time they will be seen as untracked shares. */
+static void prune_stratum_shares(struct pool *pool)
+{
+ struct stratum_share *sshare, *tmpshare;
+ time_t current_time = time(NULL);
+ int cleared = 0;
+
+ mutex_lock(&sshare_lock);
+ HASH_ITER(hh, stratum_shares, sshare, tmpshare) {
+ if (sshare->work->pool == pool && current_time > sshare->sshare_time + 120) {
+ HASH_DEL(stratum_shares, sshare);
+ free_work(sshare->work);
+ free(sshare);
+ cleared++;
+ }
+ }
+ mutex_unlock(&sshare_lock);
+
+ if (cleared) {
+ applog(LOG_WARNING, "Lost %d shares due to no stratum share response from pool %d",
+ cleared, pool->pool_no);
+ pool->stale_shares += cleared;
+ total_stale += cleared;
+ }
+}
+
static void *watchpool_thread(void __maybe_unused *userdata)
{
int intervals = 0;
@@ -7432,8 +7460,10 @@ static void *watchpool_thread(void __maybe_unused *userdata)
for (i = 0; i < total_pools; i++) {
struct pool *pool = pools[i];
- if (!opt_benchmark && !opt_benchfile)
+ if (!opt_benchmark && !opt_benchfile) {
reap_curl(pool);
+ prune_stratum_shares(pool);
+ }
/* Get a rolling utility per pool over 10 mins */
if (intervals > 19) {