Use the one curl instance for all gbt solo operations, protecting its use with a bool set under gbt lock.
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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
diff --git a/cgminer.c b/cgminer.c
index 0fa2500..0ea92ae 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -6438,6 +6438,9 @@ static bool setup_gbt_solo(CURL *curl, struct pool *pool)
applog(LOG_DEBUG, "Pool %d coinbase %s", pool->pool_no, cb);
free(cb);
}
+ pool->gbt_curl = curl_easy_init();
+ if (unlikely(!pool->gbt_curl))
+ quit(1, "GBT CURL initialisation failed");
out:
return ret;
@@ -6888,18 +6891,37 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
static void gen_solo_work(struct pool *pool, struct work *work);
+/* Use the one instance of gbt_curl, protecting the bool with the gbt_lock but
+ * avoiding holding the lock once we've set the bool. */
+static void get_gbt_curl(struct pool *pool, int poll)
+{
+ cg_wlock(&pool->gbt_lock);
+ while (pool->gbt_curl_inuse) {
+ cg_wunlock(&pool->gbt_lock);
+ cgsleep_ms(poll);
+ cg_wlock(&pool->gbt_lock);
+ }
+ pool->gbt_curl_inuse = true;
+ cg_wunlock(&pool->gbt_lock);
+}
+
+/* No need for locking here */
+static inline void release_gbt_curl(struct pool *pool)
+{
+ pool->gbt_curl_inuse = false;
+}
+
static void update_gbt_solo(struct pool *pool)
{
struct work *work = make_work();
int rolltime;
json_t *val;
- CURL *curl;
- curl = curl_easy_init();
- /* Bitcoind doesn't like many open RPC connections. */
- curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1);
+ get_gbt_curl(pool, 10);
retry:
- val = json_rpc_call(curl, pool->rpc_url, pool->rpc_userpass, pool->rpc_req,
+ /* Bitcoind doesn't like many open RPC connections. */
+ curl_easy_setopt(pool->gbt_curl, CURLOPT_FORBID_REUSE, 1);
+ val = json_rpc_call(pool->gbt_curl, pool->rpc_url, pool->rpc_userpass, pool->rpc_req,
true, false, &rolltime, pool, false);
if (likely(val)) {
@@ -6922,7 +6944,7 @@ retry:
goto retry;
}
out:
- curl_easy_cleanup(curl);
+ release_gbt_curl(pool);
}
static void gen_solo_work(struct pool *pool, struct work *work)
@@ -7872,12 +7894,6 @@ static void *longpoll_thread(void *userdata)
snprintf(threadname, sizeof(threadname), "%d/Longpoll", cp->pool_no);
RenameThread(threadname);
- curl = curl_easy_init();
- if (unlikely(!curl)) {
- applog(LOG_ERR, "CURL initialisation failed");
- return NULL;
- }
-
retry_pool:
pool = select_longpoll_pool(cp);
if (!pool) {
@@ -7901,17 +7917,20 @@ retry_pool:
json_t *val, *res_val = NULL;
if (unlikely(pool->removed))
- goto out;
+ return NULL;
- curl_easy_cleanup(curl);
- curl = curl_easy_init();
- /* Bitcoind doesn't like many open RPC connections. */
- curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1);
cgtime(&start);
wait_lpcurrent(cp);
sprintf(lpreq, "{\"id\": 0, \"method\": \"getblockcount\"}\n");
- val = json_rpc_call(curl, pool->rpc_url, pool->rpc_userpass, lpreq, true,
+
+ /* We will be making another call immediately after this
+ * one to get the height so allow this curl to be reused.*/
+ get_gbt_curl(pool, 500);
+ curl_easy_setopt(pool->gbt_curl, CURLOPT_FORBID_REUSE, 0);
+ val = json_rpc_call(pool->gbt_curl, pool->rpc_url, pool->rpc_userpass, lpreq, true,
false, &rolltime, pool, false);
+ release_gbt_curl(pool);
+
if (likely(val))
res_val = json_object_get(val, "result");
if (likely(res_val)) {
@@ -7926,8 +7945,13 @@ retry_pool:
update_gbt_solo(pool);
continue;
}
- val = json_rpc_call(curl, pool->rpc_url, pool->rpc_userpass,
+
+ get_gbt_curl(pool, 500);
+ curl_easy_setopt(pool->gbt_curl, CURLOPT_FORBID_REUSE, 1);
+ val = json_rpc_call(pool->gbt_curl, pool->rpc_url, pool->rpc_userpass,
lpreq, true, false, &rolltime, pool, false);
+ release_gbt_curl(pool);
+
if (val) {
/* Do a comparison on a short stretch of
* the hash to make sure it hasn't changed
@@ -7952,6 +7976,10 @@ retry_pool:
}
}
+ curl = curl_easy_init();
+ if (unlikely(!curl))
+ quit (1, "Longpoll CURL initialisation failed");
+
/* Any longpoll from any pool is enough for this to be true */
have_longpoll = true;
diff --git a/miner.h b/miner.h
index 90a17d3..ca002ed 100644
--- a/miner.h
+++ b/miner.h
@@ -1258,6 +1258,8 @@ struct pool {
unsigned char scriptsig_base[42 + 2];
unsigned char script_pubkey[25 + 3];
int nValue;
+ CURL *gbt_curl;
+ bool gbt_curl_inuse;
/* Shared by both stratum & GBT */
unsigned char *coinbase;