core to app quit request

svn path=/trunk/boinc/; revision=1054
This commit is contained in:
Eric Heien 2003-03-12 18:15:48 +00:00
parent 098073dfa6
commit 9572d88f59
5 changed files with 31 additions and 56 deletions

View File

@ -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 ) {

View 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);

View File

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

View File

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

View File

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