diff --git a/api/boinc_api.C b/api/boinc_api.C
index 597229e841..6c462d4dd7 100644
--- a/api/boinc_api.C
+++ b/api/boinc_api.C
@@ -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, "\n");
- return 0;
-}
-
-int parse_quit_file(FILE* f, bool& quit) {
- char buf[256];
-
- while (fgets(buf, 256, f)) {
- if (match_tag(buf, "")) 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 ) {
diff --git a/api/boinc_api.h b/api/boinc_api.h
index a678a37ed7..aaf27ba9be 100755
--- a/api/boinc_api.h
+++ b/api/boinc_api.h
@@ -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);
diff --git a/client/app.C b/client/app.C
index 768e4b1a0f..289a7867ff 100644
--- a/client/app.C
+++ b/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);
}
diff --git a/client/app.h b/client/app.h
index 002a671bb3..a4b7f6aa27 100644
--- a/client/app.h
+++ b/client/app.h
@@ -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;
diff --git a/client/cs_apps.C b/client/cs_apps.C
index 63e6ba18dc..e06e565f73 100644
--- a/client/cs_apps.C
+++ b/client/cs_apps.C
@@ -51,7 +51,7 @@ int CLIENT_STATE::cleanup_and_exit() {
// don't return here - we'll exit anyway
}
retval = write_state_file();
- if (retval) {
+ if (retval) {
fprintf(stderr, "error: CLIENT_STATE.exit: write_state_file failed\n");
// don't return here - we'll exit anyway
}