kanoi 10 years ago
parent
commit
3b4912e8e0
  1. 75
      src/stratifier.c

75
src/stratifier.c

@ -857,10 +857,27 @@ static void update_base(ckpool_t *ckp, int prio)
create_pthread(pth, do_update, ur); create_pthread(pth, do_update, ur);
} }
/* Add a stratum instance to the dead instances list */
static void __kill_instance(sdata_t *sdata, stratum_instance_t *client)
{
user_instance_t *instance = client->user_instance;
if (instance) {
worker_instance_t *worker = client->worker_instance;
DL_DELETE(instance->instances, client);
if (worker)
DL_DELETE(instance->worker_instances, worker);
}
LL_PREPEND(sdata->dead_instances, client);
sdata->stats.dead++;
}
static void __del_disconnected(sdata_t *sdata, stratum_instance_t *client) static void __del_disconnected(sdata_t *sdata, stratum_instance_t *client)
{ {
HASH_DEL(sdata->disconnected_instances, client); HASH_DEL(sdata->disconnected_instances, client);
sdata->stats.disconnected--; sdata->stats.disconnected--;
__kill_instance(sdata, client);
} }
static void drop_allclients(ckpool_t *ckp) static void drop_allclients(ckpool_t *ckp)
@ -1112,22 +1129,6 @@ static stratum_instance_t *__stratum_add_instance(ckpool_t *ckp, int64_t id, int
return instance; return instance;
} }
/* Add a stratum instance to the dead instances list */
static void __kill_instance(sdata_t *sdata, stratum_instance_t *client)
{
user_instance_t *instance = client->user_instance;
if (instance) {
worker_instance_t *worker = client->worker_instance;
DL_DELETE(instance->instances, client);
if (worker)
DL_DELETE(instance->worker_instances, worker);
}
LL_PREPEND(sdata->dead_instances, client);
sdata->stats.dead++;
}
/* Only supports a full ckpool instance sessionid with an 8 byte sessionid */ /* Only supports a full ckpool instance sessionid with an 8 byte sessionid */
static bool disconnected_sessionid_exists(sdata_t *sdata, const char *sessionid, int64_t id) static bool disconnected_sessionid_exists(sdata_t *sdata, const char *sessionid, int64_t id)
{ {
@ -1157,7 +1158,6 @@ static bool disconnected_sessionid_exists(sdata_t *sdata, const char *sessionid,
/* If we've found a matching disconnected instance, use it only /* If we've found a matching disconnected instance, use it only
* once and discard it */ * once and discard it */
__del_disconnected(sdata, instance); __del_disconnected(sdata, instance);
__kill_instance(sdata, instance);
ret = true; ret = true;
} }
out_unlock: out_unlock:
@ -1244,17 +1244,18 @@ static void dec_worker(ckpool_t *ckp, user_instance_t *instance)
static void drop_client(sdata_t *sdata, int64_t id) static void drop_client(sdata_t *sdata, int64_t id)
{ {
stratum_instance_t *client, *tmp; stratum_instance_t *client, *tmp;
user_instance_t *instance = NULL;
time_t now_t = time(NULL); time_t now_t = time(NULL);
ckpool_t *ckp = NULL;
bool dec = false; bool dec = false;
LOGINFO("Stratifier dropping client %ld", id); LOGINFO("Stratifier requested to drop client %ld", id);
ck_wlock(&sdata->instance_lock); ck_wlock(&sdata->instance_lock);
client = __instance_by_id(sdata, id); client = __instance_by_id(sdata, id);
if (client) { if (client) {
stratum_instance_t *old_client = NULL; stratum_instance_t *old_client = NULL;
__inc_instance_ref(client);
if (client->authorised) { if (client->authorised) {
dec = true; dec = true;
client->authorised = false; client->authorised = false;
@ -1269,19 +1270,11 @@ static void drop_client(sdata_t *sdata, int64_t id)
client->disconnected_time = time(NULL); client->disconnected_time = time(NULL);
} else } else
__kill_instance(sdata, client); __kill_instance(sdata, client);
ckp = client->ckp;
instance = client->user_instance;
LOGINFO("Stratifer dropped %sauthorised client %ld", dec ? "" : "un", id);
} }
ck_wunlock(&sdata->instance_lock);
/* Decrease worker count outside of instance_lock to avoid recursive
* locking */
if (dec)
dec_worker(client->ckp, client->user_instance);
/* Cull old unused clients lazily when there are no more reference
* counts for them. */
ck_wlock(&sdata->instance_lock);
if (client)
__dec_instance_ref(client);
/* Old disconnected instances will not have any valid shares so remove /* Old disconnected instances will not have any valid shares so remove
* them from the disconnected instances list if they've been dead for * them from the disconnected instances list if they've been dead for
* more than 10 minutes */ * more than 10 minutes */
@ -1290,10 +1283,10 @@ static void drop_client(sdata_t *sdata, int64_t id)
continue; continue;
LOGINFO("Discarding aged disconnected instance %ld", client->id); LOGINFO("Discarding aged disconnected instance %ld", client->id);
__del_disconnected(sdata, client); __del_disconnected(sdata, client);
__kill_instance(sdata, client);
} }
/* Discard any dead instances that no longer hold any reference counts,
* freeing up their memory safely */ /* Cull old unused clients lazily when there are no more reference
* counts for them. */
LL_FOREACH_SAFE(sdata->dead_instances, client, tmp) { LL_FOREACH_SAFE(sdata->dead_instances, client, tmp) {
if (!client->ref) { if (!client->ref) {
LOGINFO("Stratifier discarding instance %ld", client->id); LOGINFO("Stratifier discarding instance %ld", client->id);
@ -1305,6 +1298,11 @@ static void drop_client(sdata_t *sdata, int64_t id)
} }
} }
ck_wunlock(&sdata->instance_lock); ck_wunlock(&sdata->instance_lock);
/* Decrease worker count outside of instance_lock to avoid recursive
* locking. ckp and instance are guaranteed to be set if dec is true */
if (dec)
dec_worker(ckp, instance);
} }
static void stratum_broadcast_message(sdata_t *sdata, const char *msg) static void stratum_broadcast_message(sdata_t *sdata, const char *msg)
@ -3515,13 +3513,18 @@ static void *statsupdate(void *arg)
HASH_ITER(hh, sdata->user_instances, instance, tmpuser) { HASH_ITER(hh, sdata->user_instances, instance, tmpuser) {
worker_instance_t *worker; worker_instance_t *worker;
int iterations = 0;
bool idle = false; bool idle = false;
if (instance->workers < 1)
continue;
/* Decay times per worker */ /* Decay times per worker */
DL_FOREACH(instance->worker_instances, worker) { DL_FOREACH(instance->worker_instances, worker) {
/* FIXME: This shouldn't happen and is purely a sanity
* breakout till the real issue is found fixed. */
if (unlikely(iterations++ > instance->workers)) {
LOGWARNING("Statsupdate trying to iterate more than %d existing workers for worker %s",
instance->workers, worker->workername);
break;
}
per_tdiff = tvdiff(&now, &worker->last_share); per_tdiff = tvdiff(&now, &worker->last_share);
if (per_tdiff > 60) { if (per_tdiff > 60) {
decay_time(&worker->dsps1, 0, per_tdiff, 60); decay_time(&worker->dsps1, 0, per_tdiff, 60);

Loading…
Cancel
Save