API V3.0 unlimited socket reply size
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
diff --git a/API-README b/API-README
index b5497d3..5d27855 100644
--- a/API-README
+++ b/API-README
@@ -453,6 +453,12 @@ miner.php - an example web page to access the API
Feature Changelog for external applications using the API:
+API V3.0 (cgminer v3.9.1)
+
+Allow unlimited size replies
+
+---------
+
API V2.0 (cgminer v3.8.0)
Removed all GPU related commands and information from the replies
diff --git a/api.c b/api.c
index c0055bd..aa43258 100644
--- a/api.c
+++ b/api.c
@@ -614,7 +614,6 @@ struct io_data {
char *ptr;
char *cur;
bool sock;
- bool full;
bool close;
};
@@ -626,14 +625,15 @@ struct io_list {
static struct io_list *io_head = NULL;
+#define SOCKBUFALLOCSIZ 65536
+
#define io_new(init) _io_new(init, false)
-#define sock_io_new() _io_new(SOCKBUFSIZ, true)
+#define sock_io_new() _io_new(SOCKBUFALLOCSIZ, true)
static void io_reinit(struct io_data *io_data)
{
io_data->cur = io_data->ptr;
*(io_data->ptr) = '\0';
- io_data->full = false;
io_data->close = false;
}
@@ -670,29 +670,16 @@ static bool io_add(struct io_data *io_data, char *buf)
{
size_t len, dif, tot;
- if (io_data->full)
- return false;
-
len = strlen(buf);
dif = io_data->cur - io_data->ptr;
- tot = len + 1 + dif;
+ // send will always have enough space to add the JSON
+ tot = len + 1 + dif + sizeof(JSON_CLOSE) + sizeof(JSON_END);
if (tot > io_data->siz) {
- size_t new = io_data->siz * 2;
+ size_t new = io_data->siz + (2 * SOCKBUFALLOCSIZ);
if (new < tot)
- new = tot * 2;
-
- if (io_data->sock) {
- if (new > SOCKBUFSIZ) {
- if (tot > SOCKBUFSIZ) {
- io_data->full = true;
- return false;
- }
-
- new = SOCKBUFSIZ;
- }
- }
+ new = (2 + (size_t)((float)tot / (float)SOCKBUFALLOCSIZ)) * SOCKBUFALLOCSIZ;
io_data->ptr = realloc(io_data->ptr, new);
io_data->cur = io_data->ptr + dif;
@@ -838,8 +825,7 @@ static struct api_data *api_add_data_full(struct api_data *root, char *name, enu
root = api_data;
root->prev = root;
root->next = root;
- }
- else {
+ } else {
api_data->prev = root->prev;
root->prev = api_data;
api_data->next = root;
@@ -3828,28 +3814,24 @@ static void checkcommand(struct io_data *io_data, __maybe_unused SOCKETTYPE c, c
static void send_result(struct io_data *io_data, SOCKETTYPE c, bool isjson)
{
- char buf[SOCKBUFSIZ + sizeof(JSON_CLOSE) + sizeof(JSON_END)];
- int count, res, tosend, len, n;
+ int count, sendc, res, tosend, len, n;
+ char *buf = io_data->ptr;
strcpy(buf, io_data->ptr);
if (io_data->close)
strcat(buf, JSON_CLOSE);
- if (isjson) {
- if (io_data->full)
- strcat(buf, JSON_END_TRUNCATED);
- else
- strcat(buf, JSON_END);
- }
+ if (isjson)
+ strcat(buf, JSON_END);
len = strlen(buf);
tosend = len+1;
applog(LOG_DEBUG, "API: send reply: (%d) '%.10s%s'", tosend, buf, len > 10 ? "..." : BLANK);
- count = 0;
- while (count++ < 5 && tosend > 0) {
+ count = sendc = 0;
+ while (count < 5 && tosend > 0) {
// allow 50ms per attempt
struct timeval timeout = {0, 50000};
fd_set wd;
@@ -3862,28 +3844,34 @@ static void send_result(struct io_data *io_data, SOCKETTYPE c, bool isjson)
}
n = send(c, buf, tosend, 0);
+ sendc++;
if (SOCKETFAIL(n)) {
+ count++;
if (sock_blocks())
continue;
- applog(LOG_WARNING, "API: send (%d) failed: %s", tosend, SOCKERRMSG);
+ applog(LOG_WARNING, "API: send (%d:%d) failed: %s", len+1, (len+1 - tosend), SOCKERRMSG);
return;
} else {
- if (count <= 1) {
+ if (sendc <= 1) {
if (n == tosend)
applog(LOG_DEBUG, "API: sent all of %d first go", tosend);
else
applog(LOG_DEBUG, "API: sent %d of %d first go", n, tosend);
} else {
if (n == tosend)
- applog(LOG_DEBUG, "API: sent all of remaining %d (count=%d)", tosend, count);
+ applog(LOG_DEBUG, "API: sent all of remaining %d (sendc=%d)", tosend, sendc);
else
- applog(LOG_DEBUG, "API: sent %d of remaining %d (count=%d)", n, tosend, count);
+ applog(LOG_DEBUG, "API: sent %d of remaining %d (sendc=%d)", n, tosend, sendc);
}
tosend -= n;
+ buf += n;
+
+ if (n == 0)
+ count++;
}
}
}