mirror of
https://github.com/GOSTSec/sgminer
synced 2025-02-02 10:04:33 +00:00
Implement signal handler and clean up properly.
This commit is contained in:
parent
02cd113cd9
commit
20b3e07f63
81
main.c
81
main.c
@ -24,6 +24,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <signal.h>
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#endif
|
#endif
|
||||||
@ -153,6 +154,7 @@ struct thr_info *thr_info;
|
|||||||
static int work_thr_id;
|
static int work_thr_id;
|
||||||
int longpoll_thr_id;
|
int longpoll_thr_id;
|
||||||
static int stage_thr_id;
|
static int stage_thr_id;
|
||||||
|
static int watchdog_thr_id;
|
||||||
struct work_restart *work_restart = NULL;
|
struct work_restart *work_restart = NULL;
|
||||||
static pthread_mutex_t hash_lock;
|
static pthread_mutex_t hash_lock;
|
||||||
static pthread_mutex_t qd_lock;
|
static pthread_mutex_t qd_lock;
|
||||||
@ -732,8 +734,29 @@ static void workio_cmd_free(struct workio_cmd *wc)
|
|||||||
static void kill_work(void)
|
static void kill_work(void)
|
||||||
{
|
{
|
||||||
struct workio_cmd *wc;
|
struct workio_cmd *wc;
|
||||||
|
struct thr_info *thr;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
applog(LOG_INFO, "Received kill message");
|
applog(LOG_INFO, "Received kill message");
|
||||||
|
|
||||||
|
/* Kill the watchdog thread */
|
||||||
|
thr = &thr_info[watchdog_thr_id];
|
||||||
|
pthread_cancel(thr->pth);
|
||||||
|
|
||||||
|
/* Stop the mining threads*/
|
||||||
|
for (i = 0; i < mining_threads; i++) {
|
||||||
|
thr = &thr_info[i];
|
||||||
|
tq_freeze(thr->q);
|
||||||
|
/* No need to check if this succeeds or not */
|
||||||
|
pthread_cancel(thr->pth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stop the others */
|
||||||
|
thr = &thr_info[stage_thr_id];
|
||||||
|
pthread_cancel(thr->pth);
|
||||||
|
thr = &thr_info[longpoll_thr_id];
|
||||||
|
pthread_cancel(thr->pth);
|
||||||
|
|
||||||
wc = calloc(1, sizeof(*wc));
|
wc = calloc(1, sizeof(*wc));
|
||||||
if (unlikely(!wc)) {
|
if (unlikely(!wc)) {
|
||||||
applog(LOG_ERR, "Failed to calloc wc in kill_work");
|
applog(LOG_ERR, "Failed to calloc wc in kill_work");
|
||||||
@ -748,6 +771,34 @@ static void kill_work(void)
|
|||||||
applog(LOG_ERR, "Failed to tq_push work in kill_work");
|
applog(LOG_ERR, "Failed to tq_push work in kill_work");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shutdown_cleanup(void)
|
||||||
|
{
|
||||||
|
curl_global_cleanup();
|
||||||
|
if (gpu_threads) {
|
||||||
|
gpu_threads = 0;
|
||||||
|
free(gpus);
|
||||||
|
}
|
||||||
|
if (opt_n_threads) {
|
||||||
|
opt_n_threads = 0;
|
||||||
|
free(cpus);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curses_active) {
|
||||||
|
delwin(logwin);
|
||||||
|
delwin(statuswin);
|
||||||
|
delwin(mainwin);
|
||||||
|
endwin();
|
||||||
|
refresh();
|
||||||
|
curses_active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sighandler(int sig)
|
||||||
|
{
|
||||||
|
kill_work();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *get_work_thread(void *userdata)
|
static void *get_work_thread(void *userdata)
|
||||||
@ -892,6 +943,8 @@ static void *stage_thread(void *userdata)
|
|||||||
struct thr_info *mythr = userdata;
|
struct thr_info *mythr = userdata;
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
||||||
|
|
||||||
while (ok) {
|
while (ok) {
|
||||||
struct work *work = NULL;
|
struct work *work = NULL;
|
||||||
char *hexstr;
|
char *hexstr;
|
||||||
@ -1658,6 +1711,8 @@ static void *longpoll_thread(void *userdata)
|
|||||||
bool need_slash = false;
|
bool need_slash = false;
|
||||||
int failures = 0;
|
int failures = 0;
|
||||||
|
|
||||||
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
||||||
|
|
||||||
hdr_path = tq_pop(mythr->q, NULL);
|
hdr_path = tq_pop(mythr->q, NULL);
|
||||||
if (!hdr_path)
|
if (!hdr_path)
|
||||||
goto out;
|
goto out;
|
||||||
@ -1831,6 +1886,8 @@ static void *watchdog_thread(void *userdata)
|
|||||||
const unsigned int interval = opt_log_interval / 2 ? : 1;
|
const unsigned int interval = opt_log_interval / 2 ? : 1;
|
||||||
struct timeval zero_tv;
|
struct timeval zero_tv;
|
||||||
|
|
||||||
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
||||||
|
|
||||||
memset(&zero_tv, 0, sizeof(struct timeval));
|
memset(&zero_tv, 0, sizeof(struct timeval));
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -1880,8 +1937,9 @@ static void *watchdog_thread(void *userdata)
|
|||||||
|
|
||||||
int main (int argc, char *argv[])
|
int main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct thr_info *thr;
|
|
||||||
unsigned int i, j = 0, x, y;
|
unsigned int i, j = 0, x, y;
|
||||||
|
struct sigaction handler;
|
||||||
|
struct thr_info *thr;
|
||||||
char name[256];
|
char name[256];
|
||||||
|
|
||||||
if (unlikely(pthread_mutex_init(&hash_lock, NULL)))
|
if (unlikely(pthread_mutex_init(&hash_lock, NULL)))
|
||||||
@ -1893,13 +1951,16 @@ int main (int argc, char *argv[])
|
|||||||
if (unlikely(pthread_mutex_init(&curses_lock, NULL)))
|
if (unlikely(pthread_mutex_init(&curses_lock, NULL)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
handler.sa_handler = &sighandler;
|
||||||
|
sigaction(SIGTERM, &handler, 0);
|
||||||
|
sigaction(SIGINT, &handler, 0);
|
||||||
|
|
||||||
for (i = 0; i < 36; i++) {
|
for (i = 0; i < 36; i++) {
|
||||||
strcat(blank, "0");
|
strcat(blank, "0");
|
||||||
strcat(current_block, "0");
|
strcat(current_block, "0");
|
||||||
strcat(longpoll_block, "0");
|
strcat(longpoll_block, "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
opt_n_threads = num_processors = 1;
|
opt_n_threads = num_processors = 1;
|
||||||
#else
|
#else
|
||||||
@ -2122,7 +2183,8 @@ int main (int argc, char *argv[])
|
|||||||
opt_n_threads,
|
opt_n_threads,
|
||||||
algo_names[opt_algo]);
|
algo_names[opt_algo]);
|
||||||
|
|
||||||
thr = &thr_info[mining_threads + 2];
|
watchdog_thr_id = mining_threads + 2;
|
||||||
|
thr = &thr_info[watchdog_thr_id];
|
||||||
/* start wakeup thread */
|
/* start wakeup thread */
|
||||||
if (pthread_create(&thr->pth, NULL, watchdog_thread, NULL)) {
|
if (pthread_create(&thr->pth, NULL, watchdog_thread, NULL)) {
|
||||||
applog(LOG_ERR, "wakeup thread create failed");
|
applog(LOG_ERR, "wakeup thread create failed");
|
||||||
@ -2161,20 +2223,9 @@ int main (int argc, char *argv[])
|
|||||||
|
|
||||||
/* main loop - simply wait for workio thread to exit */
|
/* main loop - simply wait for workio thread to exit */
|
||||||
pthread_join(thr_info[work_thr_id].pth, NULL);
|
pthread_join(thr_info[work_thr_id].pth, NULL);
|
||||||
curl_global_cleanup();
|
|
||||||
if (gpu_threads)
|
|
||||||
free(gpus);
|
|
||||||
if (opt_n_threads)
|
|
||||||
free(cpus);
|
|
||||||
|
|
||||||
applog(LOG_INFO, "workio thread dead, exiting.");
|
applog(LOG_INFO, "workio thread dead, exiting.");
|
||||||
|
|
||||||
if (curses_active) {
|
shutdown_cleanup();
|
||||||
delwin(logwin);
|
|
||||||
delwin(statuswin);
|
|
||||||
endwin();
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user