From 42683a8a31b1774c1d36239d6e36e763bd3fd310 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 27 Jan 2010 03:55:46 +0000 Subject: [PATCH] svn path=/trunk/boinc/; revision=20269 --- checkin_notes | 24 +++++++ client/client_msgs.cpp | 2 +- client/cs_notice.cpp | 90 +++++++++++++++++---------- client/cs_notice.h | 7 +-- client/gui_rpc_server.cpp | 1 + client/gui_rpc_server.h | 8 +++ client/gui_rpc_server_ops.cpp | 14 +++-- samples/multi_thread/multi_thread.cpp | 8 ++- 8 files changed, 109 insertions(+), 45 deletions(-) diff --git a/checkin_notes b/checkin_notes index c4262ac098..678067dfed 100644 --- a/checkin_notes +++ b/checkin_notes @@ -667,3 +667,27 @@ David 25 Jan 2010 client/ app_start.cpp + +David 26 Jan 2010 + - client/manager: eliminate duplicate notices. + When appending a new notice, we check whether one with + the same title and description is present already. + If so we remove one or the other, depending on the situation. + + This introduces the possibility of "holes" in the seqno space. + In order that the manager learns of these deletions, + we use the following mechanism: + whenever a notice is removed (because it's a dup or too old) + a flag is set in each GUI_RPC_CONN. + On the next get_notice() RPC, the client returns the entire + list of notices, preceded by a dummy notice with seqno=-1; + this tells the RPC stub function to replace the current list + rather than appending to it. + + client/ + client_msgs.cpp + cs_notice.cpp,h + gui_rpc_server.h + gui_rpc_server_ops.cpp + samples/multi_thread/ + multi_thread.cpp diff --git a/client/client_msgs.cpp b/client/client_msgs.cpp index 2756b77b75..8e1a071698 100644 --- a/client/client_msgs.cpp +++ b/client/client_msgs.cpp @@ -88,7 +88,7 @@ void MESSAGE_DESCS::insert(PROJECT* p, int priority, int now, char* message) { } n.create_time = n.arrival_time = gstate.now; strcpy(n.category, "client"); - notices.append(n); + notices.append(n, false, false); } #endif } diff --git a/client/cs_notice.cpp b/client/cs_notice.cpp index 6f9ba20e6c..6f18a9d0ef 100644 --- a/client/cs_notice.cpp +++ b/client/cs_notice.cpp @@ -31,6 +31,7 @@ using std::vector; using std::string; using std::set; +using std::deque; NOTICES notices; RSS_FEEDS rss_feeds; @@ -230,6 +231,7 @@ void NOTICES::init() { if (log_flags.notice_debug) { msg_printf(0, MSG_INFO, "read %d BOINC notices", (int)notices.size()); } + write_archive(NULL); } void NOTICES::init_rss() { @@ -247,35 +249,63 @@ void NOTICES::init_rss() { } } -void NOTICES::append(NOTICE& n) { +static inline bool equivalent(NOTICE& n1, NOTICE& n2) { + if (strcmp(n1.title, n2.title)) return false; + if (n1.description != n2.description) return false; + return true; +} + +// we're considering adding a notice n. +// See if an equivalent notice n2 is already there; if so: +// keep_old: return false +// !keep_old: delete n2 +// +bool NOTICES::remove_dups(NOTICE& n, bool keep_old) { + deque::iterator i = notices.begin(); + bool removed_something = false; + while (i != notices.end()) { + NOTICE& n2 = *i; + if (equivalent(n, n2) || (n2.arrival_time < gstate.now - 30*86400)) { + if (keep_old) { + return false; + } + i = notices.erase(i); + removed_something = true; + } else { + ++i; + } + } + if (removed_something) { + gstate.gui_rpcs.set_notice_refresh(); + } + return true; +} + +bool NOTICES::append(NOTICE& n, bool keep_old, bool archive) { if (notices.empty()) { n.seqno = 1; } else { + if (!remove_dups(n, keep_old)) { + return false; + } n.seqno = notices.front().seqno + 1; } - notices.push_front(n); - prune(); - if (!strlen(n.feed_url)) { - write_archive(NULL); - } -} - -bool NOTICES::append_unique(NOTICE& n) { - for (unsigned int i=0; i gstate.now - 30*86400) break; - notices.pop_back(); - } -} - // write archive file for the given RSS feed // (or, if NULL, non-RSS notices) // @@ -368,12 +387,19 @@ void NOTICES::write_archive(RSS_FEED* rfp) { // write notices newer than seqno as XML (for GUI RPC). // Write them in order of increasing seqno // -void NOTICES::write(int seqno, MIOFILE& fout, bool public_only) { +void NOTICES::write(int seqno, MIOFILE& fout, bool public_only, bool notice_refresh) { unsigned int i; fout.printf("\n"); - for (i=0; i0; i--) { NOTICE& n = notices[i-1]; @@ -485,7 +511,7 @@ int RSS_FEED::parse_items(XML_PARSER& xp, int& nitems) { } else { n.arrival_time = gstate.now; strcpy(n.feed_url, url); - if (notices.append_unique(n)) { + if (notices.append(n, true, false)) { nitems++; } } diff --git a/client/cs_notice.h b/client/cs_notice.h index d8c9d93f1a..f08f0a8207 100644 --- a/client/cs_notice.h +++ b/client/cs_notice.h @@ -67,14 +67,13 @@ struct NOTICES { std::deque notices; - void write(int seqno, MIOFILE&, bool public_only); - void append(NOTICE&); - bool append_unique(NOTICE&); + void write(int seqno, MIOFILE&, bool public_only, bool notice_refresh); + bool append(NOTICE&, bool keep_old, bool archive); void init(); void init_rss(); int read_archive_file(char* file, char* feed_url); void write_archive(struct RSS_FEED*); - void prune(); + bool remove_dups(NOTICE&, bool keep_old); }; extern NOTICES notices; diff --git a/client/gui_rpc_server.cpp b/client/gui_rpc_server.cpp index ffd9b9ef53..5352f5afc1 100644 --- a/client/gui_rpc_server.cpp +++ b/client/gui_rpc_server.cpp @@ -79,6 +79,7 @@ GUI_RPC_CONN::GUI_RPC_CONN(int s): got_auth1 = false; got_auth2 = false; sent_unauthorized = false; + notice_refresh = false; } GUI_RPC_CONN::~GUI_RPC_CONN() { diff --git a/client/gui_rpc_server.h b/client/gui_rpc_server.h index 122e3182da..779133efaa 100644 --- a/client/gui_rpc_server.h +++ b/client/gui_rpc_server.h @@ -55,6 +55,9 @@ public: GET_PROJECT_CONFIG_OP get_project_config_op; LOOKUP_ACCOUNT_OP lookup_account_op; CREATE_ACCOUNT_OP create_account_op; + bool notice_refresh; + // next time we get a get_notices RPC, + // send a -1 seqno, then the whole list GUI_RPC_CONN(int); ~GUI_RPC_CONN(); @@ -96,4 +99,9 @@ public: void send_quits(); bool quits_sent(); bool poll(); + void set_notice_refresh() { + for (unsigned int i=0; inotice_refresh = true; + } + } }; diff --git a/client/gui_rpc_server_ops.cpp b/client/gui_rpc_server_ops.cpp index 7d63452717..596d2976bc 100644 --- a/client/gui_rpc_server_ops.cpp +++ b/client/gui_rpc_server_ops.cpp @@ -1055,16 +1055,16 @@ static void handle_set_cc_config(char* buf, MIOFILE& fout) { ); } -static void handle_get_notices(char* buf, MIOFILE& fout) { +static void handle_get_notices(char* buf, MIOFILE& fout, bool notice_refresh) { int seqno = 0; parse_int(buf, "", seqno); - notices.write(seqno, fout, false); + notices.write(seqno, fout, false, notice_refresh); } -static void handle_get_notices_public(char* buf, MIOFILE& fout) { +static void handle_get_notices_public(char* buf, MIOFILE& fout, bool notice_refresh) { int seqno = 0; parse_int(buf, "", seqno); - notices.write(seqno, fout, true); + notices.write(seqno, fout, true, notice_refresh); } // Some of the RPCs have empty-element request messages. @@ -1166,7 +1166,8 @@ int GUI_RPC_CONN::handle_rpc() { } else if (match_req(request_msg, "get_all_projects_list")) { read_all_projects_list_file(mf); } else if (match_req(request_msg, "get_notices_public")) { - handle_get_notices_public(request_msg, mf); + handle_get_notices_public(request_msg, mf, notice_refresh); + notice_refresh = false; // Operations that require authentication start here @@ -1247,7 +1248,8 @@ int GUI_RPC_CONN::handle_rpc() { } else if (match_req(request_msg, "set_debts")) { handle_set_debts(request_msg, mf); } else if (match_req(request_msg, "get_notices")) { - handle_get_notices(request_msg, mf); + handle_get_notices(request_msg, mf, notice_refresh); + notice_refresh = false; } else { // RPCs after this point require authentication, diff --git a/samples/multi_thread/multi_thread.cpp b/samples/multi_thread/multi_thread.cpp index a89bd226a6..f1e2ada3f7 100644 --- a/samples/multi_thread/multi_thread.cpp +++ b/samples/multi_thread/multi_thread.cpp @@ -16,7 +16,11 @@ // along with BOINC. If not, see . // Example multi-thread BOINC application. -// It does 64 "units" of computation, where each units is about 1 GFLOP. +// This app defines its own classes (THREAD, THREAD_SET) for managing threads. +// You can also use libraries such as OpenMP. +// Just make sure you call boinc_init_parallel(). +// +// This app does 64 "units" of computation, where each units is about 1 GFLOP. // It divides this among N "worker" threads. // N is passed in the command line, and defaults to 1. // @@ -25,7 +29,7 @@ #include #include #ifdef _WIN32 -#include "boinc_win.h" +#include "boinc_win.h" #else #include #include