|
|
@ -158,7 +158,7 @@ static const char SEPARATOR = '|'; |
|
|
|
#define SEPSTR "|" |
|
|
|
#define SEPSTR "|" |
|
|
|
static const char GPUSEP = ','; |
|
|
|
static const char GPUSEP = ','; |
|
|
|
|
|
|
|
|
|
|
|
static const char *APIVERSION = "1.8"; |
|
|
|
static const char *APIVERSION = "1.9"; |
|
|
|
static const char *DEAD = "Dead"; |
|
|
|
static const char *DEAD = "Dead"; |
|
|
|
static const char *SICK = "Sick"; |
|
|
|
static const char *SICK = "Sick"; |
|
|
|
static const char *NOSTART = "NoStart"; |
|
|
|
static const char *NOSTART = "NoStart"; |
|
|
@ -229,6 +229,7 @@ static const char *OSINFO = |
|
|
|
#define _NOTIFY "NOTIFY" |
|
|
|
#define _NOTIFY "NOTIFY" |
|
|
|
#define _DEVDETAILS "DEVDETAILS" |
|
|
|
#define _DEVDETAILS "DEVDETAILS" |
|
|
|
#define _BYE "BYE" |
|
|
|
#define _BYE "BYE" |
|
|
|
|
|
|
|
#define _RESTART "RESTART" |
|
|
|
|
|
|
|
|
|
|
|
static const char ISJSON = '{'; |
|
|
|
static const char ISJSON = '{'; |
|
|
|
#define JSON0 "{" |
|
|
|
#define JSON0 "{" |
|
|
@ -260,6 +261,7 @@ static const char ISJSON = '{'; |
|
|
|
#define JSON_NOTIFY JSON1 _NOTIFY JSON2 |
|
|
|
#define JSON_NOTIFY JSON1 _NOTIFY JSON2 |
|
|
|
#define JSON_DEVDETAILS JSON1 _DEVDETAILS JSON2 |
|
|
|
#define JSON_DEVDETAILS JSON1 _DEVDETAILS JSON2 |
|
|
|
#define JSON_BYE JSON1 _BYE JSON1 |
|
|
|
#define JSON_BYE JSON1 _BYE JSON1 |
|
|
|
|
|
|
|
#define JSON_RESTART JSON1 _RESTART JSON1 |
|
|
|
#define JSON_CLOSE JSON3 |
|
|
|
#define JSON_CLOSE JSON3 |
|
|
|
#define JSON_END JSON4 |
|
|
|
#define JSON_END JSON4 |
|
|
|
|
|
|
|
|
|
|
@ -479,6 +481,12 @@ static int my_thr_id = 0; |
|
|
|
static int bye = 0; |
|
|
|
static int bye = 0; |
|
|
|
static bool ping = true; |
|
|
|
static bool ping = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Used to control quit restart access to shutdown variables
|
|
|
|
|
|
|
|
static pthread_mutex_t quit_restart_lock; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int do_a_quit = 0; |
|
|
|
|
|
|
|
static int do_a_restart = 0; |
|
|
|
|
|
|
|
|
|
|
|
static time_t when = 0; // when the request occurred
|
|
|
|
static time_t when = 0; // when the request occurred
|
|
|
|
|
|
|
|
|
|
|
|
struct IP4ACCESS { |
|
|
|
struct IP4ACCESS { |
|
|
@ -612,7 +620,7 @@ static int pgadevice(int pgaid) |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
// All replies (except BYE) start with a message
|
|
|
|
// All replies (except BYE and RESTART) start with a message
|
|
|
|
// thus for JSON, message() inserts JSON_START at the front
|
|
|
|
// thus for JSON, message() inserts JSON_START at the front
|
|
|
|
// and send_result() adds JSON_END at the end
|
|
|
|
// and send_result() adds JSON_END at the end
|
|
|
|
static char *message(int messageid, int paramid, char *param2, bool isjson) |
|
|
|
static char *message(int messageid, int paramid, char *param2, bool isjson) |
|
|
@ -1811,22 +1819,26 @@ static void gpuvddc(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, boo |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void send_result(SOCKETTYPE c, bool isjson); |
|
|
|
void doquit(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson) |
|
|
|
|
|
|
|
|
|
|
|
void doquit(SOCKETTYPE c, __maybe_unused char *param, bool isjson) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
if (isjson) |
|
|
|
if (isjson) |
|
|
|
strcpy(io_buffer, JSON_START JSON_BYE); |
|
|
|
strcpy(io_buffer, JSON_START JSON_BYE); |
|
|
|
else |
|
|
|
else |
|
|
|
strcpy(io_buffer, _BYE); |
|
|
|
strcpy(io_buffer, _BYE); |
|
|
|
|
|
|
|
|
|
|
|
send_result(c, isjson); |
|
|
|
|
|
|
|
*io_buffer = '\0'; |
|
|
|
|
|
|
|
bye = 1; |
|
|
|
bye = 1; |
|
|
|
|
|
|
|
do_a_quit = 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
PTH(&thr_info[my_thr_id]) = 0L; |
|
|
|
void dorestart(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (isjson) |
|
|
|
|
|
|
|
strcpy(io_buffer, JSON_START JSON_RESTART); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
strcpy(io_buffer, _RESTART); |
|
|
|
|
|
|
|
|
|
|
|
kill_work(); |
|
|
|
bye = 1; |
|
|
|
|
|
|
|
do_a_restart = 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void privileged(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson) |
|
|
|
void privileged(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson) |
|
|
@ -2017,6 +2029,7 @@ struct CMDS { |
|
|
|
{ "privileged", privileged, true }, |
|
|
|
{ "privileged", privileged, true }, |
|
|
|
{ "notify", notify, false }, |
|
|
|
{ "notify", notify, false }, |
|
|
|
{ "devdetails", devdetails, false }, |
|
|
|
{ "devdetails", devdetails, false }, |
|
|
|
|
|
|
|
{ "restart", dorestart, true }, |
|
|
|
{ NULL, NULL, false } |
|
|
|
{ NULL, NULL, false } |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
@ -2041,11 +2054,12 @@ static void send_result(SOCKETTYPE c, bool isjson) |
|
|
|
else |
|
|
|
else |
|
|
|
applog(LOG_DEBUG, "API: sent %d", n); |
|
|
|
applog(LOG_DEBUG, "API: sent %d", n); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void tidyup(__maybe_unused void *arg) |
|
|
|
static void tidyup(__maybe_unused void *arg) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
mutex_lock(&quit_restart_lock); |
|
|
|
|
|
|
|
|
|
|
|
bye = 1; |
|
|
|
bye = 1; |
|
|
|
|
|
|
|
|
|
|
|
if (sock != INVSOCK) { |
|
|
|
if (sock != INVSOCK) { |
|
|
@ -2068,6 +2082,8 @@ static void tidyup(__maybe_unused void *arg) |
|
|
|
free(io_buffer); |
|
|
|
free(io_buffer); |
|
|
|
io_buffer = NULL; |
|
|
|
io_buffer = NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mutex_unlock(&quit_restart_lock); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
@ -2172,8 +2188,37 @@ popipo: |
|
|
|
free(buf); |
|
|
|
free(buf); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void *quit_thread(__maybe_unused void *userdata) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// allow thread creator to finish whatever it's doing
|
|
|
|
|
|
|
|
mutex_lock(&quit_restart_lock); |
|
|
|
|
|
|
|
mutex_unlock(&quit_restart_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (opt_debug) |
|
|
|
|
|
|
|
applog(LOG_DEBUG, "API: killing cgminer"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
kill_work(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void *restart_thread(__maybe_unused void *userdata) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// allow thread creator to finish whatever it's doing
|
|
|
|
|
|
|
|
mutex_lock(&quit_restart_lock); |
|
|
|
|
|
|
|
mutex_unlock(&quit_restart_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (opt_debug) |
|
|
|
|
|
|
|
applog(LOG_DEBUG, "API: restarting cgminer"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app_restart(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void api(int api_thr_id) |
|
|
|
void api(int api_thr_id) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
struct thr_info bye_thr; |
|
|
|
char buf[BUFSIZ]; |
|
|
|
char buf[BUFSIZ]; |
|
|
|
char param_buf[BUFSIZ]; |
|
|
|
char param_buf[BUFSIZ]; |
|
|
|
const char *localaddr = "127.0.0.1"; |
|
|
|
const char *localaddr = "127.0.0.1"; |
|
|
@ -2197,6 +2242,8 @@ void api(int api_thr_id) |
|
|
|
bool did; |
|
|
|
bool did; |
|
|
|
int i; |
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mutex_init(&quit_restart_lock); |
|
|
|
|
|
|
|
|
|
|
|
pthread_cleanup_push(tidyup, NULL); |
|
|
|
pthread_cleanup_push(tidyup, NULL); |
|
|
|
my_thr_id = api_thr_id; |
|
|
|
my_thr_id = api_thr_id; |
|
|
|
|
|
|
|
|
|
|
@ -2408,4 +2455,33 @@ void api(int api_thr_id) |
|
|
|
} |
|
|
|
} |
|
|
|
die: |
|
|
|
die: |
|
|
|
pthread_cleanup_pop(true); |
|
|
|
pthread_cleanup_pop(true); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (opt_debug) |
|
|
|
|
|
|
|
applog(LOG_DEBUG, "API: terminating due to: %s", |
|
|
|
|
|
|
|
do_a_quit ? "QUIT" : (do_a_restart ? "RESTART" : (bye ? "BYE" : "UNKNOWN!"))); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mutex_lock(&quit_restart_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (do_a_restart != 0) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (thr_info_create(&bye_thr, NULL, restart_thread, &bye_thr)) { |
|
|
|
|
|
|
|
mutex_unlock(&quit_restart_lock); |
|
|
|
|
|
|
|
quit(1, "API failed to initiate a restart - aborting"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_detach(bye_thr.pth); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else |
|
|
|
|
|
|
|
if (do_a_quit != 0) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (thr_info_create(&bye_thr, NULL, quit_thread, &bye_thr)) { |
|
|
|
|
|
|
|
mutex_unlock(&quit_restart_lock); |
|
|
|
|
|
|
|
quit(1, "API failed to initiate a clean quit - aborting"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_detach(bye_thr.pth); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mutex_unlock(&quit_restart_lock); |
|
|
|
} |
|
|
|
} |
|
|
|