Browse Source

Simplify longpoll changeover to just check which pool it should grab its next longpoll from. This should prevent locking hangs and thread cancellation
crashes.

Con Kolivas 14 years ago
parent
commit
2257b5023a
3 changed files with 28 additions and 40 deletions
  1. 28 34
      main.c
  2. 0 1
      miner.h
  3. 0 5
      util.c

+ 28 - 34
main.c

@@ -2732,8 +2732,6 @@ static struct pool *priority_pool(int choice)
 	return ret;
 	return ret;
 }
 }
 
 
-static void restart_longpoll(void);
-
 static void switch_pools(struct pool *selected)
 static void switch_pools(struct pool *selected)
 {
 {
 	struct pool *pool, *last_pool;
 	struct pool *pool, *last_pool;
@@ -2786,12 +2784,8 @@ static void switch_pools(struct pool *selected)
 	pool = currentpool;
 	pool = currentpool;
 	mutex_unlock(&control_lock);
 	mutex_unlock(&control_lock);
 
 
-	if (pool != last_pool) {
+	if (pool != last_pool)
 		applog(LOG_WARNING, "Switching to %s", pool->rpc_url);
 		applog(LOG_WARNING, "Switching to %s", pool->rpc_url);
-		/* Only switch longpoll if the new pool also supports LP */
-		if (pool->hdr_path)
-			restart_longpoll();
-	}
 
 
 	/* Reset the queued amount to allow more to be queued for the new pool */
 	/* Reset the queued amount to allow more to be queued for the new pool */
 	mutex_lock(&qd_lock);
 	mutex_lock(&qd_lock);
@@ -3395,6 +3389,9 @@ retry:
 	opt_loginput = false;
 	opt_loginput = false;
 }
 }
 
 
+static void start_longpoll(void);
+static void stop_longpoll(void);
+
 static void set_options(void)
 static void set_options(void)
 {
 {
 	int selected;
 	int selected;
@@ -3421,7 +3418,11 @@ retry:
 	} else if (!strncasecmp(&input, "l", 1)) {
 	} else if (!strncasecmp(&input, "l", 1)) {
 		want_longpoll ^= true;
 		want_longpoll ^= true;
 		applog(LOG_WARNING, "Longpoll %s", want_longpoll ? "enabled" : "disabled");
 		applog(LOG_WARNING, "Longpoll %s", want_longpoll ? "enabled" : "disabled");
-		restart_longpoll();
+		if (!want_longpoll) {
+			if (have_longpoll)
+				stop_longpoll();
+		} else
+			start_longpoll();
 		goto retry;
 		goto retry;
 	} else if  (!strncasecmp(&input, "s", 1)) {
 	} else if  (!strncasecmp(&input, "s", 1)) {
 		selected = curses_int("Set scantime in seconds");
 		selected = curses_int("Set scantime in seconds");
@@ -4898,12 +4899,15 @@ static struct pool *select_longpoll_pool(void)
 
 
 static void *longpoll_thread(void *userdata)
 static void *longpoll_thread(void *userdata)
 {
 {
-	struct thr_info *mythr = userdata;
-	CURL *curl = NULL;
 	char *copy_start, *hdr_path, *lp_url = NULL;
 	char *copy_start, *hdr_path, *lp_url = NULL;
+	struct thr_info *mythr = userdata;
+	struct timeval start, end;
 	bool need_slash = false;
 	bool need_slash = false;
+	struct pool *sp, *pool;
+	CURL *curl = NULL;
 	int failures = 0;
 	int failures = 0;
-	struct pool *pool;
+	bool rolltime;
+	json_t *val;
 
 
 	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
 	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
 	pthread_detach(pthread_self());
 	pthread_detach(pthread_self());
@@ -4915,7 +4919,9 @@ static void *longpoll_thread(void *userdata)
 	}
 	}
 
 
 	tq_pop(mythr->q, NULL);
 	tq_pop(mythr->q, NULL);
+
 	pool = select_longpoll_pool();
 	pool = select_longpoll_pool();
+new_longpoll:
 	if (!pool->hdr_path) {
 	if (!pool->hdr_path) {
 		applog(LOG_WARNING, "No long-poll found on any pool server");
 		applog(LOG_WARNING, "No long-poll found on any pool server");
 		goto out;
 		goto out;
@@ -4926,15 +4932,13 @@ static void *longpoll_thread(void *userdata)
 	if (strstr(hdr_path, "://")) {
 	if (strstr(hdr_path, "://")) {
 		lp_url = hdr_path;
 		lp_url = hdr_path;
 		hdr_path = NULL;
 		hdr_path = NULL;
-	}
-
-	/* absolute path, on current server */
-	else {
+	} else {
+		/* absolute path, on current server */
 		copy_start = (*hdr_path == '/') ? (hdr_path + 1) : hdr_path;
 		copy_start = (*hdr_path == '/') ? (hdr_path + 1) : hdr_path;
 		if (pool->rpc_url[strlen(pool->rpc_url) - 1] != '/')
 		if (pool->rpc_url[strlen(pool->rpc_url) - 1] != '/')
 			need_slash = true;
 			need_slash = true;
 
 
-		lp_url = alloca(strlen(pool->rpc_url) + strlen(copy_start) + 2);
+		lp_url = malloc(strlen(pool->rpc_url) + strlen(copy_start) + 2);
 		if (!lp_url)
 		if (!lp_url)
 			goto out;
 			goto out;
 
 
@@ -4945,10 +4949,6 @@ static void *longpoll_thread(void *userdata)
 	applog(LOG_WARNING, "Long-polling activated for %s", lp_url);
 	applog(LOG_WARNING, "Long-polling activated for %s", lp_url);
 
 
 	while (1) {
 	while (1) {
-		struct timeval start, end;
-		bool rolltime;
-		json_t *val;
-
 		gettimeofday(&start, NULL);
 		gettimeofday(&start, NULL);
 		val = json_rpc_call(curl, lp_url, pool->rpc_userpass, rpc_req,
 		val = json_rpc_call(curl, lp_url, pool->rpc_userpass, rpc_req,
 				    false, true, &rolltime, pool);
 				    false, true, &rolltime, pool);
@@ -4965,26 +4965,28 @@ static void *longpoll_thread(void *userdata)
 			if (end.tv_sec - start.tv_sec > 30)
 			if (end.tv_sec - start.tv_sec > 30)
 				continue;
 				continue;
 			if (opt_retries == -1 || failures++ < opt_retries) {
 			if (opt_retries == -1 || failures++ < opt_retries) {
-				sleep(30);
 				applog(LOG_WARNING,
 				applog(LOG_WARNING,
 					"longpoll failed for %s, sleeping for 30s", lp_url);
 					"longpoll failed for %s, sleeping for 30s", lp_url);
+				sleep(30);
 			} else {
 			} else {
 				applog(LOG_ERR,
 				applog(LOG_ERR,
 					"longpoll failed for %s, ending thread", lp_url);
 					"longpoll failed for %s, ending thread", lp_url);
 				goto out;
 				goto out;
 			}
 			}
 		}
 		}
+		sp = select_longpoll_pool();
+		if (sp != pool) {
+			if (likely(lp_url))
+				free(lp_url);
+			pool = sp;
+			goto new_longpoll;
+		}
 	}
 	}
 
 
 out:
 out:
 	if (curl)
 	if (curl)
 		curl_easy_cleanup(curl);
 		curl_easy_cleanup(curl);
 
 
-	/* Wait indefinitely if longpoll is flagged as existing, thus making
-	 * this thread only die if killed from elsewhere, usually in
-	 * thr_info_cancel */
-	if (have_longpoll)
-		tq_pop(mythr->q, NULL);
 	tq_freeze(mythr->q);
 	tq_freeze(mythr->q);
 	return NULL;
 	return NULL;
 }
 }
@@ -5010,14 +5012,6 @@ static void start_longpoll(void)
 	tq_push(thr_info[longpoll_thr_id].q, &ping);
 	tq_push(thr_info[longpoll_thr_id].q, &ping);
 }
 }
 
 
