Browse Source

Use a mutex to block pool_active on a common check per pool at any given time

Luke Dashjr 11 years ago
parent
commit
3a3d3c3994
3 changed files with 42 additions and 14 deletions
  1. 39 14
      miner.c
  2. 1 0
      miner.h
  3. 2 0
      util.c

+ 39 - 14
miner.c

@@ -1044,6 +1044,7 @@ struct pool *add_pool(void)
 	pool->pool_no = pool->prio = total_pools;
 	mutex_init(&pool->last_work_lock);
 	mutex_init(&pool->pool_lock);
+	mutex_init(&pool->pool_test_lock);
 	if (unlikely(pthread_cond_init(&pool->cr_cond, NULL)))
 		quit(1, "Failed to pthread_cond_init in add_pool");
 	cglock_init(&pool->data_lock);
@@ -8441,6 +8442,8 @@ static bool supports_resume(struct pool *pool)
 	return ret;
 }
 
+static bool pools_active;
+
 /* 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
@@ -8478,7 +8481,7 @@ static void *stratum_thread(void *userdata)
 				applog(LOG_DEBUG, "Pool %u: Invalid socket, suspending",
 				       pool->pool_no);
 			else
-			if (!sock_full(pool) && !cnx_needed(pool))
+			if (!sock_full(pool) && !cnx_needed(pool) && pools_active)
 				applog(LOG_DEBUG, "Pool %u: Connection not needed, suspending",
 				       pool->pool_no);
 			else
@@ -8636,24 +8639,46 @@ static bool pool_active(struct pool *pool, bool pinging)
 	struct timeval tv_now, tv_getwork, tv_getwork_reply;
 	bool ret = false;
 	json_t *val;
-	CURL *curl;
+	CURL *curl = NULL;
 	int rolltime;
 	char *rpc_req;
 	struct work *work;
 	enum pool_protocol proto;
 
 	if (pool->stratum_init)
-		return pool->stratum_active;
+	{
+		if (pool->stratum_active)
+			return true;
+	}
+	else
+	if (!pool->idle)
+	{
+		timer_set_now(&tv_now);
+		if (pool_recently_got_work(pool, &tv_now))
+			return true;
+	}
+	
+	mutex_lock(&pool->pool_test_lock);
+	
+	if (pool->stratum_init)
+	{
+		ret = pool->stratum_active;
+		goto out;
+	}
 	
 	timer_set_now(&tv_now);
+	
 	if (pool->idle)
 	{
 		if (timer_elapsed(&pool->tv_idle, &tv_now) < 30)
-			return false;
+			goto out;
 	}
 	else
 	if (pool_recently_got_work(pool, &tv_now))
-		return true;
+	{
+		ret = true;
+		goto out;
+	}
 	
 		applog(LOG_INFO, "Testing pool %s", pool->rpc_url);
 
@@ -8661,7 +8686,7 @@ static bool pool_active(struct pool *pool, bool pinging)
 	curl = curl_easy_init();
 	if (unlikely(!curl)) {
 		applog(LOG_ERR, "CURL initialisation failed");
-		return false;
+		goto out;
 	}
 
 	if (!(want_gbt || want_getwork))
@@ -8703,8 +8728,7 @@ tryagain:
 			json_decref(val);
 
 retry_stratum:
-		curl_easy_cleanup(curl);
-		
+		;
 		/* We create the stratum thread for each pool just after
 		 * successful authorisation. Once the init flag has been set
 		 * we never unset it and the stratum thread is responsible for
@@ -8712,7 +8736,7 @@ retry_stratum:
 		bool init = pool_tset(pool, &pool->stratum_init);
 
 		if (!init) {
-			bool ret = initiate_stratum(pool) && auth_stratum(pool);
+			ret = initiate_stratum(pool) && auth_stratum(pool);
 
 			if (ret)
 			{
@@ -8724,9 +8748,10 @@ retry_stratum:
 				pool_tclear(pool, &pool->stratum_init);
 				pool->tv_idle = tv_getwork_reply;
 			}
-			return ret;
+			goto out;
 		}
-		return pool->stratum_active;
+		ret = pool->stratum_active;
+		goto out;
 	}
 	else if (pool->has_stratum)
 		shutdown_stratum(pool);
@@ -8830,7 +8855,9 @@ nohttp:
 			applog(LOG_WARNING, "Pool %u slow/down or URL or credentials invalid", pool->pool_no);
 	}
 out:
-	curl_easy_cleanup(curl);
+	if (curl)
+		curl_easy_cleanup(curl);
+	mutex_unlock(&pool->pool_test_lock);
 	return ret;
 }
 
@@ -10669,8 +10696,6 @@ char *curses_input(const char *query)
 }
 #endif
 
-static bool pools_active = false;
-
 static void *test_pool_thread(void *arg)
 {
 	struct pool *pool = (struct pool *)arg;

+ 1 - 0
miner.h

@@ -1271,6 +1271,7 @@ struct pool {
 	char *rpc_proxy;
 
 	pthread_mutex_t pool_lock;
+	pthread_mutex_t pool_test_lock;
 	cglock_t data_lock;
 
 	struct thread_q *submit_q;

+ 2 - 0
util.c

@@ -2859,12 +2859,14 @@ out:
 
 bool restart_stratum(struct pool *pool)
 {
+	mutex_lock(&pool->pool_test_lock);
 	if (pool->stratum_active)
 		suspend_stratum(pool);
 	if (!initiate_stratum(pool))
 		return false;
 	if (!auth_stratum(pool))
 		return false;
+	mutex_unlock(&pool->pool_test_lock);
 	return true;
 }