Use a separate lock for the transaction table.

This commit is contained in:
ckolivas 2017-01-12 11:09:23 +11:00
parent 79a2ec9640
commit 8119d24175

View File

@ -487,6 +487,9 @@ struct stratifier_data {
uint64_t enonce1_64;
/* For protecting the txntable data */
cklock_t txn_lock;
/* For protecting the hashtable data */
cklock_t workbase_lock;
@ -1288,7 +1291,7 @@ static bool add_txn(ckpool_t *ckp, sdata_t *sdata, txntable_t **txns, const char
/* Look for transactions we already know about and increment their
* refcount if we're still using them. */
ck_rlock(&sdata->workbase_lock);
ck_wlock(&sdata->txn_lock);
HASH_FIND_STR(sdata->txns, hash, txn);
if (txn) {
if (!local)
@ -1297,7 +1300,7 @@ static bool add_txn(ckpool_t *ckp, sdata_t *sdata, txntable_t **txns, const char
txn->refcount = REFCOUNT_LOCAL;
txn->seen = found = true;
}
ck_runlock(&sdata->workbase_lock);
ck_wunlock(&sdata->txn_lock);
if (found)
return false;
@ -1396,7 +1399,7 @@ static void update_txns(ckpool_t *ckp, sdata_t *sdata, txntable_t *txns, bool lo
/* Find which transactions have their refcount decremented to zero
* and remove them. */
ck_wlock(&sdata->workbase_lock);
ck_wlock(&sdata->txn_lock);
HASH_ITER(hh, sdata->txns, tmp, tmpa) {
json_t *txn_val;
@ -1432,7 +1435,7 @@ static void update_txns(ckpool_t *ckp, sdata_t *sdata, txntable_t *txns, bool lo
HASH_ADD_STR(sdata->txns, hash, tmp);
added++;
}
ck_wunlock(&sdata->workbase_lock);
ck_wunlock(&sdata->txn_lock);
if (added) {
JSON_CPACK(val, "{so}", "transaction", txn_array);
@ -1797,7 +1800,7 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb)
memcpy(hash, hashes + i * 65, 64);
ck_wlock(&sdata->workbase_lock);
ck_wlock(&sdata->txn_lock);
HASH_FIND_STR(sdata->txns, hash, txn);
if (likely(txn)) {
txn->refcount = REFCOUNT_REMOTE;
@ -1806,7 +1809,7 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb)
"hash", hash, "data", txn->data);
json_array_append_new(txn_array, txn_val);
}
ck_wunlock(&sdata->workbase_lock);
ck_wunlock(&sdata->txn_lock);
if (likely(txn_val))
continue;
@ -1820,7 +1823,7 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb)
}
/* We've found it, let's add it to the table */
ck_wlock(&sdata->workbase_lock);
ck_wlock(&sdata->txn_lock);
/* One last check in case it got added while we dropped the lock */
HASH_FIND_STR(sdata->txns, hash, txn);
if (likely(!txn)) {
@ -1836,7 +1839,7 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb)
"hash", hash, "data", txn->data);
json_array_append_new(txn_array, txn_val);
}
ck_wunlock(&sdata->workbase_lock);
ck_wunlock(&sdata->txn_lock);
}
if (ret) {
@ -3249,6 +3252,7 @@ static void free_proxy(ckpool_t *ckp, proxy_t *proxy)
}
mutex_unlock(&dsdata->share_lock);
/* Do we need to check readcount here if freeing the proxy? */
ck_wlock(&dsdata->workbase_lock);
HASH_ITER(hh, dsdata->workbases, wb, tmpwb) {
HASH_DEL(dsdata->workbases, wb);
@ -6783,12 +6787,12 @@ static void send_node_all_txns(sdata_t *sdata, const stratum_instance_t *client)
txn_array = json_array();
ck_rlock(&sdata->workbase_lock);
ck_rlock(&sdata->txn_lock);
HASH_ITER(hh, sdata->txns, txn, tmp) {
JSON_CPACK(txn_val, "{ss,ss}", "hash", txn->hash, "data", txn->data);
json_array_append_new(txn_array, txn_val);
}
ck_runlock(&sdata->workbase_lock);
ck_runlock(&sdata->txn_lock);
if (client->trusted) {
JSON_CPACK(val, "{ss,so}", "method", stratum_msgs[SM_TRANSACTIONS],
@ -7493,7 +7497,7 @@ static json_t *get_hash_transactions(sdata_t *sdata, const json_t *hashes)
int found = 0;
size_t index;
ck_rlock(&sdata->workbase_lock);
ck_rlock(&sdata->txn_lock);
json_array_foreach(hashes, index, arr_val) {
const char *hash = json_string_value(arr_val);
json_t *txn_val;
@ -7507,7 +7511,7 @@ static json_t *get_hash_transactions(sdata_t *sdata, const json_t *hashes)
json_array_append_new(txn_array, txn_val);
found++;
}
ck_runlock(&sdata->workbase_lock);
ck_runlock(&sdata->txn_lock);
return txn_array;
}
@ -8962,6 +8966,7 @@ void *stratifier(void *arg)
create_pthread(&pth_heartbeat, ckdb_heartbeat, ckp);
read_poolstats(ckp);
cklock_init(&sdata->txn_lock);
cklock_init(&sdata->workbase_lock);
if (!ckp->proxy)
create_pthread(&pth_blockupdate, blockupdate, ckp);