From 67c00d57c68dd4c1e48c5e85b9e9cb4218cbff6c Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 4 Feb 2015 23:42:16 +1100 Subject: [PATCH] Fine grain the locking for read/write sections using the upgradeable variants in the stratifier where suitable --- src/stratifier.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index cfc959db..6be91432 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -1160,15 +1160,19 @@ static stratum_instance_t *ref_instance_by_id(sdata_t *sdata, const int64_t id) { stratum_instance_t *client; - ck_wlock(&sdata->instance_lock); + ck_ilock(&sdata->instance_lock); client = __instance_by_id(sdata, id); if (client) { if (unlikely(client->dropped)) client = NULL; - else + else { + /* Upgrade to write lock to modify client refcount */ + ck_ulock(&sdata->instance_lock); __inc_instance_ref(client); + ck_dwilock(&sdata->instance_lock); + } } - ck_wunlock(&sdata->instance_lock); + ck_uilock(&sdata->instance_lock); return client; } @@ -1292,7 +1296,7 @@ static uint64_t disconnected_sessionid_exists(sdata_t *sdata, const char *sessio /* Number is in BE but we don't swap either of them */ hex2bin(&enonce1_64, sessionid, slen); - ck_wlock(&sdata->instance_lock); + ck_ilock(&sdata->instance_lock); HASH_ITER(hh, sdata->stratum_instances, client, tmp) { if (client->id == id) continue; @@ -1307,11 +1311,16 @@ static uint64_t disconnected_sessionid_exists(sdata_t *sdata, const char *sessio /* Delete the entry once we are going to use it since there * will be a new instance with the enonce1_64 */ old_id = client->id; + + /* Upgrade to write lock to disconnect */ + ck_ulock(&sdata->instance_lock); __del_disconnected(sdata, client); + ck_dwilock(&sdata->instance_lock); + ret = enonce1_64; } out_unlock: - ck_wunlock(&sdata->instance_lock); + ck_uilock(&sdata->instance_lock); out: if (ret) LOGNOTICE("Reconnecting old instance %ld to instance %ld", old_id, id); @@ -1406,8 +1415,10 @@ static void drop_client(sdata_t *sdata, const int64_t id) LOGINFO("Stratifier asked to drop client %ld", id); - ck_wlock(&sdata->instance_lock); + ck_ilock(&sdata->instance_lock); client = __instance_by_id(sdata, id); + /* Upgrade to write lock */ + ck_ulock(&sdata->instance_lock); if (client && !client->dropped) { user = client->user_instance; ckp = client->ckp; @@ -2171,8 +2182,10 @@ static user_instance_t *generate_user(ckpool_t *ckp, stratum_instance_t *client, if (unlikely(len > 127)) username[127] = '\0'; - ck_wlock(&sdata->instance_lock); + ck_ilock(&sdata->instance_lock); HASH_FIND_STR(sdata->user_instances, username, user); + /* Upgrade to write lock */ + ck_ulock(&sdata->instance_lock); if (!user) { /* New user instance. Secondary user id will be NULL */ user = ckzalloc(sizeof(user_instance_t)); @@ -3451,8 +3464,10 @@ static void srecv_process(ckpool_t *ckp, char *buf) json_object_clear(val); /* Parse the message here */ - ck_wlock(&sdata->instance_lock); + ck_ilock(&sdata->instance_lock); client = __instance_by_id(sdata, msg->client_id); + /* Upgrade to write lock */ + ck_ulock(&sdata->instance_lock); /* If client_id instance doesn't exist yet, create one */ if (unlikely(!client)) { if (likely(!__dropped_instance(sdata, msg->client_id))) { @@ -3545,17 +3560,20 @@ static stratum_instance_t *preauth_ref_instance_by_id(sdata_t *sdata, const int6 { stratum_instance_t *client; - ck_wlock(&sdata->instance_lock); + ck_ilock(&sdata->instance_lock); client = __instance_by_id(sdata, id); if (client) { if (client->dropped || client->authorising || client->authorised) client = NULL; else { + /* Upgrade to write lock to modify client data */ + ck_ulock(&sdata->instance_lock); __inc_instance_ref(client); client->authorising = true; + ck_dwilock(&sdata->instance_lock); } } - ck_wunlock(&sdata->instance_lock); + ck_uilock(&sdata->instance_lock); return client; }