Browse Source

Fine grain the locking for read/write sections using the upgradeable variants in the stratifier where suitable

master
Con Kolivas 10 years ago
parent
commit
67c00d57c6
  1. 38
      src/stratifier.c

38
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;
}

Loading…
Cancel
Save