Browse Source

Merge commit '1ac2181' into bfgminer

Conflicts:
	api.c
Luke Dashjr 11 years ago
parent
commit
1113dc24fc
1 changed files with 40 additions and 21 deletions
  1. 40 21
      api.c

+ 40 - 21
api.c

@@ -3510,6 +3510,25 @@ static void send_result(struct io_data *io_data, SOCKETTYPE c, bool isjson)
 		       (long)bytes_len(&io_data->data));
 		       (long)bytes_len(&io_data->data));
 }
 }
 
 
+static
+void _tidyup_socket(SOCKETTYPE * const sockp)
+{
+	if (*sockp != INVSOCK) {
+		shutdown(*sockp, SHUT_RDWR);
+		CLOSESOCKET(*sockp);
+		*sockp = INVSOCK;
+		free(sockp);
+	}
+}
+
+static
+void tidyup_socket(void * const arg)
+{
+	mutex_lock(&quit_restart_lock);
+	_tidyup_socket(arg);
+	mutex_unlock(&quit_restart_lock);
+}
+
 static void tidyup(__maybe_unused void *arg)
 static void tidyup(__maybe_unused void *arg)
 {
 {
 	mutex_lock(&quit_restart_lock);
 	mutex_lock(&quit_restart_lock);
@@ -3518,12 +3537,7 @@ static void tidyup(__maybe_unused void *arg)
 
 
 	bye = true;
 	bye = true;
 
 
-	if (*apisock != INVSOCK) {
-		shutdown(*apisock, SHUT_RDWR);
-		CLOSESOCKET(*apisock);
-		*apisock = INVSOCK;
-		free(apisock);
-	}
+	_tidyup_socket(apisock);
 
 
 	if (ipaccess != NULL) {
 	if (ipaccess != NULL) {
 		free(ipaccess);
 		free(ipaccess);
@@ -3839,7 +3853,7 @@ static void mcast()
 	struct sockaddr_in came_from;
 	struct sockaddr_in came_from;
 	struct timeval bindstart;
 	struct timeval bindstart;
 	const char *binderror;
 	const char *binderror;
-	SOCKETTYPE mcast_sock;
+	SOCKETTYPE *mcastsock;
 	SOCKETTYPE reply_sock;
 	SOCKETTYPE reply_sock;
 	socklen_t came_from_siz;
 	socklen_t came_from_siz;
 	char *connectaddr;
 	char *connectaddr;
@@ -3862,10 +3876,14 @@ static void mcast()
 		quit(1, "Invalid Multicast Address");
 		quit(1, "Invalid Multicast Address");
 	grp.imr_interface.s_addr = INADDR_ANY;
 	grp.imr_interface.s_addr = INADDR_ANY;
 
 
-	mcast_sock = socket(AF_INET, SOCK_DGRAM, 0);
+	mcastsock = malloc(sizeof(*mcastsock));
+	*mcastsock = INVSOCK;
+	pthread_cleanup_push(tidyup_socket, mcastsock);
+	
+	*mcastsock = socket(AF_INET, SOCK_DGRAM, 0);
 
 
 	int optval = 1;
 	int optval = 1;
-	if (SOCKETFAIL(setsockopt(mcast_sock, SOL_SOCKET, SO_REUSEADDR, (void *)(&optval), sizeof(optval)))) {
+	if (SOCKETFAIL(setsockopt(*mcastsock, SOL_SOCKET, SO_REUSEADDR, (void *)(&optval), sizeof(optval)))) {
 		applog(LOG_ERR, "API mcast setsockopt SO_REUSEADDR failed (%s)%s", SOCKERRMSG, MUNAVAILABLE);
 		applog(LOG_ERR, "API mcast setsockopt SO_REUSEADDR failed (%s)%s", SOCKERRMSG, MUNAVAILABLE);
 		goto die;
 		goto die;
 	}
 	}
@@ -3879,7 +3897,7 @@ static void mcast()
 	bound = 0;
 	bound = 0;
 	timer_set_now(&bindstart);
 	timer_set_now(&bindstart);
 	while (bound == 0) {
 	while (bound == 0) {
-		if (SOCKETFAIL(bind(mcast_sock, (struct sockaddr *)(&listen), sizeof(listen)))) {
+		if (SOCKETFAIL(bind(*mcastsock, (struct sockaddr *)(&listen), sizeof(listen)))) {
 			binderror = SOCKERRMSG;
 			binderror = SOCKERRMSG;
 			if (timer_elapsed(&bindstart, NULL) > 61)
 			if (timer_elapsed(&bindstart, NULL) > 61)
 				break;
 				break;
@@ -3894,7 +3912,7 @@ static void mcast()
 		goto die;
 		goto die;
 	}
 	}
 
 
-	if (SOCKETFAIL(setsockopt(mcast_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)(&grp), sizeof(grp)))) {
+	if (SOCKETFAIL(setsockopt(*mcastsock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)(&grp), sizeof(grp)))) {
 		applog(LOG_ERR, "API mcast join failed (%s)%s", SOCKERRMSG, MUNAVAILABLE);
 		applog(LOG_ERR, "API mcast join failed (%s)%s", SOCKERRMSG, MUNAVAILABLE);
 		goto die;
 		goto die;
 	}
 	}
@@ -3911,10 +3929,10 @@ static void mcast()
 
 
 		count++;
 		count++;
 		came_from_siz = sizeof(came_from);
 		came_from_siz = sizeof(came_from);
-		if (SOCKETFAIL(rep = recvfrom(mcast_sock, buf, sizeof(buf) - 1,
+		if (SOCKETFAIL(rep = recvfrom(*mcastsock, buf, sizeof(buf) - 1,
 						0, (struct sockaddr *)(&came_from), &came_from_siz))) {
 						0, (struct sockaddr *)(&came_from), &came_from_siz))) {
 			applog(LOG_DEBUG, "API mcast failed count=%d (%s) (%d)",
 			applog(LOG_DEBUG, "API mcast failed count=%d (%s) (%d)",
-					count, SOCKERRMSG, (int)mcast_sock);
+					count, SOCKERRMSG, (int)*mcastsock);
 			continue;
 			continue;
 		}
 		}
 
 
@@ -3961,6 +3979,7 @@ static void mcast()
 								replybuf, (int)rep, (int)reply_sock);
 								replybuf, (int)rep, (int)reply_sock);
 				}
 				}
 
 
