Commit fe23dfd3d4e51a3928044d02073905c19d7add83

kanoi 2012-07-29T04:16:29

Merge pull request #2 from luke-jr/rpc_poolpriority RPC: New "poolpriority" command to set the order of pool priorities

diff --git a/API-README b/API-README
index df905ef..6ea5a53 100644
--- a/API-README
+++ b/API-README
@@ -174,6 +174,11 @@ The list of requests - a (*) means it requires privileged access - and replies a
                               Use '\\' to get a '\' and '\,' to include a comma
                               inside URL, USR or PASS
 
+ poolpriority|N,... (*)
+               none           There is no reply section just the STATUS section
+                              stating the results of changing pool priorities
+                              See usage below
+
  disablepool|N (*)
                none           There is no reply section just the STATUS section
                               stating the results of disabling pool N
@@ -270,8 +275,15 @@ The list of requests - a (*) means it requires privileged access - and replies a
 When you enable, disable or restart a GPU or PGA, you will also get Thread messages
 in the cgminer status window
 
-When you switch to a different pool to the current one, you will get a
-'Switching to URL' message in the cgminer status windows
+The 'poolpriority' command can be used to reset the priority order of pools.
+Each pool should be listed by id number in order of preference (first = most
+preferred). Any pools not listed will be prioritized after the ones that are,
+in an undefined order. If the priority change affects the miner's preference
+for mining, it may switch immediately.
+
+When you switch to a different pool to the current one (including by priority
+change), you will get a 'Switching to URL' message in the cgminer status
+windows
 
 Obviously, the JSON format is simply just the names as given before the '='
 with the values after the '='
diff --git a/api.c b/api.c
index 342c371..bfa3fca 100644
--- a/api.c
+++ b/api.c
@@ -339,6 +339,7 @@ static const char *JSON_PARAMETER = "parameter";
 #define MSG_ACCDENY 45
 #define MSG_ACCOK 46
 #define MSG_ENAPOOL 47
+#define MSG_POOLPRIO 73
 #define MSG_DISPOOL 48
 #define MSG_ALRENAP 49
 #define MSG_ALRDISP 50
@@ -501,6 +502,7 @@ struct CODES {
  { SEVERITY_ERR,   MSG_ACCDENY,	PARAM_STR,	"Access denied to '%s' command" },
  { SEVERITY_SUCC,  MSG_ACCOK,	PARAM_NONE,	"Privileged access OK" },
  { SEVERITY_SUCC,  MSG_ENAPOOL,	PARAM_POOL,	"Enabling pool %d:'%s'" },
+ { SEVERITY_SUCC,  MSG_POOLPRIO,PARAM_NONE,	"Changed pool priorities" },
  { SEVERITY_SUCC,  MSG_DISPOOL,	PARAM_POOL,	"Disabling pool %d:'%s'" },
  { SEVERITY_INFO,  MSG_ALRENAP,	PARAM_POOL,	"Pool %d:'%s' already enabled" },
  { SEVERITY_INFO,  MSG_ALRDISP,	PARAM_POOL,	"Pool %d:'%s' already disabled" },
@@ -2128,6 +2130,51 @@ static void enablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __
 	strcpy(io_buffer, message(MSG_ENAPOOL, id, NULL, isjson));
 }
 
+static void poolpriority(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
+{
+	SETUP_STRTOK_TS;
+	int total_pools_ = total_pools;  // Keep a local copy, to be more threadsafe
+	char *a;
+	int i, prio = 0, e = -1;
+
+	if (total_pools_ == 0) {
+		strcpy(io_buffer, message(MSG_NOPOOL, 0, NULL, isjson));
+		return;
+	}
+
+	bool pools_changed[total_pools_];
+	for (i = 0; i < total_pools_; ++i)
+		pools_changed[i] = false;
+
+	a = strtok_ts(param, ",");
+	do {
+		i = strtol(a, &a, 10);
+		if (unlikely(*a > 0x20 || i < 0 || i >= total_pools)) {
+			e = (*a > 0x20) ? -2 : i;
+			continue;
+		}
+		pools[i]->prio = prio++;
+		pools_changed[i] = true;
+	} while ( (a = strtok_ts(NULL, ",")) );
+
+	for (i = 0; i < total_pools_; ++i)
+		if (!pools_changed[i])
+			pools[i]->prio = prio++;
+
+	if (current_pool()->prio)
+		switch_pools(NULL);
+
+	if (e != -1) {
+		if (e == -2)
+			strcpy(io_buffer, message(MSG_MISPID, 0, NULL, isjson));
+		else
+			strcpy(io_buffer, message(MSG_INVPID, e, NULL, isjson));
+		return;
+	}
+
+	strcpy(io_buffer, message(MSG_POOLPRIO, 0, NULL, isjson));
+}
+
 static void disablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
 {
 	struct pool *pool;
@@ -2659,6 +2706,7 @@ struct CMDS {
 	{ "cpucount",		cpucount,	false },
 	{ "switchpool",		switchpool,	true },
 	{ "addpool",		addpool,	true },
+	{ "poolpriority",	poolpriority,	true },
 	{ "enablepool",		enablepool,	true },
 	{ "disablepool",	disablepool,	true },
 	{ "removepool",		removepool,	true },
diff --git a/compat.h b/compat.h
index c6e38d8..19a14f0 100644
--- a/compat.h
+++ b/compat.h
@@ -9,6 +9,10 @@
 
 #include <windows.h>
 
+// NOTE: Windows strtok uses a thread-local static buffer, so this is safe
+#define SETUP_STRTOK_TS  /*nothing needed*/
+#define strtok_ts  strtok
+
 #include "miner.h"  // for timersub
 
 static inline int nanosleep(const struct timespec *req, struct timespec *rem)
@@ -72,8 +76,13 @@ typedef long suseconds_t;
 #endif
 
 #define PTH(thr) ((thr)->pth.p)
-#else
+#else /* ! WIN32 */
+
 #define PTH(thr) ((thr)->pth)
+
+#define SETUP_STRTOK_TS  char*_strtok_ts_saveptr
+#define strtok_ts(str, delim)  strtok_r(str, delim, &_strtok_ts_saveptr)
+
 #endif /* WIN32 */
 
 #endif /* __COMPAT_H__ */