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; stratum_instance_t *client;
ck_wlock(&sdata->instance_lock); ck_ilock(&sdata->instance_lock);
client = __instance_by_id(sdata, id); client = __instance_by_id(sdata, id);
if (client) { if (client) {
if (unlikely(client->dropped)) if (unlikely(client->dropped))
client = NULL; client = NULL;
else else {
/* Upgrade to write lock to modify client refcount */
ck_ulock(&sdata->instance_lock);
__inc_instance_ref(client); __inc_instance_ref(client);
ck_dwilock(&sdata->instance_lock);
}
} }
ck_wunlock(&sdata->instance_lock); ck_uilock(&sdata->instance_lock);
return client; 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 */ /* Number is in BE but we don't swap either of them */
hex2bin(&enonce1_64, sessionid, slen); hex2bin(&enonce1_64, sessionid, slen);
ck_wlock(&sdata->instance_lock); ck_ilock(&sdata->instance_lock);
HASH_ITER(hh, sdata->stratum_instances, client, tmp) { HASH_ITER(hh, sdata->stratum_instances, client, tmp) {
if (client->id == id) if (client->id == id)
continue; 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 /* Delete the entry once we are going to use it since there
* will be a new instance with the enonce1_64 */ * will be a new instance with the enonce1_64 */
old_id = client->id; old_id = client->id;
/* Upgrade to write lock to disconnect */
ck_ulock(&sdata->instance_lock);
__del_disconnected(sdata, client); __del_disconnected(sdata, client);
ck_dwilock(&sdata->instance_lock);
ret = enonce1_64; ret = enonce1_64;
} }
out_unlock: out_unlock:
ck_wunlock(&sdata->instance_lock); ck_uilock(&sdata->instance_lock);
out: out:
if (ret) if (ret)
LOGNOTICE("Reconnecting old instance %ld to instance %ld", old_id, id); 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); LOGINFO("Stratifier asked to drop client %ld", id);
ck_wlock(&sdata->instance_lock); ck_ilock(&sdata->instance_lock);
client = __instance_by_id(sdata, id); client = __instance_by_id(sdata, id);
/* Upgrade to write lock */
ck_ulock(&sdata->instance_lock);
if (client && !client->dropped) { if (client && !client->dropped) {
user = client->user_instance; user = client->user_instance;
ckp = client->ckp; ckp = client->ckp;
@ -2171,8 +2182,10 @@ static user_instance_t *generate_user(ckpool_t *ckp, stratum_instance_t *client,
if (unlikely(len > 127)) if (unlikely(len > 127))
username[127] = '\0'; username[127] = '\0';
ck_wlock(&sdata->instance_lock); ck_ilock(&sdata->instance_lock);
HASH_FIND_STR(sdata->user_instances, username, user); HASH_FIND_STR(sdata->user_instances, username, user);
/* Upgrade to write lock */
ck_ulock(&sdata->instance_lock);
if (!user) { if (!user) {
/* New user instance. Secondary user id will be NULL */ /* New user instance. Secondary user id will be NULL */
user = ckzalloc(sizeof(user_instance_t)); user = ckzalloc(sizeof(user_instance_t));
@ -3451,8 +3464,10 @@ static void srecv_process(ckpool_t *ckp, char *buf)
json_object_clear(val); json_object_clear(val);
/* Parse the message here */ /* Parse the message here */
ck_wlock(&sdata->instance_lock); ck_ilock(&sdata->instance_lock);
client = __instance_by_id(sdata, msg->client_id); 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 client_id instance doesn't exist yet, create one */
if (unlikely(!client)) { if (unlikely(!client)) {
if (likely(!__dropped_instance(sdata, msg->client_id))) { 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; stratum_instance_t *client;
ck_wlock(&sdata->instance_lock); ck_ilock(&sdata->instance_lock);
client = __instance_by_id(sdata, id); client = __instance_by_id(sdata, id);
if (client) { if (client) {
if (client->dropped || client->authorising || client->authorised) if (client->dropped || client->authorising || client->authorised)
client = NULL; client = NULL;
else { else {
/* Upgrade to write lock to modify client data */
ck_ulock(&sdata->instance_lock);
__inc_instance_ref(client); __inc_instance_ref(client);
client->authorising = true; client->authorising = true;
ck_dwilock(&sdata->instance_lock);
} }
} }
ck_wunlock(&sdata->instance_lock); ck_uilock(&sdata->instance_lock);
return client; return client;
} }

Loading…
Cancel
Save