From e4effc372ca20170b12d6b555120ea266ba1f383 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Mon, 15 Apr 2013 12:01:24 +1000 Subject: [PATCH] Avoid applog under stratum_lock in __stratum_send. --- util.c | 52 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/util.c b/util.c index 61233a8d..5e221049 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; }