diff --git a/src/stratifier.c b/src/stratifier.c index 2b34f713..1dc29ef5 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -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);