-static void restart_longpoll(void)
-{
-	if (have_longpoll)
-		stop_longpoll();
-	if (want_longpoll)
-		start_longpoll();
-}
-
 static void *reinit_cpu(void *userdata)
 static void *reinit_cpu(void *userdata)
 {
 {
 	pthread_detach(pthread_self());
 	pthread_detach(pthread_self());

+ 0 - 1
miner.h

@@ -453,7 +453,6 @@ extern int total_getworks, total_stale, total_discarded;
 extern unsigned int local_work;
 extern unsigned int local_work;
 extern unsigned int total_go, total_ro;
 extern unsigned int total_go, total_ro;
 extern int opt_log_interval;
 extern int opt_log_interval;
-extern pthread_mutex_t control_lock;
 
 
 #ifdef HAVE_OPENCL
 #ifdef HAVE_OPENCL
 typedef struct {
 typedef struct {

+ 0 - 5
util.c

@@ -669,9 +669,7 @@ int thr_info_create(struct thr_info *thr, pthread_attr_t *attr, void *(*start) (
 {
 {
 	int ret;
 	int ret;
 
 
-	mutex_lock(&control_lock);
 	ret = pthread_create(&thr->pth, attr, start, arg);
 	ret = pthread_create(&thr->pth, attr, start, arg);
-	mutex_unlock(&control_lock);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -683,14 +681,11 @@ void thr_info_cancel(struct thr_info *thr)
 	if (thr->q)
 	if (thr->q)
 		tq_freeze(thr->q);
 		tq_freeze(thr->q);
 
 
-	/* control_lock protects thr->pth */
-	mutex_lock(&control_lock);
 	if (thr->pth) {
 	if (thr->pth) {
 			if (!pthread_cancel(thr->pth))
 			if (!pthread_cancel(thr->pth))
 				pthread_join(thr->pth, NULL);
 				pthread_join(thr->pth, NULL);
 			thr->pth = 0L;
 			thr->pth = 0L;
 	}
 	}
-	mutex_unlock(&control_lock);
 }
 }
 
 
 bool get_dondata(char **url, char **userpass)
 bool get_dondata(char **url, char **userpass)