From 64b871f819e4057f3dbaaa9a8ff58db748cd9449 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 28 Apr 2005 23:19:58 +0000 Subject: [PATCH] *** empty log message *** svn path=/trunk/boinc/; revision=5962 --- api/boinc_api.C | 35 +++++++++----- api/boinc_api.h | 2 + apps/upper_case.C | 100 +++++++++++++++++++++++----------------- checkin_notes | 46 ++++++++++++++---- client/app.C | 62 ++++++++++++++++++++++++- client/app.h | 4 ++ client/app_control.C | 29 ++---------- client/client_state.C | 1 + client/client_types.C | 18 ++++++++ client/client_types.h | 2 + client/cs_apps.C | 1 + client/cs_files.C | 2 + client/gui_rpc_server.C | 2 +- lib/app_ipc.h | 10 ++-- lib/error_numbers.h | 2 + lib/filesys.C | 2 +- lib/mfile.C | 4 +- lib/network.C | 6 +-- lib/parse.C | 10 +++- 19 files changed, 238 insertions(+), 100 deletions(-) diff --git a/api/boinc_api.C b/api/boinc_api.C index 067a4e3f64..f6eb191a14 100644 --- a/api/boinc_api.C +++ b/api/boinc_api.C @@ -70,7 +70,7 @@ static volatile double last_wu_cpu_time; static bool standalone = false; static double initial_wu_cpu_time; static volatile bool have_new_trickle_up = false; -static volatile bool have_trickle_down = true; +static volatile bool have_trickle_down = true; // on first call, scan slot dir for msgs static volatile int heartbeat_giveup_time; static volatile bool heartbeat_active; @@ -430,22 +430,31 @@ static void handle_heartbeat_msg() { } static void handle_upload_file_status() { - char path[256], buf[256]; + char path[256], buf[256], log_name[256]; std::string filename; int status; relative_to_absolute("", path); DirScanner dirscan(path); while (dirscan.scan(filename)) { - fprintf(stderr, "scan: %s\n", filename.c_str()); + strcpy(buf, filename.c_str()); + if (strstr(buf, UPLOAD_FILE_STATUS_PREFIX) != buf) continue; + strcpy(log_name, buf+strlen(UPLOAD_FILE_STATUS_PREFIX)); FILE* f = boinc_fopen(filename.c_str(), "r"); - if (!f) continue; + if (!f) { + fprintf(stderr, "handle_file_upload_status: can't open %s\n", filename.c_str()); + continue; + } fgets(buf, 256, f); - parse_int(buf, "", status); - UPLOAD_FILE_STATUS uf; - uf.name = filename; - uf.status = status; - upload_file_status.push_back(uf); + fclose(f); + if (parse_int(buf, "", status)) { + UPLOAD_FILE_STATUS uf; + uf.name = std::string(log_name); + uf.status = status; + upload_file_status.push_back(uf); + } else { + fprintf(stderr, "handle_upload_file_status: can't parse %s\n", buf); + } } } @@ -457,7 +466,7 @@ static void handle_trickle_down_msg() { if (match_tag(buf, "")) { have_trickle_down = true; } - if (match_tag(buf, "")) { + if (match_tag(buf, "")) { handle_upload_file_status(); } } @@ -700,8 +709,12 @@ bool boinc_receive_trickle_down(char* buf, int len) { int boinc_upload_file(std::string& name) { char buf[256]; + std::string pname; + int retval; - sprintf(buf, "boinc_ufr_%s", name.c_str()); + retval = boinc_resolve_filename_s(name.c_str(), pname); + if (retval) return retval; + sprintf(buf, "%s%s", UPLOAD_FILE_REQ_PREFIX, name.c_str()); FILE* f = boinc_fopen(buf, "w"); if (!f) return ERR_FOPEN; have_new_upload_file = true; diff --git a/api/boinc_api.h b/api/boinc_api.h index 1028d1ae5b..ee9968acdb 100755 --- a/api/boinc_api.h +++ b/api/boinc_api.h @@ -97,6 +97,8 @@ extern int boinc_get_status(BOINC_STATUS&); extern int boinc_resolve_filename_s(const char*, std::string&); extern int boinc_get_init_data(APP_INIT_DATA&); extern int boinc_wu_cpu_time(double&); +extern int boinc_upload_file(std::string& name); +extern int boinc_upload_status(std::string& name); /////////// API ENDS HERE diff --git a/apps/upper_case.C b/apps/upper_case.C index f6b6817154..0be1735e17 100755 --- a/apps/upper_case.C +++ b/apps/upper_case.C @@ -53,6 +53,8 @@ using std::string; #define CHECKPOINT_FILE "upper_case_state" +#define INPUT_FILENAME "in" +#define OUTPUT_FILENAME "out" #ifdef BOINC_APP_GRAPHICS char display_buf[10]; @@ -60,9 +62,10 @@ double xPos=0, yPos=0; double xDelta=0.03, yDelta=0.07; #endif -bool run_slow=false, raise_signal=false, random_exit=false; -bool cpu_time=false; -time_t my_start_time; +bool run_slow; +bool raise_signal; +bool random_exit; +bool cpu_time; APP_INIT_DATA uc_aid; int do_checkpoint(MFILE& mf, int nchars) { @@ -85,6 +88,35 @@ int do_checkpoint(MFILE& mf, int nchars) { return 0; } +static void use_some_cpu() { +#if 0 + double j = 3.14159; + int i, n = 0; + for (i=0; i<20000000; i++) { + n++; + j *= n+j-3.14159; + j /= (float)n; + } +#endif + boinc_sleep(5.0); +} + +#define TEST_INT_UPLOAD 1 + +#ifdef TEST_INT_UPLOAD +#define UPLOAD_FILE_NAME "int_upload" + +int write_upload_file() { + std::string physname; + int retval = boinc_resolve_filename_s(UPLOAD_FILE_NAME, physname); + if (retval) return retval; + FILE* f = boinc_fopen(physname.c_str(), "w"); + fprintf(f, "blah blah\nfoobar\n"); + fclose(f); + return 0; +} +#endif + #ifdef _WIN32 extern int main(int argc, char** argv); @@ -101,26 +133,21 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR Args, int WinMode #endif int main(int argc, char **argv) { - int c, nchars = 0, retval, i, n; - double j, fsize; + int c, nchars = 0, retval, i; + double fsize; char resolved_name[512]; MFILE out; FILE* state, *in; - int flags = 0; - my_start_time = time(0); - - - flags = + int flags = BOINC_DIAG_DUMPCALLSTACKENABLED | BOINC_DIAG_HEAPCHECKENABLED | BOINC_DIAG_REDIRECTSTDERR; -#if 0 - if (standalone) - flags |= BOINC_DIAG_TRACETOSTDERR; -#endif + boinc_init_diagnostics(flags); + retval = boinc_init(); + if (retval) exit(retval); // NOTE: if you change output here, remember to change the output that // test_uc.py pattern-matches against. @@ -133,15 +160,6 @@ int main(int argc, char **argv) { if (!strcmp(argv[i], "-exit")) random_exit = true; } - retval = boinc_init(); - if (retval) exit(retval); - - // can't write to stderr until after boinc_init() - // - for (i=0; i\n%s\n\n", uc_aid.app_preferences - // ); fprintf(stderr, "APP: upper_case: starting, argc %d\n", argc); - boinc_resolve_filename("in", resolved_name, sizeof(resolved_name)); - in = fopen(resolved_name, "r"); + boinc_resolve_filename(INPUT_FILENAME, resolved_name, sizeof(resolved_name)); + in = boinc_fopen(resolved_name, "r"); if (in == NULL) { fprintf( stderr, @@ -169,15 +184,15 @@ int main(int argc, char **argv) { file_size(resolved_name, fsize); boinc_resolve_filename(CHECKPOINT_FILE, resolved_name, sizeof(resolved_name)); - state = fopen(resolved_name, "r"); + state = boinc_fopen(resolved_name, "r"); if (state) { fscanf(state, "%d", &nchars); printf("nchars %d\n", nchars); fseek(in, nchars, SEEK_SET); - boinc_resolve_filename("out", resolved_name, sizeof(resolved_name)); + boinc_resolve_filename(OUTPUT_FILENAME, resolved_name, sizeof(resolved_name)); retval = out.open(resolved_name, "a"); } else { - boinc_resolve_filename("out", resolved_name, sizeof(resolved_name)); + boinc_resolve_filename(OUTPUT_FILENAME, resolved_name, sizeof(resolved_name)); retval = out.open(resolved_name, "w"); } if (retval) { @@ -197,16 +212,19 @@ int main(int argc, char **argv) { out._putchar(c); nchars++; +#ifdef TEST_INT_UPLOAD + if (nchars == fsize/2) { + retval = write_upload_file(); + fprintf(stderr, "write_upload_file() %d\n", retval); + retval = boinc_upload_file(std::string(UPLOAD_FILE_NAME)); + fprintf(stderr, "boinc_upload_file() %d\n", retval); + } else if (nchars >= fsize/2) { + retval = boinc_upload_status(std::string(UPLOAD_FILE_NAME)); + fprintf(stderr, "upload status %d\n", retval); + } +#endif if (cpu_time) { - n = 0; - j = 3.14159; - for(i=0; i<20000000; i++) { - n++; - j *= n+j-3.14159; - j /= (float)n; - } - - if (n==j) n = 0; + use_some_cpu(); } if (run_slow) { @@ -243,8 +261,6 @@ int main(int argc, char **argv) { } if (random_exit) exit(-10); fprintf(stderr, "APP: upper_case ending, wrote %d chars\n", nchars); - double cur_cpu; - boinc_wu_cpu_time(cur_cpu); #ifdef BOINC_APP_GRAPHICS boinc_finish_opengl(); diff --git a/checkin_notes b/checkin_notes index 7ca0455908..c487e059ba 100755 --- a/checkin_notes +++ b/checkin_notes @@ -27752,12 +27752,12 @@ David 26 April 2005 boinc_cli.vcproj Charlie 27 April 2005 -Mac: created installer. Changed working directory from -user-specific "~/Library/Application Support/BOINC Data" -to global "/Library/Application Support/BOINC Data". -Fixed CViewProjects::OnProjectWebsiteClicked for Mac. -Added progress display to screensaver when no application -graphics. + Mac: created installer. Changed working directory from + user-specific "~/Library/Application Support/BOINC Data" + to global "/Library/Application Support/BOINC Data". + Fixed CViewProjects::OnProjectWebsiteClicked for Mac. + Added progress display to screensaver when no application + graphics. mac-installer/ LoginItemAPI.c (new) @@ -27811,9 +27811,9 @@ Janus 28 April 2005 userw.php Charlie 28 April 2005 -Mac: Clean up XCode project by removing unused libraries -and frameworks. -Update build instructions to include screensaver & installer. + Mac: Clean up XCode project by removing unused libraries + and frameworks. + Update build instructions to include screensaver & installer. mac_build/ HowToBuildBOINC_XCode.rtf @@ -27826,3 +27826,31 @@ Rom 28 April 2005 lib/ gui_roc_client.C, .h + +David 28 April 2005 + - debugged intermediate upload feature + - Got rid of some -1 returns. + A BOINC function should never return -1 + (or the return value of a system call) + since this discards info about where the error came from + - parse_double(): don't accept NaN or +- infinity + + api/ + boinc_api.C,h + apps/ + upper_case.C + client/ + app.C,h + app_control.C + client_state.C + client_types.C,h + cs_apps.C + cs_files.C + gui_rpc_server.C + lib/ + app_ipc.h + error_numbers.h + filesys.C + mfile.C + network.C + parse.C diff --git a/client/app.C b/client/app.C index ef47829ee3..339fc08061 100644 --- a/client/app.C +++ b/client/app.C @@ -100,6 +100,7 @@ ACTIVE_TASK::ACTIVE_TASK() { vm_bytes = 0; rss_bytes = 0; have_trickle_down = false; + send_upload_file_status = false; pending_suspend_via_quit = false; #ifdef _WIN32 pid_handle = 0; @@ -294,7 +295,7 @@ int ACTIVE_TASK::move_trickle_file() { // double ACTIVE_TASK::est_cpu_time_to_completion() { if (fraction_done <= 0 || fraction_done > 1) { - return -1; + return 0; } return (current_cpu_time / fraction_done) - current_cpu_time; } @@ -336,7 +337,7 @@ int ACTIVE_TASK_SET::get_free_slot() { } if (!found) return j; } - return -1; // probably never get here + return ERR_NOT_FOUND; // probably never get here } int ACTIVE_TASK::write(MIOFILE& fout) { @@ -515,4 +516,61 @@ void ACTIVE_TASK_SET::report_overdue(double now) { } } +// scan the slot directory, looking for files with names +// of the form boinc_ufr_X. +// Then mark file X as being present (and uploadable) +// +int ACTIVE_TASK::handle_upload_files() { + std::string filename; + char buf[256], path[256]; + + DirScanner dirscan(slot_dir); + while (dirscan.scan(filename)) { + strcpy(buf, filename.c_str()); + if (strstr(buf, UPLOAD_FILE_REQ_PREFIX) == buf) { + char* p = buf+strlen(UPLOAD_FILE_REQ_PREFIX); + FILE_INFO* fip = result->lookup_file_logical(p); + if (fip) { + fip->status = FILE_PRESENT; + } else { + msg_printf(0, MSG_ERROR, "Can't find %s", p); + } + sprintf(path, "%s/%s", slot_dir, buf); + boinc_delete_file(path); + } + } + return 0; +} + +void ACTIVE_TASK_SET::handle_upload_files() { + for (unsigned int i=0; ihandle_upload_files(); + } +} + +void ACTIVE_TASK::upload_notify_app(const FILE_INFO* fip, const FILE_REF* frp) { + char path[256]; + sprintf(path, "%s/%s%s", slot_dir, UPLOAD_FILE_STATUS_PREFIX, frp->open_name); + FILE* f = boinc_fopen(path, "w"); + if (!f) return; + fprintf(f, "%d\n", fip->status); + fclose(f); + send_upload_file_status = true; +} + +// a file upload has finished. +// If any running apps are waiting for it, notify them +// +void ACTIVE_TASK_SET::upload_notify_app(FILE_INFO* fip) { + for (unsigned int i=0; iresult; + FILE_REF* frp = rp->lookup_file(fip); + if (frp) { + atp->upload_notify_app(fip, frp); + } + } +} + const char *BOINC_RCSID_778b61195e = "$Id$"; diff --git a/client/app.h b/client/app.h index 3a06c4c42b..fd542ea122 100644 --- a/client/app.h +++ b/client/app.h @@ -122,6 +122,7 @@ public: double max_disk_usage; // abort if disk usage (in+out+temp) exceeds this double max_mem_usage; // abort if memory usage exceeds this bool have_trickle_down; + bool send_upload_file_status; bool pending_suspend_via_quit; // waiting for task to suspend via quit APP_CLIENT_SHM app_client_shm; // core/app shared mem @@ -176,6 +177,7 @@ public: int write_app_init_file(); int move_trickle_file(); int handle_upload_files(); + void upload_notify_app(const FILE_INFO*, const FILE_REF*); int write(MIOFILE&); int parse(MIOFILE&); @@ -206,6 +208,8 @@ public: void send_heartbeats(); void send_trickle_downs(); void report_overdue(double); + void handle_upload_files(); + void upload_notify_app(FILE_INFO*); // screensaver-related functions ACTIVE_TASK* get_ss_app(); diff --git a/client/app_control.C b/client/app_control.C index 3cc9150a20..9d4e9cbd0e 100644 --- a/client/app_control.C +++ b/client/app_control.C @@ -350,6 +350,11 @@ void ACTIVE_TASK_SET::send_trickle_downs() { sent = atp->app_client_shm.shm->trickle_down.send_msg("\n"); if (sent) atp->have_trickle_down = false; } + if (atp->send_upload_file_status) { + if (!atp->app_client_shm.shm) continue; + sent = atp->app_client_shm.shm->trickle_down.send_msg("\n"); + if (sent) atp->send_upload_file_status = false; + } } } @@ -865,30 +870,6 @@ bool ACTIVE_TASK::get_trickle_up_msg() { return found; } -// scan the slot director, looking for files with names -// of the form boinc_ufr_X. -// Then mark file X as being present (and uploadable) -// -int ACTIVE_TASK::handle_upload_files() { - std::string filename; - char buf[256], path[256]; - - DirScanner dirscan(slot_dir); - while (dirscan.scan(filename)) { - strcpy(buf, filename.c_str()); - if (strstr(buf, "boinc_ufr") == buf) { - char* p = buf+strlen("boinc_ufr"); - FILE_INFO* fip = gstate.lookup_file_info(result->project, p); - if (fip) { - fip->status = FILE_PRESENT; - } - sprintf(path, "%s/%s", slot_dir, buf); - boinc_delete_file(path); - } - } - return 0; -} - // check for msgs from active tasks. // Return true if any of them has changed its checkpoint_cpu_time // (since in that case we need to write state file) diff --git a/client/client_state.C b/client/client_state.C index 9851c7648d..8554f47514 100644 --- a/client/client_state.C +++ b/client/client_state.C @@ -340,6 +340,7 @@ int CLIENT_STATE::init() { if (retval) return retval; active_tasks.report_overdue(dtime()); + active_tasks.handle_upload_files(); // Just to be on the safe side; something may have been modified // diff --git a/client/client_types.C b/client/client_types.C index f3205c9d67..b6b9e815ed 100644 --- a/client/client_types.C +++ b/client/client_types.C @@ -1372,4 +1372,22 @@ double RESULT::estimated_cpu_time_remaining() { return estimated_cpu_time(); } +FILE_REF* RESULT::lookup_file(FILE_INFO* fip) { + for (unsigned int i=0; iexit_status != ERR_ABORTED_VIA_GUI) { for (i=0; ioutput_files.size(); i++) { fip = rp->output_files[i].file_info; + if (fip->uploaded) continue; get_pathname(fip, path); retval = file_size(path, size); if (retval) { diff --git a/client/cs_files.C b/client/cs_files.C index 06b84208dc..8846217a42 100644 --- a/client/cs_files.C +++ b/client/cs_files.C @@ -223,6 +223,7 @@ bool CLIENT_STATE::handle_pers_file_xfers(double now) { fip->delete_file(); } fip->uploaded = true; + active_tasks.upload_notify_app(fip); } else if (fip->status >= 0) { // file transfer did not fail (non-negative status) @@ -261,4 +262,5 @@ bool CLIENT_STATE::handle_pers_file_xfers(double now) { return action; } + const char *BOINC_RCSID_66410b3cab = "$Id$"; diff --git a/client/gui_rpc_server.C b/client/gui_rpc_server.C index 99324cf61e..64b2db18fa 100644 --- a/client/gui_rpc_server.C +++ b/client/gui_rpc_server.C @@ -507,7 +507,7 @@ int GUI_RPC_CONN::handle_rpc() { #else n = read(sock, request_msg, 4095); #endif - if (n <= 0) return -1; + if (n <= 0) return ERR_READ; request_msg[n] = 0; scope_messages.printf("GUI RPC Command = '%s'\n", request_msg); diff --git a/lib/app_ipc.h b/lib/app_ipc.h index 38097665fa..11aee702a9 100755 --- a/lib/app_ipc.h +++ b/lib/app_ipc.h @@ -22,6 +22,7 @@ #include #include +#include #include "hostinfo.h" #include "proxy_info.h" @@ -98,6 +99,9 @@ struct SHARED_MEM { // }; +// MSG_QUEUE provides a queuing mechanism for shared-mem messages +// (which don't have one otherwise) +// struct MSG_QUEUE { std::vector msgs; char name[256]; @@ -123,8 +127,6 @@ struct MSG_QUEUE { #define NGRAPHICS_MSGS 7 -#include - struct GRAPHICS_MSG { int mode; char window_station[256]; @@ -212,8 +214,10 @@ int parse_graphics_file(FILE* f, GRAPHICS_INFO* gi); #define STDERR_FILE "stderr.txt" #define STDOUT_FILE "stdout.txt" #define LOCKFILE "boinc_lockfile" +#define UPLOAD_FILE_REQ_PREFIX "boinc_ufr_" +#define UPLOAD_FILE_STATUS_PREFIX "boinc_ufs_" extern const char* xml_graphics_modes[NGRAPHICS_MSGS]; -int boinc_link(const char* existing, const char* new_link); +extern int boinc_link(const char* phys_name, const char* logical_name); #endif diff --git a/lib/error_numbers.h b/lib/error_numbers.h index 2f1af8517c..8b6cf92428 100755 --- a/lib/error_numbers.h +++ b/lib/error_numbers.h @@ -146,3 +146,5 @@ #define ERR_INSUFFICIENT_RESOURCE -198 #define ERR_RETRY -199 #define ERR_WRONG_SIZE -200 +#define ERR_USER_PERMISSION -201 + // e.g. user didn't allow network connection diff --git a/lib/filesys.C b/lib/filesys.C index c5cf1bc7eb..68e150f07c 100755 --- a/lib/filesys.C +++ b/lib/filesys.C @@ -277,7 +277,7 @@ int file_size(const char* path, double& size) { int retval; retval = stat(path, &sbuf); - if (retval) return retval; + if (retval) return ERR_NOT_FOUND; size = (double)sbuf.st_size; return 0; } diff --git a/lib/mfile.C b/lib/mfile.C index a73062c6df..dd6633696d 100644 --- a/lib/mfile.C +++ b/lib/mfile.C @@ -51,7 +51,7 @@ MFILE::~MFILE() { int MFILE::open(const char* path, const char* mode) { f = boinc_fopen(path, mode); - if (!f) return -1; + if (!f) return ERR_FOPEN; return 0; } @@ -64,7 +64,7 @@ int MFILE::vprintf(const char* format, va_list ap) { buf = (char*)realloc(buf, len+n+1); if (!buf) { errno = ERR_MALLOC; - return -1; + return ERR_MALLOC; } strncpy(buf+len, buf2, n); len += n; diff --git a/lib/network.C b/lib/network.C index 755729a053..974ccd2ef9 100644 --- a/lib/network.C +++ b/lib/network.C @@ -249,13 +249,13 @@ int NetOpen() { // Don't Autodial if already connected to Internet by Modem or LAN if (!rc) { if((double)time(NULL) < net_last_dial_time + CONFIRM_WAIT) { - return -1; + return ERR_USER_PERMISSION; } #if !defined(_WIN32) && !defined(_CONSOLE) if(gstate.global_prefs.confirm_before_connecting) { net_last_req_time = (double)time(NULL); if(!RequestNetConnect()) { - return -1; + return ERR_USER_PERMISSION; } } #endif @@ -274,7 +274,7 @@ int NetOpen() { rc = GetLastError(); // Don't continue if busy signal, no answer or user cancelled if (rc == ERROR_USER_DISCONNECTION) { - return -1; + return ERR_USER_PERMISSION; } } } diff --git a/lib/parse.C b/lib/parse.C index 23af294701..54ffb6de66 100644 --- a/lib/parse.C +++ b/lib/parse.C @@ -26,6 +26,7 @@ #ifdef _WIN32 #include "boinc_win.h" +#include #endif #ifndef _WIN32 @@ -73,13 +74,18 @@ bool parse_int(const char* buf, const char* tag, int& x) { // Same, for doubles // bool parse_double(const char* buf, const char* tag, double& x) { + double y; char* p = strstr(buf, tag); if (!p) return false; std::string strLocale = setlocale(LC_NUMERIC, NULL); setlocale(LC_NUMERIC, "C"); - x = atof(p+strlen(tag)); + y = atof(p+strlen(tag)); setlocale(LC_NUMERIC, strLocale.c_str()); - return true; + if (_finite(y)) { + x = y; + return true; + } + return false; } // parse a string of the form ...string...;