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);
|
||||
#else
|
||||
extern void boinc_catch_signal(int signal);
|
||||
extern void boinc_quit(int sig);
|
||||
#endif
|
||||
|
||||
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 time_until_checkpoint;
|
||||
static double time_until_fraction_done_update;
|
||||
static double time_until_quit_check;
|
||||
static double fraction_done;
|
||||
static double last_checkpoint_cpu_time;
|
||||
static bool ready_to_checkpoint = false;
|
||||
static bool check_quit = false;
|
||||
static bool write_frac_done = false;
|
||||
static bool this_process_active;
|
||||
static bool time_to_quit = false;
|
||||
|
@ -161,7 +160,6 @@ int boinc_init() {
|
|||
#endif
|
||||
time_until_checkpoint = aid.checkpoint_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;
|
||||
|
||||
boinc_install_signal_handlers();
|
||||
|
@ -177,7 +175,7 @@ int boinc_install_signal_handlers() {
|
|||
#ifdef HAVE_SIGNAL_H
|
||||
signal( SIGHUP, boinc_catch_signal ); // terminal line hangup
|
||||
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( SIGABRT, boinc_catch_signal ); // abort(2) call
|
||||
signal( SIGBUS, boinc_catch_signal ); // bus error
|
||||
|
@ -244,7 +242,6 @@ void boinc_catch_signal(int signal) {
|
|||
switch(signal) {
|
||||
case SIGHUP: fprintf( stderr, "SIGHUP: terminal line hangup" ); 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 SIGABRT: fprintf( stderr, "SIGABRT: abort called" ); break;
|
||||
case SIGBUS: fprintf( stderr, "SIGBUS: bus error" ); break;
|
||||
|
@ -256,6 +253,11 @@ void boinc_catch_signal(int signal) {
|
|||
fprintf( stderr, "\nExiting...\n" );
|
||||
exit(ERR_SIGNAL_CATCH);
|
||||
}
|
||||
|
||||
void boinc_quit(int sig) {
|
||||
signal( SIGQUIT, boinc_quit ); // reset signal
|
||||
time_to_quit = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
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() {
|
||||
if (check_quit) {
|
||||
FILE* f = fopen(QUIT_FILE, "r");
|
||||
if(f) {
|
||||
parse_quit_file(f,time_to_quit);
|
||||
fclose(f);
|
||||
}
|
||||
time_until_quit_check = 1; // reset to 1 second
|
||||
check_quit = false;
|
||||
#ifdef _WIN32
|
||||
DWORD eventState;
|
||||
// Check if core client has requested us to exit
|
||||
WaitForSingleObject(quitRequestEvent, 0L);
|
||||
|
||||
switch (eventState) {
|
||||
case WAIT_OBJECT_0:
|
||||
case WAIT_ABANDONED:
|
||||
}
|
||||
#endif
|
||||
|
||||
if (write_frac_done) {
|
||||
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) {
|
||||
time_until_fraction_done_update -= timer_period;
|
||||
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;
|
||||
}
|
||||
|
||||
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.
|
||||
// Also, give the tags better names
|
||||
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 write_fraction_done_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 GRAPHICS_DATA_FILE "graphics.xml"
|
||||
#define FD_INIT_FILE "fd_init.xml"
|
||||
#define FRACTION_DONE_FILE "fraction_done.xml"
|
||||
#define FRACTION_DONE_TEMP_FILE "fraction_done.tmp"
|
||||
#define QUIT_FILE "quit.xml"
|
||||
#define STDERR_FILE "stderr.txt"
|
||||
|
||||
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);
|
||||
|
||||
sprintf(temp, "%s%s%s", slot_dir, PATH_SEPARATOR, QUIT_FILE);
|
||||
file_delete(temp);
|
||||
|
||||
#ifdef _WIN32
|
||||
PROCESS_INFORMATION process_info;
|
||||
STARTUPINFO startup_info;
|
||||
SECURITY_ATTRIBUTES quit_handle_attrs;
|
||||
char slotdirpath[256];
|
||||
char cmd_line[512];
|
||||
int win_error;
|
||||
|
@ -282,6 +280,11 @@ int ACTIVE_TASK::start(bool first_time) {
|
|||
startup_info.lpReserved = NULL;
|
||||
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();
|
||||
|
||||
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
|
||||
//
|
||||
int ACTIVE_TASK::request_exit() {
|
||||
char quit_file[256];
|
||||
int retval;
|
||||
|
||||
get_slot_dir(slot, slot_dir);
|
||||
sprintf(quit_file, "%s%s%s", slot_dir, PATH_SEPARATOR, QUIT_FILE);
|
||||
FILE *fp = fopen(quit_file, "w");
|
||||
if (!fp) return ERR_FOPEN;
|
||||
retval = write_quit_file(fp);
|
||||
fclose(fp);
|
||||
if (retval) return retval;
|
||||
return 0;
|
||||
#ifdef _WIN32
|
||||
return !SetEvent(quitRequestEvent);
|
||||
#else
|
||||
return kill(pid, SIGQUIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
int ACTIVE_TASK::kill_task() {
|
||||
#ifdef _WIN32
|
||||
TerminateProcess(pid_handle, -1);
|
||||
return 0;
|
||||
return !TerminateProcess(pid_handle, -1);
|
||||
#else
|
||||
return kill(pid, SIGKILL);
|
||||
#endif
|
||||
|
@ -464,6 +460,7 @@ bool ACTIVE_TASK_SET::poll() {
|
|||
}
|
||||
CloseHandle(atp->pid_handle);
|
||||
CloseHandle(atp->thread_handle);
|
||||
CloseHandle(atp->quitRequestEvent);
|
||||
atp->read_stderr_file();
|
||||
clean_out_dir(atp->slot_dir);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ typedef int PROCESS_ID;
|
|||
class ACTIVE_TASK {
|
||||
public:
|
||||
#ifdef _WIN32
|
||||
HANDLE pid_handle,thread_handle;
|
||||
HANDLE pid_handle, thread_handle, quitRequestEvent;
|
||||
#endif
|
||||
RESULT* result;
|
||||
WORKUNIT* wup;
|
||||
|
|
Loading…
Reference in New Issue