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:
This defaults to the cgminer version but is the value of --api-description This defaults to the cgminer version but is the value of --api-description
if it was specified at runtime. 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: 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
stating success or failure saving the cgminer config stating success or failure saving the cgminer config
to filename 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 reply before cgminer quits
notify NOTIFY The last status and history count of each devices problem 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
by the 'devs' command by the 'devs' command
e.g. DEVDETAILS=0,Name=GPU,ID=0,Driver=opencl,...| 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 When you enable, disable or restart a GPU or PGA, you will also get Thread messages
in the cgminer status window in the cgminer status window

96
api.c

@ -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);
} }

Loading…
Cancel
Save