From 9dae34e3fa00740b6e9435bf98022cf8601d1acf Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 30 Oct 2014 14:34:32 +1100 Subject: [PATCH] Make update_base calls asynchronous to not hold up stratum loop messages and ping miners if we get no base to keep them mining --- src/stratifier.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 708ef31e..4d3cf5f3 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -721,24 +721,39 @@ static void send_generator(ckpool_t *ckp, const char *msg, int prio) gen_priority = 0; } +struct update_req { + pthread_t *pth; + ckpool_t *ckp; + int prio; +}; + +static void broadcast_ping(void); + /* This function assumes it will only receive a valid json gbt base template * since checking should have been done earlier, and creates the base template * for generating work templates. */ -static void update_base(ckpool_t *ckp, int prio) +static void *do_update(void *arg) { + struct update_req *ur = (struct update_req *)arg; + ckpool_t *ckp = ur->ckp; bool new_block = false; + int prio = ur->prio; + bool ret = false; workbase_t *wb; json_t *val; char *buf; + pthread_detach(pthread_self()); + rename_proc("updater"); + buf = send_recv_generator(ckp, "getbase", prio); if (unlikely(!buf)) { LOGWARNING("Failed to get base from generator in update_base"); - return; + goto out; } if (unlikely(cmdmatch(buf, "failed"))) { LOGWARNING("Generator returned failure in update_base"); - return; + goto out; } wb = ckzalloc(sizeof(workbase_t)); @@ -783,6 +798,29 @@ static void update_base(ckpool_t *ckp, int prio) add_base(ckp, wb, &new_block); stratum_broadcast_update(new_block); + ret = true; + LOGINFO("Broadcasted updated stratum base"); +out: + /* Send a ping to miners if we fail to get a base to keep them + * connected while bitcoind recovers(?) */ + if (!ret) { + LOGWARNING("Broadcasted ping due to failed stratum base update"); + broadcast_ping(); + } + free(ur->pth); + free(ur); + return NULL; +} + +static void update_base(ckpool_t *ckp, int prio) +{ + struct update_req *ur = ckalloc(sizeof(struct update_req)); + pthread_t *pth = ckalloc(sizeof(pthread_t)); + + ur->pth = pth; + ur->ckp = ckp; + ur->prio = prio; + create_pthread(pth, do_update, ur); } static void drop_allclients(ckpool_t *ckp)