Browse Source

Drop clients that are holding a reference count only after they've dropped it

master
Con Kolivas 10 years ago
parent
commit
e11cb5c57e
  1. 58
      src/stratifier.c

58
src/stratifier.c

@ -244,6 +244,7 @@ struct stratum_instance {
char address[INET6_ADDRSTRLEN]; char address[INET6_ADDRSTRLEN];
bool subscribed; bool subscribed;
bool authorised; bool authorised;
bool dropped;
bool idle; bool idle;
int reject; /* Indicator that this client is having a run of rejects int reject; /* Indicator that this client is having a run of rejects
* or other problem and should be dropped lazily if * or other problem and should be dropped lazily if
@ -1103,6 +1104,32 @@ static stratum_instance_t *ref_instance_by_id(sdata_t *sdata, int64_t id)
return instance; return instance;
} }
static void __drop_client(sdata_t *sdata, stratum_instance_t *client, user_instance_t *instance,
int64_t id)
{
stratum_instance_t *old_client = NULL;
HASH_DEL(sdata->stratum_instances, client);
if (instance)
DL_DELETE(instance->instances, client);
HASH_FIND(hh, sdata->disconnected_instances, &client->enonce1_64, sizeof(uint64_t), old_client);
/* Only keep around one copy of the old client in server mode */
if (!client->ckp->proxy && !old_client && client->enonce1_64 && client->authorised) {
LOGNOTICE("Disconnecting client %ld %s %s", id, client->workername,
client->dropped ? "lazily" : "");
HASH_ADD(hh, sdata->disconnected_instances, enonce1_64, sizeof(uint64_t), client);
sdata->stats.disconnected++;
client->disconnected_time = time(NULL);
} else {
if (client->workername)
LOGNOTICE("Dropping client %ld %s %s", id, client->workername,
client->dropped ? "lazily" : "");
else
LOGINFO("Dropping workerless client %ld %s", id, client->dropped ? "lazily" : "");
__add_dead(sdata, client);
}
}
/* Decrease the reference count of instance. */ /* Decrease the reference count of instance. */
static void _dec_instance_ref(sdata_t *sdata, stratum_instance_t *instance, const char *file, static void _dec_instance_ref(sdata_t *sdata, stratum_instance_t *instance, const char *file,
const char *func, const int line) const char *func, const int line)
@ -1112,6 +1139,10 @@ static void _dec_instance_ref(sdata_t *sdata, stratum_instance_t *instance, cons
LOGERR("Instance ref count dropped below zero from %s %s:%d", file, func, line); LOGERR("Instance ref count dropped below zero from %s %s:%d", file, func, line);
instance->ref = 0; instance->ref = 0;
} }
/* See if there are any instances that were dropped that could not be
* moved due to holding a reference and drop them now. */
if (unlikely(instance->dropped && !instance->ref))
__drop_client(sdata, instance, instance->user_instance, instance->id);
ck_wunlock(&sdata->instance_lock); ck_wunlock(&sdata->instance_lock);
} }
@ -1261,33 +1292,18 @@ static void drop_client(sdata_t *sdata, int64_t 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 && likely(!client->ref)) { if (client) {
stratum_instance_t *old_client = NULL;
instance = client->user_instance; instance = client->user_instance;
if (client->authorised) { if (client->authorised) {
dec = true; dec = true;
client->authorised = false;
ckp = client->ckp; ckp = client->ckp;
} }
/* If the client is still holding a reference, don't drop them
HASH_DEL(sdata->stratum_instances, client); * now but wait till the reference is dropped */
if (instance) if (likely(!client->ref))
DL_DELETE(instance->instances, client); __drop_client(sdata, client, instance, id);
HASH_FIND(hh, sdata->disconnected_instances, &client->enonce1_64, sizeof(uint64_t), old_client);
/* Only keep around one copy of the old client in server mode */
if (!client->ckp->proxy && !old_client && client->enonce1_64 && dec) {
LOGNOTICE("Disconnecting client %ld %s", client->id, client->workername);
HASH_ADD(hh, sdata->disconnected_instances, enonce1_64, sizeof(uint64_t), client);
sdata->stats.disconnected++;
client->disconnected_time = time(NULL);
} else {
if (client->workername)
LOGNOTICE("Dropping client %ld %s", client->id, client->workername);
else else
LOGINFO("Dropping workerless client %ld", client->id); client->dropped = true;
__add_dead(sdata, client);
}
} }
/* Old disconnected instances will not have any valid shares so remove /* Old disconnected instances will not have any valid shares so remove

Loading…
Cancel
Save