mirror of https://github.com/BOINC/boinc.git
core to app quit request
svn path=/trunk/boinc/; revision=1054
This commit is contained in:
parent
098073dfa6
commit
9572d88f59
|
@ -81,6 +81,7 @@ extern BOOL win_loop_done;
|
||||||
LONG CALLBACK boinc_catch_signal(EXCEPTION_POINTERS *ExceptionInfo);
|
LONG CALLBACK boinc_catch_signal(EXCEPTION_POINTERS *ExceptionInfo);
|
||||||
#else
|
#else
|
||||||
extern void boinc_catch_signal(int signal);
|
extern void boinc_catch_signal(int signal);
|
||||||
|
extern void boinc_quit(int sig);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static APP_INIT_DATA aid;
|
static APP_INIT_DATA aid;
|
||||||
|
@ -88,11 +89,9 @@ GRAPHICS_INFO gi;
|
||||||
static double timer_period = 1.0/50.0; // 50 Hz timer
|
static double timer_period = 1.0/50.0; // 50 Hz timer
|
||||||
static double time_until_checkpoint;
|
static double time_until_checkpoint;
|
||||||
static double time_until_fraction_done_update;
|
static double time_until_fraction_done_update;
|
||||||
static double time_until_quit_check;
|
|
||||||
static double fraction_done;
|
static double fraction_done;
|
||||||
static double last_checkpoint_cpu_time;
|
static double last_checkpoint_cpu_time;
|
||||||
static bool ready_to_checkpoint = false;
|
static bool ready_to_checkpoint = false;
|
||||||
static bool check_quit = false;
|
|
||||||
static bool write_frac_done = false;
|
static bool write_frac_done = false;
|
||||||
static bool this_process_active;
|
static bool this_process_active;
|
||||||
static bool time_to_quit = false;
|
static bool time_to_quit = false;
|
||||||
|
@ -161,7 +160,6 @@ int boinc_init() {
|
||||||
#endif
|
#endif
|
||||||
time_until_checkpoint = aid.checkpoint_period;
|
time_until_checkpoint = aid.checkpoint_period;
|
||||||
time_until_fraction_done_update = aid.fraction_done_update_period;
|
time_until_fraction_done_update = aid.fraction_done_update_period;
|
||||||
time_until_quit_check = 1; // check every 1 second for quit request from core client
|
|
||||||
this_process_active = true;
|
this_process_active = true;
|
||||||
|
|
||||||
boinc_install_signal_handlers();
|
boinc_install_signal_handlers();
|
||||||
|
@ -177,7 +175,7 @@ int boinc_install_signal_handlers() {
|
||||||
#ifdef HAVE_SIGNAL_H
|
#ifdef HAVE_SIGNAL_H
|
||||||
signal( SIGHUP, boinc_catch_signal ); // terminal line hangup
|
signal( SIGHUP, boinc_catch_signal ); // terminal line hangup
|
||||||
signal( SIGINT, boinc_catch_signal ); // interrupt program
|
signal( SIGINT, boinc_catch_signal ); // interrupt program
|
||||||
signal( SIGQUIT, boinc_catch_signal ); // quit program
|
signal( SIGQUIT, boinc_quit ); // quit program
|
||||||
signal( SIGILL, boinc_catch_signal ); // illegal instruction
|
signal( SIGILL, boinc_catch_signal ); // illegal instruction
|
||||||
signal( SIGABRT, boinc_catch_signal ); // abort(2) call
|
signal( SIGABRT, boinc_catch_signal ); // abort(2) call
|
||||||
signal( SIGBUS, boinc_catch_signal ); // bus error
|
signal( SIGBUS, boinc_catch_signal ); // bus error
|
||||||
|
@ -244,7 +242,6 @@ void boinc_catch_signal(int signal) {
|
||||||
switch(signal) {
|
switch(signal) {
|
||||||
case SIGHUP: fprintf( stderr, "SIGHUP: terminal line hangup" ); break;
|
case SIGHUP: fprintf( stderr, "SIGHUP: terminal line hangup" ); break;
|
||||||
case SIGINT: fprintf( stderr, "SIGINT: interrupt program" ); break;
|
case SIGINT: fprintf( stderr, "SIGINT: interrupt program" ); break;
|
||||||
case SIGQUIT: fprintf( stderr, "SIGQUIT: quit program" ); break;
|
|
||||||
case SIGILL: fprintf( stderr, "SIGILL: illegal instruction" ); break;
|
case SIGILL: fprintf( stderr, "SIGILL: illegal instruction" ); break;
|
||||||
case SIGABRT: fprintf( stderr, "SIGABRT: abort called" ); break;
|
case SIGABRT: fprintf( stderr, "SIGABRT: abort called" ); break;
|
||||||
case SIGBUS: fprintf( stderr, "SIGBUS: bus error" ); break;
|
case SIGBUS: fprintf( stderr, "SIGBUS: bus error" ); break;
|
||||||
|
@ -256,6 +253,11 @@ void boinc_catch_signal(int signal) {
|
||||||
fprintf( stderr, "\nExiting...\n" );
|
fprintf( stderr, "\nExiting...\n" );
|
||||||
exit(ERR_SIGNAL_CATCH);
|
exit(ERR_SIGNAL_CATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void boinc_quit(int sig) {
|
||||||
|
signal( SIGQUIT, boinc_quit ); // reset signal
|
||||||
|
time_to_quit = true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int boinc_finish(int status) {
|
int boinc_finish(int status) {
|
||||||
|
@ -306,15 +308,16 @@ int boinc_resolve_filename(char *virtual_name, char *physical_name, int len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boinc_time_to_checkpoint() {
|
bool boinc_time_to_checkpoint() {
|
||||||
if (check_quit) {
|
#ifdef _WIN32
|
||||||
FILE* f = fopen(QUIT_FILE, "r");
|
DWORD eventState;
|
||||||
if(f) {
|
// Check if core client has requested us to exit
|
||||||
parse_quit_file(f,time_to_quit);
|
WaitForSingleObject(quitRequestEvent, 0L);
|
||||||
fclose(f);
|
|
||||||
}
|
switch (eventState) {
|
||||||
time_until_quit_check = 1; // reset to 1 second
|
case WAIT_OBJECT_0:
|
||||||
check_quit = false;
|
case WAIT_ABANDONED:
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (write_frac_done) {
|
if (write_frac_done) {
|
||||||
write_fraction_done_file(fraction_done, boinc_cpu_time(), last_checkpoint_cpu_time);
|
write_fraction_done_file(fraction_done, boinc_cpu_time(), last_checkpoint_cpu_time);
|
||||||
|
@ -435,13 +438,6 @@ void on_timer(int a) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!check_quit) {
|
|
||||||
time_until_quit_check -= timer_period;
|
|
||||||
if (time_until_quit_check <= 0) {
|
|
||||||
check_quit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!write_frac_done && this_process_active) {
|
if (!write_frac_done && this_process_active) {
|
||||||
time_until_fraction_done_update -= timer_period;
|
time_until_fraction_done_update -= timer_period;
|
||||||
if (time_until_fraction_done_update <= 0) {
|
if (time_until_fraction_done_update <= 0) {
|
||||||
|
@ -592,21 +588,6 @@ int parse_fraction_done_file(FILE* f, double& pct, double& cpu, double& checkpoi
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_quit_file(FILE* f) {
|
|
||||||
fprintf(f, "<quit/>\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int parse_quit_file(FILE* f, bool& quit) {
|
|
||||||
char buf[256];
|
|
||||||
|
|
||||||
while (fgets(buf, 256, f)) {
|
|
||||||
if (match_tag(buf, "<quit/>")) quit = true;
|
|
||||||
else fprintf(stderr, "parse_quit_file: unrecognized %s", buf);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: this should handle arbitrarily many fd/filename pairs.
|
// TODO: this should handle arbitrarily many fd/filename pairs.
|
||||||
// Also, give the tags better names
|
// Also, give the tags better names
|
||||||
int write_fd_init_file(FILE* f, char *file_name, int fdesc, int input_file ) {
|
int write_fd_init_file(FILE* f, char *file_name, int fdesc, int input_file ) {
|
||||||
|
|
|
@ -84,15 +84,12 @@ int write_fd_init_file(FILE*, char*, int, int);
|
||||||
int parse_fd_init_file(FILE*);
|
int parse_fd_init_file(FILE*);
|
||||||
int write_fraction_done_file(double, double, double);
|
int write_fraction_done_file(double, double, double);
|
||||||
int parse_fraction_done_file(FILE*, double&, double&, double&);
|
int parse_fraction_done_file(FILE*, double&, double&, double&);
|
||||||
int write_quit_file(FILE* f);
|
|
||||||
int parse_quit_file(FILE* f, bool& quit);
|
|
||||||
|
|
||||||
#define INIT_DATA_FILE "init_data.xml"
|
#define INIT_DATA_FILE "init_data.xml"
|
||||||
#define GRAPHICS_DATA_FILE "graphics.xml"
|
#define GRAPHICS_DATA_FILE "graphics.xml"
|
||||||
#define FD_INIT_FILE "fd_init.xml"
|
#define FD_INIT_FILE "fd_init.xml"
|
||||||
#define FRACTION_DONE_FILE "fraction_done.xml"
|
#define FRACTION_DONE_FILE "fraction_done.xml"
|
||||||
#define FRACTION_DONE_TEMP_FILE "fraction_done.tmp"
|
#define FRACTION_DONE_TEMP_FILE "fraction_done.tmp"
|
||||||
#define QUIT_FILE "quit.xml"
|
|
||||||
#define STDERR_FILE "stderr.txt"
|
#define STDERR_FILE "stderr.txt"
|
||||||
|
|
||||||
int set_timer(double period);
|
int set_timer(double period);
|
||||||
|
|
29
client/app.C
29
client/app.C
|
@ -266,12 +266,10 @@ int ACTIVE_TASK::start(bool first_time) {
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
sprintf(temp, "%s%s%s", slot_dir, PATH_SEPARATOR, QUIT_FILE);
|
|
||||||
file_delete(temp);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
PROCESS_INFORMATION process_info;
|
PROCESS_INFORMATION process_info;
|
||||||
STARTUPINFO startup_info;
|
STARTUPINFO startup_info;
|
||||||
|
SECURITY_ATTRIBUTES quit_handle_attrs;
|
||||||
char slotdirpath[256];
|
char slotdirpath[256];
|
||||||
char cmd_line[512];
|
char cmd_line[512];
|
||||||
int win_error;
|
int win_error;
|
||||||
|
@ -282,6 +280,11 @@ int ACTIVE_TASK::start(bool first_time) {
|
||||||
startup_info.lpReserved = NULL;
|
startup_info.lpReserved = NULL;
|
||||||
startup_info.lpDesktop = "";
|
startup_info.lpDesktop = "";
|
||||||
|
|
||||||
|
quit_handle_attrs.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
quit_handle_attrs.lpSecurityDescriptor = NULL;
|
||||||
|
quit_handle_attrs.bInheritHandle = TRUE;
|
||||||
|
quitRequestEvent = CreateEvent( &quit_handle_attrs, FALSE, FALSE,
|
||||||
|
|
||||||
// NOTE: in Windows, stderr is redirected within boinc_init();
|
// NOTE: in Windows, stderr is redirected within boinc_init();
|
||||||
|
|
||||||
sprintf( cmd_line, "%s %s", exec_path, wup->command_line );
|
sprintf( cmd_line, "%s %s", exec_path, wup->command_line );
|
||||||
|
@ -360,23 +363,16 @@ int ACTIVE_TASK::start(bool first_time) {
|
||||||
// If it doesn't exit within a set time (seconds), the process is terminated
|
// If it doesn't exit within a set time (seconds), the process is terminated
|
||||||
//
|
//
|
||||||
int ACTIVE_TASK::request_exit() {
|
int ACTIVE_TASK::request_exit() {
|
||||||
char quit_file[256];
|
#ifdef _WIN32
|
||||||
int retval;
|
return !SetEvent(quitRequestEvent);
|
||||||
|
#else
|
||||||
get_slot_dir(slot, slot_dir);
|
return kill(pid, SIGQUIT);
|
||||||
sprintf(quit_file, "%s%s%s", slot_dir, PATH_SEPARATOR, QUIT_FILE);
|
#endif
|
||||||
FILE *fp = fopen(quit_file, "w");
|
|
||||||
if (!fp) return ERR_FOPEN;
|
|
||||||
retval = write_quit_file(fp);
|
|
||||||
fclose(fp);
|
|
||||||
if (retval) return retval;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ACTIVE_TASK::kill_task() {
|
int ACTIVE_TASK::kill_task() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
TerminateProcess(pid_handle, -1);
|
return !TerminateProcess(pid_handle, -1);
|
||||||
return 0;
|
|
||||||
#else
|
#else
|
||||||
return kill(pid, SIGKILL);
|
return kill(pid, SIGKILL);
|
||||||
#endif
|
#endif
|
||||||
|
@ -464,6 +460,7 @@ bool ACTIVE_TASK_SET::poll() {
|
||||||
}
|
}
|
||||||
CloseHandle(atp->pid_handle);
|
CloseHandle(atp->pid_handle);
|
||||||
CloseHandle(atp->thread_handle);
|
CloseHandle(atp->thread_handle);
|
||||||
|
CloseHandle(atp->quitRequestEvent);
|
||||||
atp->read_stderr_file();
|
atp->read_stderr_file();
|
||||||
clean_out_dir(atp->slot_dir);
|
clean_out_dir(atp->slot_dir);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ typedef int PROCESS_ID;
|
||||||
class ACTIVE_TASK {
|
class ACTIVE_TASK {
|
||||||
public:
|
public:
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HANDLE pid_handle,thread_handle;
|
HANDLE pid_handle, thread_handle, quitRequestEvent;
|
||||||
#endif
|
#endif
|
||||||
RESULT* result;
|
RESULT* result;
|
||||||
WORKUNIT* wup;
|
WORKUNIT* wup;
|
||||||
|
|
|
@ -51,7 +51,7 @@ int CLIENT_STATE::cleanup_and_exit() {
|
||||||
// don't return here - we'll exit anyway
|
// don't return here - we'll exit anyway
|
||||||
}
|
}
|
||||||
retval = write_state_file();
|
retval = write_state_file();
|
||||||
if (retval) {
|
if (retval) {
|
||||||
fprintf(stderr, "error: CLIENT_STATE.exit: write_state_file failed\n");
|
fprintf(stderr, "error: CLIENT_STATE.exit: write_state_file failed\n");
|
||||||
// don't return here - we'll exit anyway
|
// don't return here - we'll exit anyway
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue