Browse Source

Add locking for redirector share management.

master
Con Kolivas 8 years ago
parent
commit
93f0c27fd5
  1. 24
      src/connector.c

24
src/connector.c

@ -439,7 +439,7 @@ static void send_client(cdata_t *cdata, int64_t id, char *buf);
/* Look for shares being submitted via a redirector and add them to a linked /* Look for shares being submitted via a redirector and add them to a linked
* list for looking up the responses. */ * list for looking up the responses. */
static void parse_redirector_share(client_instance_t *client, const json_t *val) static void parse_redirector_share(cdata_t *cdata, client_instance_t *client, const json_t *val)
{ {
share_t *share, *tmp; share_t *share, *tmp;
time_t now; time_t now;
@ -453,9 +453,14 @@ static void parse_redirector_share(client_instance_t *client, const json_t *val)
now = time(NULL); now = time(NULL);
share->submitted = now; share->submitted = now;
share->id = id; share->id = id;
DL_APPEND(client->shares, share);
LOGINFO("Redirector adding client %"PRId64" share id: %"PRId64, client->id, id); LOGINFO("Redirector adding client %"PRId64" share id: %"PRId64, client->id, id);
/* We use the cdata lock instead of a separate lock since this function
* is called infrequently. */
ck_wlock(&cdata->lock);
DL_APPEND(client->shares, share);
/* Age old shares. */ /* Age old shares. */
DL_FOREACH_SAFE(client->shares, share, tmp) { DL_FOREACH_SAFE(client->shares, share, tmp) {
if (now > share->submitted + 120) { if (now > share->submitted + 120) {
@ -463,6 +468,7 @@ static void parse_redirector_share(client_instance_t *client, const json_t *val)
dealloc(share); dealloc(share);
} }
} }
ck_wunlock(&cdata->lock);
} }
/* Client is holding a reference count from being on the epoll list. Returns /* Client is holding a reference count from being on the epoll list. Returns
@ -519,7 +525,7 @@ reparse:
json_object_set_new_nocheck(val, "client_id", json_integer(passthrough_id)); json_object_set_new_nocheck(val, "client_id", json_integer(passthrough_id));
} else { } else {
if (ckp->redirector && !client->redirected && strstr(client->buf, "mining.submit")) if (ckp->redirector && !client->redirected && strstr(client->buf, "mining.submit"))
parse_redirector_share(client, val); parse_redirector_share(cdata, client, val);
json_object_set_new_nocheck(val, "client_id", json_integer(client->id)); json_object_set_new_nocheck(val, "client_id", json_integer(client->id));
json_object_set_new_nocheck(val, "address", json_string(client->address_name)); json_object_set_new_nocheck(val, "address", json_string(client->address_name));
} }
@ -857,7 +863,7 @@ static void redirect_client(ckpool_t *ckp, client_instance_t *client)
/* Look for accepted shares in redirector mode to know we can redirect this /* Look for accepted shares in redirector mode to know we can redirect this
* client to a protected server. */ * client to a protected server. */
static void test_redirector_shares(ckpool_t *ckp, client_instance_t *client, const char *buf) static void test_redirector_shares(ckpool_t *ckp, cdata_t *cdata, client_instance_t *client, const char *buf)
{ {
json_t *val = json_loads(buf, 0, NULL); json_t *val = json_loads(buf, 0, NULL);
share_t *share, *found = NULL; share_t *share, *found = NULL;
@ -872,19 +878,21 @@ static void test_redirector_shares(ckpool_t *ckp, client_instance_t *client, con
LOGINFO("Failed to find response id"); LOGINFO("Failed to find response id");
goto out; goto out;
} }
ck_rlock(&cdata->lock);
DL_FOREACH(client->shares, share) { DL_FOREACH(client->shares, share) {
if (share->id == id) { if (share->id == id) {
LOGDEBUG("Found matching share %"PRId64" in trs for client %"PRId64, LOGDEBUG("Found matching share %"PRId64" in trs for client %"PRId64,
id, client->id); id, client->id);
DL_DELETE(client->shares, share);
found = share; found = share;
break; break;
} }
} }
ck_runlock(&cdata->lock);
if (found) { if (found) {
bool result = false; bool result = false;
dealloc(found);
if (!json_get_bool(&result, val, "result")) { if (!json_get_bool(&result, val, "result")) {
LOGINFO("Failed to find result in trs share"); LOGINFO("Failed to find result in trs share");
goto out; goto out;
@ -902,10 +910,12 @@ static void test_redirector_shares(ckpool_t *ckp, client_instance_t *client, con
redirect_client(ckp, client); redirect_client(ckp, client);
/* Clear the list now since we don't need it any more */ /* Clear the list now since we don't need it any more */
ck_wlock(&cdata->lock);
DL_FOREACH_SAFE(client->shares, share, found) { DL_FOREACH_SAFE(client->shares, share, found) {
DL_DELETE(client->shares, share); DL_DELETE(client->shares, share);
dealloc(share); dealloc(share);
} }
ck_wunlock(&cdata->lock);
} }
out: out:
json_decref(val); json_decref(val);
@ -979,7 +989,7 @@ static void send_client(cdata_t *cdata, const int64_t id, char *buf)
stratifier_add_recv(ckp, val); stratifier_add_recv(ckp, val);
} }
if (ckp->redirector && !client->redirected) if (ckp->redirector && !client->redirected)
test_redirector_shares(ckp, client, buf); test_redirector_shares(ckp, cdata, client, buf);
} }
out: out:
sender_send = ckzalloc(sizeof(sender_send_t)); sender_send = ckzalloc(sizeof(sender_send_t));

Loading…
Cancel
Save