Commit 648be96f30f5a73c47f78d2e7e34aaa16dd8b168

Con Kolivas 2014-02-18T20:50:45

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.

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) {