Browse Source

api.c V1.9 add 'restart' + redesign 'quit' so thread exits cleanly

nfactor-troky
Kano 13 years ago committed by Con Kolivas
parent
commit
524e2fb8f2
  1. 7
      README
  2. 96
      api.c

7
README

@ -647,7 +647,7 @@ The STATUS section is: @@ -647,7 +647,7 @@ The STATUS section is:
This defaults to the cgminer version but is the value of --api-description
if it was specified at runtime.
For API version 1.8:
For API version 1.9:
The list of requests - a (*) means it requires privileged access - and replies are:
@ -768,7 +768,7 @@ The list of requests - a (*) means it requires privileged access - and replies a @@ -768,7 +768,7 @@ The list of requests - a (*) means it requires privileged access - and replies a
stating success or failure saving the cgminer config
to filename
quit (*) none There is no status section but just a single "BYE|"
quit (*) none There is no status section but just a single "BYE"
reply before cgminer quits
notify NOTIFY The last status and history count of each devices problem
@ -798,6 +798,9 @@ The list of requests - a (*) means it requires privileged access - and replies a @@ -798,6 +798,9 @@ The list of requests - a (*) means it requires privileged access - and replies a
by the 'devs' command
e.g. DEVDETAILS=0,Name=GPU,ID=0,Driver=opencl,...|
restart (*) none There is no status section but just a single "RESTART"
reply before cgminer restarts
When you enable, disable or restart a GPU or PGA, you will also get Thread messages
in the cgminer status window

96
api.c

@ -158,7 +158,7 @@ static const char SEPARATOR = '|'; @@ -158,7 +158,7 @@ static const char SEPARATOR = '|';
#define SEPSTR "|"
static const char GPUSEP = ',';
static const char *APIVERSION = "1.8";
static const char *APIVERSION = "1.9";
static const char *DEAD = "Dead";
static const char *SICK = "Sick";
static const char *NOSTART = "NoStart";
@ -229,6 +229,7 @@ static const char *OSINFO = @@ -229,6 +229,7 @@ static const char *OSINFO =
#define _NOTIFY "NOTIFY"
#define _DEVDETAILS "DEVDETAILS"
#define _BYE "BYE"
#define _RESTART "RESTART"
static const char ISJSON = '{';
#define JSON0 "{"
@ -260,6 +261,7 @@ static const char ISJSON = '{'; @@ -260,6 +261,7 @@ static const char ISJSON = '{';
#define JSON_NOTIFY JSON1 _NOTIFY JSON2
#define JSON_DEVDETAILS JSON1 _DEVDETAILS JSON2
#define JSON_BYE JSON1 _BYE JSON1
#define JSON_RESTART JSON1 _RESTART JSON1
#define JSON_CLOSE JSON3
#define JSON_END JSON4
@ -479,6 +481,12 @@ static int my_thr_id = 0; @@ -479,6 +481,12 @@ static int my_thr_id = 0;
static int bye = 0;
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
struct IP4ACCESS {
@ -612,7 +620,7 @@ static int pgadevice(int pgaid) @@ -612,7 +620,7 @@ static int pgadevice(int pgaid)
}
#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
// and send_result() adds JSON_END at the end
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 @@ -1811,22 +1819,26 @@ static void gpuvddc(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, boo
#endif
}
static void send_result(SOCKETTYPE c, bool isjson);
void doquit(SOCKETTYPE c, __maybe_unused char *param, bool isjson)
void doquit(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
{
if (isjson)
strcpy(io_buffer, JSON_START JSON_BYE);
else
strcpy(io_buffer, _BYE);
send_result(c, isjson);
*io_buffer = '\0';
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)
@ -2017,6 +2029,7 @@ struct CMDS { @@ -2017,6 +2029,7 @@ struct CMDS {
{ "privileged", privileged, true },
{ "notify", notify, false },
{ "devdetails", devdetails, false },
{ "restart", dorestart, true },
{ NULL, NULL, false }
};
@ -2041,11 +2054,12 @@ static void send_result(SOCKETTYPE c, bool isjson) @@ -2041,11 +2054,12 @@ static void send_result(SOCKETTYPE c, bool isjson)
else
applog(LOG_DEBUG, "API: sent %d", n);
}
}
static void tidyup(__maybe_unused void *arg)
{
mutex_lock(&quit_restart_lock);
bye = 1;
if (sock != INVSOCK) {
@ -2068,6 +2082,8 @@ static void tidyup(__maybe_unused void *arg) @@ -2068,6 +2082,8 @@ static void tidyup(__maybe_unused void *arg)
free(io_buffer);
io_buffer = NULL;
}
mutex_unlock(&quit_restart_lock);
}
/*
@ -2172,8 +2188,37 @@ popipo: @@ -2172,8 +2188,37 @@ popipo:
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)
{
struct thr_info bye_thr;
char buf[BUFSIZ];
char param_buf[BUFSIZ];
const char *localaddr = "127.0.0.1";
@ -2197,6 +2242,8 @@ void api(int api_thr_id) @@ -2197,6 +2242,8 @@ void api(int api_thr_id)
bool did;
int i;
mutex_init(&quit_restart_lock);
pthread_cleanup_push(tidyup, NULL);
my_thr_id = api_thr_id;
@ -2408,4 +2455,33 @@ void api(int api_thr_id) @@ -2408,4 +2455,33 @@ void api(int api_thr_id)
}
die:
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);
}

Loading…
Cancel
Save