+				shutdown(reply_sock, SHUT_RDWR);
 				CLOSESOCKET(reply_sock);
 				CLOSESOCKET(reply_sock);
 			}
 			}
 		} else
 		} else
@@ -3968,8 +3987,8 @@ static void mcast()
 	}
 	}
 
 
 die:
 die:
-
-	CLOSESOCKET(mcast_sock);
+	;  // statement in case pthread_cleanup_pop doesn't start with one
+	pthread_cleanup_pop(true);
 }
 }
 
 
 static void *mcast_thread(void *userdata)
 static void *mcast_thread(void *userdata)
@@ -4048,14 +4067,14 @@ void api(int api_thr_id)
 
 
 		if (ips == 0) {
 		if (ips == 0) {
 			applog(LOG_WARNING, "API not running (no valid IPs specified)%s", UNAVAILABLE);
 			applog(LOG_WARNING, "API not running (no valid IPs specified)%s", UNAVAILABLE);
-			return;
+			pthread_exit(NULL);
 		}
 		}
 	}
 	}
 
 
 	*apisock = socket(AF_INET, SOCK_STREAM, 0);
 	*apisock = socket(AF_INET, SOCK_STREAM, 0);
 	if (*apisock == INVSOCK) {
 	if (*apisock == INVSOCK) {
 		applog(LOG_ERR, "API1 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE);
 		applog(LOG_ERR, "API1 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE);
-		return;
+		pthread_exit(NULL);
 	}
 	}
 
 
 	memset(&serv, 0, sizeof(serv));
 	memset(&serv, 0, sizeof(serv));
@@ -4066,7 +4085,7 @@ void api(int api_thr_id)
 		serv.sin_addr.s_addr = inet_addr(localaddr);
 		serv.sin_addr.s_addr = inet_addr(localaddr);
 		if (serv.sin_addr.s_addr == (in_addr_t)INVINETADDR) {
 		if (serv.sin_addr.s_addr == (in_addr_t)INVINETADDR) {
 			applog(LOG_ERR, "API2 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE);
 			applog(LOG_ERR, "API2 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE);
-			return;
+			pthread_exit(NULL);
 		}
 		}
 	}
 	}
 
 
@@ -4104,13 +4123,12 @@ void api(int api_thr_id)
 
 
 	if (bound == 0) {
 	if (bound == 0) {
 		applog(LOG_ERR, "API bind to port %d failed (%s)%s", port, binderror, UNAVAILABLE);
 		applog(LOG_ERR, "API bind to port %d failed (%s)%s", port, binderror, UNAVAILABLE);
-		return;
+		pthread_exit(NULL);
 	}
 	}
 
 
 	if (SOCKETFAIL(listen(*apisock, QUEUE))) {
 	if (SOCKETFAIL(listen(*apisock, QUEUE))) {
 		applog(LOG_ERR, "API3 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE);
 		applog(LOG_ERR, "API3 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE);
-		CLOSESOCKET(*apisock);
-		return;
+		pthread_exit(NULL);
 	}
 	}
 
 
 	if (opt_api_allow)
 	if (opt_api_allow)
@@ -4297,6 +4315,7 @@ inochi:
 					send_result(io_data, c, isjson);
 					send_result(io_data, c, isjson);
 			}
 			}
 		}
 		}
+		shutdown(c, SHUT_RDWR);
 		CLOSESOCKET(c);
 		CLOSESOCKET(c);
 	}
 	}
 die:
 die: