Avoid applog under stratum_lock in __stratum_send.
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
diff --git a/util.c b/util.c
index 61233a8..5e22104 100644
--- a/util.c
+++ b/util.c
@@ -892,16 +892,20 @@ bool extract_sockaddr(struct pool *pool, char *url)
return true;
}
+enum send_ret {
+ SEND_OK,
+ SEND_SELECTFAIL,
+ SEND_SENDFAIL,
+ SEND_INACTIVE
+};
+
/* Send a single command across a socket, appending \n to it. This should all
* be done under stratum lock except when first establishing the socket */
-static bool __stratum_send(struct pool *pool, char *s, ssize_t len)
+static enum send_ret __stratum_send(struct pool *pool, char *s, ssize_t len)
{
SOCKETTYPE sock = pool->sock;
ssize_t ssent = 0;
- if (opt_protocol)
- applog(LOG_DEBUG, "SEND: %s", s);
-
strcat(s, "\n");
len++;
@@ -912,16 +916,12 @@ static bool __stratum_send(struct pool *pool, char *s, ssize_t len)
FD_ZERO(&wd);
FD_SET(sock, &wd);
- if (select(sock + 1, NULL, &wd, NULL, &timeout) < 1) {
- applog(LOG_DEBUG, "Write select failed on pool %d sock", pool->pool_no);
- return false;
- }
+ if (select(sock + 1, NULL, &wd, NULL, &timeout) < 1)
+ return SEND_SELECTFAIL;
sent = send(pool->sock, s + ssent, len, 0);
if (sent < 0) {
- if (errno != EAGAIN && errno != EWOULDBLOCK) {
- applog(LOG_DEBUG, "Failed to curl_easy_send in stratum_send");
- return false;
- }
+ if (errno != EAGAIN && errno != EWOULDBLOCK)
+ return SEND_SENDFAIL;
sent = 0;
}
ssent += sent;
@@ -931,21 +931,37 @@ static bool __stratum_send(struct pool *pool, char *s, ssize_t len)
pool->cgminer_pool_stats.times_sent++;
pool->cgminer_pool_stats.bytes_sent += ssent;
pool->cgminer_pool_stats.net_bytes_sent += ssent;
- return true;
+ return SEND_OK;
}
bool stratum_send(struct pool *pool, char *s, ssize_t len)
{
- bool ret = false;
+ enum send_ret ret = SEND_INACTIVE;
+
+ if (opt_protocol)
+ applog(LOG_DEBUG, "SEND: %s", s);
mutex_lock(&pool->stratum_lock);
if (pool->stratum_active)
ret = __stratum_send(pool, s, len);
- else
- applog(LOG_DEBUG, "Stratum send failed due to no pool stratum_active");
mutex_unlock(&pool->stratum_lock);
- return ret;
+ /* This is to avoid doing applog under stratum_lock */
+ switch (ret) {
+ default:
+ case SEND_OK:
+ break;
+ case SEND_SELECTFAIL:
+ applog(LOG_DEBUG, "Write select failed on pool %d sock", pool->pool_no);
+ break;
+ case SEND_SENDFAIL:
+ applog(LOG_DEBUG, "Failed to curl_easy_send in stratum_send");
+ break;
+ case SEND_INACTIVE:
+ applog(LOG_DEBUG, "Stratum send failed due to no pool stratum_active");
+ break;
+ }
+ return (ret == SEND_OK);
}
static bool socket_full(struct pool *pool, bool wait)
@@ -1557,7 +1573,7 @@ resend:
sprintf(s, "{\"id\": %d, \"method\": \"mining.subscribe\", \"params\": [\""PACKAGE"/"VERSION"\"]}", swork_id++);
}
- if (!__stratum_send(pool, s, strlen(s))) {
+ if (__stratum_send(pool, s, strlen(s)) != SEND_OK) {
applog(LOG_DEBUG, "Failed to send s in initiate_stratum");
goto out;
}