From 042360bf400864a3746536ba5f9d0ca7efebb499 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 6 Feb 2015 21:35:48 +1100 Subject: [PATCH 1/4] Don't try to act on inactive clients --- src/stratifier.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 0f01e42e..889a22db 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -1331,6 +1331,11 @@ out: return ret; } +static inline bool client_active(stratum_instance_t *client) +{ + return (client->authorised && !client->dropped); +} + /* For creating a list of sends without locking that can then be concatenated * to the stratum_sends list. Minimises locking and avoids taking recursive * locks. */ @@ -1350,7 +1355,7 @@ static void stratum_broadcast(sdata_t *sdata, json_t *val) ckmsg_t *client_msg; smsg_t *msg; - if (!client->authorised) + if (!client_active(client)) continue; client_msg = ckalloc(sizeof(ckmsg_t)); msg = ckzalloc(sizeof(smsg_t)); @@ -3255,7 +3260,7 @@ static void suggest_diff(stratum_instance_t *client, const char *method, const j sdata_t *sdata = client->ckp->data; int64_t sdiff; - if (unlikely(!client->authorised)) { + if (unlikely(!client_active(client))) { LOGWARNING("Attempted to suggest diff on unauthorised client %"PRId64, client->id); return; } @@ -3954,7 +3959,7 @@ static void *statsupdate(void *arg) ck_rlock(&sdata->instance_lock); HASH_ITER(hh, sdata->stratum_instances, client, tmp) { - if (!client->authorised) + if (!client_active(client)) continue; per_tdiff = tvdiff(&now, &client->last_share); From 8b1b6d45d645449fdf8263629e7eee4baa8bfc8f Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 8 Feb 2015 13:02:50 +1100 Subject: [PATCH 2/4] fd being invalidated is checked for in wait_write_select so we don't need to handle it twice --- src/connector.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/connector.c b/src/connector.c index 950dd26c..9d053dba 100644 --- a/src/connector.c +++ b/src/connector.c @@ -506,10 +506,6 @@ void *sender(void *arg) fd = client->fd; ck_runlock(&cdata->lock); - if (fd == -1) { - LOGDEBUG("Discarding message sent to invalidated client"); - goto contfree; - } /* If this socket is not ready to receive data from us, put the * send back on the tail of the list and decrease the timeout * to poll to either look for a client that is ready or poll From 163fc40afbbe53201e40cd8a8855f09a7bf8acd9 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 8 Feb 2015 13:27:33 +1100 Subject: [PATCH 3/4] Check all delayed clients for a serviceable one in the connector when we can and consider dropping a client servicing one to not potentially create delayed sends faster than we service them --- src/connector.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/connector.c b/src/connector.c index 9d053dba..135da0bb 100644 --- a/src/connector.c +++ b/src/connector.c @@ -466,17 +466,17 @@ void *sender(void *arg) rename_proc("csender"); while (42) { - sender_send_t *sender_send; + sender_send_t *sender_send, *delayed; client_instance_t *client; - int ret, fd, ofs = 0; + int ret = 0, fd, ofs = 0; mutex_lock(&cdata->sender_lock); - /* Poll every 100ms if there are no new sends. Re-examine + /* Poll every 10ms if there are no new sends. Re-examine * delayed sends immediately after a successful send in case * endless new sends more frequently end up starving the * delayed sends. */ if (!cdata->sender_sends && !sent) { - const ts_t polltime = {0, 100000000}; + const ts_t polltime = {0, 10000000}; ts_t timeout_ts; ts_realtime(&timeout_ts); @@ -494,23 +494,33 @@ void *sender(void *arg) * conditional with no new sends appearing or have just * serviced another message successfully. */ if (!sender_send) { - if (!cdata->delayed_sends) + /* Find a delayed client that needs servicing and set + * ret accordingly. We do not need to use FOREACH_SAFE + * as we break out of the loop as soon as we manipuate + * the list. */ + DL_FOREACH(cdata->delayed_sends, delayed) { + if ((ret = wait_write_select(delayed->client->fd, 0))) { + sender_send = cdata->delayed_sends; + DL_DELETE(cdata->delayed_sends, sender_send); + break; + } + } + /* None found ? */ + if (!sender_send) continue; - sender_send = cdata->delayed_sends; - DL_DELETE(cdata->delayed_sends, sender_send); } - client = sender_send->client; - ck_rlock(&cdata->lock); - fd = client->fd; - ck_runlock(&cdata->lock); - /* If this socket is not ready to receive data from us, put the * send back on the tail of the list and decrease the timeout * to poll to either look for a client that is ready or poll * select on this one */ - ret = wait_write_select(fd, 0); + ck_rlock(&cdata->lock); + fd = client->fd; + if (!ret) + ret = wait_write_select(fd, 0); + ck_runlock(&cdata->lock); + if (ret < 1) { if (ret < 0) { LOGINFO("Client id %"PRId64" fd %d interrupted", client->id, fd); @@ -526,7 +536,6 @@ void *sender(void *arg) cdata->sends_delayed++; continue; } - sent = true; while (sender_send->len) { ret = send(fd, sender_send->buf + ofs, sender_send->len , 0); if (unlikely(ret < 0)) { @@ -538,6 +547,7 @@ void *sender(void *arg) sender_send->len -= ret; } contfree: + sent = true; free(sender_send->buf); free(sender_send); dec_instance_ref(cdata, client); From 3ed9f9757b0b8b66c1e2bf32dbdbc993fb87991e Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 8 Feb 2015 19:02:23 +1100 Subject: [PATCH 4/4] Push version to 0.8.6 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d99cf945..49d28ee2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(ckpool, 0.8.5, kernel@kolivas.org) +AC_INIT(ckpool, 0.8.6, kernel@kolivas.org) AC_CANONICAL_SYSTEM AC_CONFIG_MACRO_DIR([m4])