mirror of https://github.com/BOINC/boinc.git
*** empty log message ***
svn path=/trunk/boinc/; revision=11960
This commit is contained in:
parent
aebefb85a4
commit
6a10211584
|
@ -1103,3 +1103,12 @@ David 24 Jan 2007
|
|||
client_types.C,h
|
||||
cs_apps.C
|
||||
cs_scheduler.C
|
||||
|
||||
David 24 Jan 2007
|
||||
- core client: fix compile warnings, get rid of cs_data.C
|
||||
|
||||
client/
|
||||
Makefile.am
|
||||
client_state.h
|
||||
cs_data.C
|
||||
scheduler_op.C
|
||||
|
|
|
@ -39,7 +39,6 @@ boinc_client_SOURCES = \
|
|||
cs_apps.C \
|
||||
cs_benchmark.C \
|
||||
cs_cmdline.C \
|
||||
cs_data.C \
|
||||
cs_files.C \
|
||||
cs_prefs.C \
|
||||
cs_scheduler.C \
|
||||
|
|
|
@ -845,7 +845,9 @@ int ACTIVE_TASK::unsuspend() {
|
|||
msg_printf(0, MSG_INFO, "Internal error: expected process to be suspended");
|
||||
}
|
||||
if (log_flags.cpu_sched) {
|
||||
msg_printf(0, MSG_INFO, "[cpu_sched] Resuming %s", result->name);
|
||||
msg_printf(result->project, MSG_INFO,
|
||||
"[cpu_sched] Resuming %s", result->name
|
||||
);
|
||||
}
|
||||
int n = process_control_queue.msg_queue_purge("<suspend/>");
|
||||
if (n == 0) {
|
||||
|
|
|
@ -434,36 +434,6 @@ public:
|
|||
|
||||
void check_all();
|
||||
void free_mem();
|
||||
|
||||
#if 0
|
||||
// ------------------ cs_data.C:
|
||||
// mechanisms for managing data saved on host
|
||||
//
|
||||
public:
|
||||
bool get_more_disk_space(PROJECT*, double);
|
||||
int anything_free(double &);
|
||||
int calc_proj_size(PROJECT*);
|
||||
int calc_all_proj_size();
|
||||
int compute_share_disk_size(PROJECT*);
|
||||
int total_potential_offender(PROJECT*, double &);
|
||||
int total_potential_self(PROJECT*, double &);
|
||||
double select_delete(PROJECT*, double, int);
|
||||
double delete_results(PROJECT*, double);
|
||||
double compute_resource_share(PROJECT*);
|
||||
PROJECT* greatest_offender();
|
||||
private:
|
||||
bool data_manager_poll();
|
||||
bool fix_data_overflow(double, double);
|
||||
int reset_checks();
|
||||
int delete_inactive_results(PROJECT*);
|
||||
int unstick_result_files(RESULT*);
|
||||
double delete_next_file(PROJECT*, int);
|
||||
double delete_expired(PROJECT*);
|
||||
double offender(PROJECT*);
|
||||
double proj_potentially_free(PROJECT*);
|
||||
FILE_INFO* get_priority_or_lru(PROJECT*, int);
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
extern CLIENT_STATE gstate;
|
||||
|
|
565
client/cs_data.C
565
client/cs_data.C
|
@ -1,565 +0,0 @@
|
|||
// Berkeley Open Infrastructure for Network Computing
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2005 University of California
|
||||
//
|
||||
// This is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation;
|
||||
// either version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This software is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// To view the GNU Lesser General Public License visit
|
||||
// http://www.gnu.org/copyleft/lesser.html
|
||||
// or write to the Free Software Foundation, Inc.,
|
||||
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
// Includes the methods required for managing saved data on the client
|
||||
// utilized by the client to managed its deletion policy and communicate with
|
||||
// the user and the server what the status of the data storage is
|
||||
//
|
||||
// Uhhhh... what exactly does the above say????
|
||||
//
|
||||
|
||||
#include "cpp.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "boinc_win.h"
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "config.h"
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include "filesys.h"
|
||||
#include "client_msgs.h"
|
||||
#include "client_types.h"
|
||||
#include "client_state.h"
|
||||
|
||||
using std::vector;
|
||||
|
||||
#if 0
|
||||
|
||||
// This gets called when the client doesn't have enough disk space to continue
|
||||
// running active tasks.
|
||||
// Notify user which project is the greatest offender
|
||||
// of their data share
|
||||
//
|
||||
void data_overflow_notify(PROJECT* project) {
|
||||
if (project == NULL) {
|
||||
msg_printf(NULL, MSG_ERROR,
|
||||
"BOINC has run out of disk space.\n"
|
||||
"Please change your General Preferences to allocate more space.\n"
|
||||
);
|
||||
} else {
|
||||
msg_printf(project, MSG_ERROR,
|
||||
"BOINC has run out of disk space for %s.\n"
|
||||
"Please change your General Preferences to allocate more space.\n",
|
||||
project->project_name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Polling function called in do_something()
|
||||
//
|
||||
// Makes sure the disk bounds have not been drastically violated
|
||||
// Returns true if something has been violated and tries to correct
|
||||
// the problem
|
||||
// TODO: notify the user of corrections made?
|
||||
//
|
||||
bool CLIENT_STATE::data_manager_poll() {
|
||||
double tdu, adu;
|
||||
|
||||
static int counter=0;
|
||||
|
||||
if (++counter < 10000) {
|
||||
return false;
|
||||
}
|
||||
counter = 0;
|
||||
|
||||
total_disk_usage(tdu);
|
||||
allowed_disk_usage(adu);
|
||||
|
||||
// delete files from offenders only
|
||||
//
|
||||
if (tdu > adu) {
|
||||
if (size_overflow || !projects.size()) {
|
||||
return false;
|
||||
}
|
||||
return fix_data_overflow(tdu, adu);
|
||||
}
|
||||
|
||||
if (size_overflow) {
|
||||
calc_all_proj_size();
|
||||
size_overflow = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CLIENT_STATE::fix_data_overflow(double tdu, double adu) {
|
||||
double space_needed, deleted_space;
|
||||
unsigned int i;
|
||||
int priority;
|
||||
bool deleted;
|
||||
bool tentative;
|
||||
PROJECT* p;
|
||||
|
||||
// Check if any projects are tentative
|
||||
// could have new prefs in RPC
|
||||
//
|
||||
for (i=0; i<projects.size(); i++) {
|
||||
if (projects[i]->tentative) return false;
|
||||
}
|
||||
|
||||
// get accurate sizes as of right now
|
||||
//
|
||||
calc_all_proj_size();
|
||||
|
||||
// delete files from offenders only
|
||||
|
||||
space_needed = tdu - adu;
|
||||
get_more_disk_space(NULL, space_needed);
|
||||
total_disk_usage(tdu);
|
||||
|
||||
i=0;
|
||||
priority = P_LOW;
|
||||
deleted = false;
|
||||
|
||||
while (tdu > adu) {
|
||||
// there is an offender that doesn't want to give up its files
|
||||
// try deleting files from other projects first
|
||||
//
|
||||
if (i >= projects.size()) {
|
||||
if (!deleted){
|
||||
if (priority >= P_HIGH) {
|
||||
break;
|
||||
} else {
|
||||
priority++;
|
||||
}
|
||||
}
|
||||
deleted = false;
|
||||
i=0;
|
||||
}
|
||||
p = projects[i];
|
||||
deleted_space = select_delete(p, 1, priority);
|
||||
if (deleted_space != 0) deleted = true;
|
||||
tdu -= deleted_space;
|
||||
i++;
|
||||
}
|
||||
|
||||
i=0;
|
||||
deleted = false;
|
||||
tentative = false;
|
||||
|
||||
while (tdu > adu) {
|
||||
// still not enough space, projects give up non-active WUs
|
||||
//
|
||||
if (i >= projects.size()) {
|
||||
if (!deleted) {
|
||||
size_overflow = true;
|
||||
data_overflow_notify(NULL);
|
||||
return true;
|
||||
}
|
||||
i=0;
|
||||
deleted = false;
|
||||
}
|
||||
p = projects[i];
|
||||
deleted_space = delete_results(p, 1);
|
||||
if (deleted_space != 0) deleted = true;
|
||||
tdu -= deleted_space;
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculate the size of all the projects
|
||||
// use after any deletions to ensure accurate number for size
|
||||
//
|
||||
int CLIENT_STATE::calc_all_proj_size() {
|
||||
for (unsigned int i=0; i<projects.size(); ++i) {
|
||||
calc_proj_size(projects[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// recalculates the total size of the project directory
|
||||
// and any associated active task directories
|
||||
//
|
||||
int CLIENT_STATE::calc_proj_size(PROJECT* p) {
|
||||
p->size = 0;
|
||||
project_disk_usage(p, p->size);
|
||||
compute_share_disk_size(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Any space that is unallocated, returns number of bytes
|
||||
//
|
||||
int CLIENT_STATE::anything_free(double& size) {
|
||||
double total_size = 0;
|
||||
double disk_available;
|
||||
|
||||
for (unsigned int i=0; i<projects.size(); ++i) {
|
||||
total_size += projects[i]->size;
|
||||
}
|
||||
allowed_project_disk_usage(disk_available);
|
||||
size = disk_available - total_size;
|
||||
if (size > 0) {
|
||||
return 0;
|
||||
} else {
|
||||
size = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Tries to get more disk space for a project. Takes some percentage
|
||||
// of the disk space that is not utilzed by a project and awards the
|
||||
// space to the project to be used. Returns true if this was successful,
|
||||
// false if it was not. It will be uncessful if all the projects are at their
|
||||
// limits and the currect project is trying to exceed theirs.
|
||||
//
|
||||
// This function will try its best to allow a project to grow in size
|
||||
// It will delete files from all projects that have a larger gap than
|
||||
// the current project.
|
||||
//
|
||||
bool CLIENT_STATE::get_more_disk_space(PROJECT *p, double space_needed) {
|
||||
PROJECT * other_p = NULL;
|
||||
double total_space = 0;
|
||||
double free_space;
|
||||
double offend_size;
|
||||
int priority = 0;
|
||||
|
||||
// check to see if there is enough extra space floating around
|
||||
// such will be the case after calling this after a deletion
|
||||
//
|
||||
if (!anything_free(free_space)) {
|
||||
total_space += free_space;
|
||||
if (total_space > space_needed) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// If the function has not exited with true, this means that all available
|
||||
// space is being used by some combination of projects
|
||||
// Check if one of the projects is over its resource share and give the space
|
||||
// to the requesting project
|
||||
|
||||
reset_checks();
|
||||
priority = P_LOW;
|
||||
|
||||
while (total_space < space_needed) {
|
||||
other_p = greatest_offender();
|
||||
if (other_p == NULL || (other_p == p)) {
|
||||
if (priority > P_HIGH) {
|
||||
return false;
|
||||
} else {
|
||||
priority++;
|
||||
reset_checks();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
other_p->checked = true;
|
||||
|
||||
offend_size = offender(other_p);
|
||||
if (space_needed - total_space > offend_size) {
|
||||
total_space += select_delete(other_p, offend_size, priority);
|
||||
} else {
|
||||
total_space += select_delete(other_p, (space_needed - total_space), priority);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// try and delete this many bytes of data from the greatest offender
|
||||
// return the amount of disk space that was actually freed by the delete
|
||||
//
|
||||
double CLIENT_STATE::select_delete(PROJECT* p, double space_to_delete, int priority) {
|
||||
double deleted_space = 0;
|
||||
double total_space = 0;
|
||||
|
||||
garbage_collect();
|
||||
|
||||
// if not, then it must start selecting and deleting files
|
||||
// until enough space is freed up
|
||||
while (total_space < space_to_delete) {
|
||||
deleted_space = delete_next_file(p, priority);
|
||||
if (deleted_space == 0) break;
|
||||
total_space += deleted_space;
|
||||
}
|
||||
// delete all files that you can after reflagging stickys
|
||||
garbage_collect();
|
||||
// calculate the size of the project after the deletion
|
||||
calc_proj_size(p);
|
||||
return total_space;
|
||||
}
|
||||
|
||||
// Tries to delete everything but files associated with the active task
|
||||
// If this function exits with 0 and there is still not enough space,
|
||||
// the active task needs to be suspended and not restarted until there is
|
||||
// enough space to run that project.
|
||||
|
||||
double CLIENT_STATE::delete_results(PROJECT *p, double space_to_delete) {
|
||||
double deleted_space = 0;
|
||||
double oldsize = p->size;
|
||||
|
||||
while (deleted_space < space_to_delete) {
|
||||
if (delete_inactive_results(p)) {
|
||||
break;
|
||||
}
|
||||
calc_proj_size(p);
|
||||
deleted_space += oldsize - p->size;
|
||||
}
|
||||
return deleted_space;
|
||||
}
|
||||
|
||||
// Returns the next file based on the deletion policy of the project.
|
||||
// Returns true if a file that can be deleted was found,
|
||||
// false otherwise
|
||||
//
|
||||
double CLIENT_STATE::delete_next_file(PROJECT* p, int priority) {
|
||||
FILE_INFO* retval = NULL;
|
||||
double space_freed = 0;
|
||||
|
||||
if (p->deletion_policy_expire) {
|
||||
space_freed = delete_expired(p);
|
||||
}
|
||||
if (space_freed == 0) {
|
||||
retval = get_priority_or_lru(p, priority);
|
||||
if (retval != NULL) {
|
||||
retval->sticky = false;
|
||||
space_freed = retval->nbytes;
|
||||
}
|
||||
}
|
||||
return space_freed;
|
||||
}
|
||||
|
||||
// Returns the file_info from the project that has the lowest priority
|
||||
//
|
||||
FILE_INFO* CLIENT_STATE::get_priority_or_lru(PROJECT* p, int priority) {
|
||||
FILE_INFO* fip;
|
||||
unsigned int i;
|
||||
double lowest_p = 0;
|
||||
FILE_INFO* lowest = NULL;
|
||||
|
||||
for (i=0; i<file_infos.size(); i++) {
|
||||
fip = file_infos[i];
|
||||
|
||||
// files that have no wu's or results and are permenant
|
||||
if (fip->ref_cnt==0 && fip->project == p
|
||||
&& fip->sticky && fip->priority <= priority) {
|
||||
if (lowest == NULL) {
|
||||
lowest = fip;
|
||||
lowest_p = fip->priority;
|
||||
} else if (fip->priority < lowest_p) {
|
||||
lowest = file_infos[i];
|
||||
lowest_p = lowest->priority;
|
||||
} else if (fip->priority == lowest_p) {
|
||||
if (p->deletion_policy_expire && fip->exp_date < lowest->exp_date) {
|
||||
lowest = file_infos[i];
|
||||
} else if (fip->time_last_used < lowest->time_last_used) {
|
||||
lowest = file_infos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return lowest;
|
||||
}
|
||||
|
||||
// Deletes all expired file_infos
|
||||
// Returns the amount of bytes freed
|
||||
//
|
||||
double CLIENT_STATE::delete_expired(PROJECT* p) {
|
||||
FILE_INFO* fip;
|
||||
double space_expired = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i=0; i<file_infos.size(); i++) {
|
||||
fip = file_infos[i];
|
||||
// files that have no wu's or results and are permenant
|
||||
if (fip->ref_cnt==0 && fip->project == p && fip->sticky) {
|
||||
if (fip->exp_date > gstate.now) {
|
||||
fip->sticky = false;
|
||||
space_expired += fip->nbytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
return space_expired;
|
||||
}
|
||||
|
||||
// Delete any files that associated with inactive results
|
||||
// by marking their results to acknowledged
|
||||
//
|
||||
int CLIENT_STATE::delete_inactive_results(PROJECT *p) {
|
||||
bool deleted = false;
|
||||
RESULT* result;
|
||||
unsigned int i;
|
||||
|
||||
for (i=0; i<results.size(); i++) {
|
||||
result = results[i];
|
||||
if (!result->is_active && result->state < RESULT_COMPUTE_DONE) {
|
||||
result->got_server_ack = true;
|
||||
unstick_result_files(result);
|
||||
deleted = true;
|
||||
}
|
||||
}
|
||||
if (deleted) {
|
||||
garbage_collect();
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// should be called after forcebly deleting any result
|
||||
// ensures any files that were supposed to by permanent are
|
||||
// deleted as well, as we are already low on disk space
|
||||
//
|
||||
int CLIENT_STATE::unstick_result_files(RESULT *rp) {
|
||||
WORKUNIT* wup;
|
||||
int retval = 1;
|
||||
unsigned int i;
|
||||
for (i=0; i<rp->output_files.size(); i++) {
|
||||
retval = 0;
|
||||
rp->output_files[i].file_info->sticky = false;
|
||||
}
|
||||
wup = rp->wup;
|
||||
for (i=0; i<wup->input_files.size(); i++) {
|
||||
retval = 0;
|
||||
wup->input_files[i].file_info->sticky = false;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
// returns the number of bytes the greatest offender is over his usual resource share
|
||||
// the argument is returned with the number of bytes and the offending
|
||||
// project is returned
|
||||
//
|
||||
PROJECT* CLIENT_STATE::greatest_offender() {
|
||||
PROJECT* g_offender = NULL;
|
||||
PROJECT* current_suspect;
|
||||
double max_offense = 0;
|
||||
for (unsigned int i=0; i<projects.size(); ++i) {
|
||||
if (!projects[i]->checked){
|
||||
current_suspect = projects[i];
|
||||
if (offender(current_suspect) > max_offense) {
|
||||
g_offender = current_suspect;
|
||||
max_offense = offender(current_suspect);
|
||||
}
|
||||
}
|
||||
}
|
||||
return g_offender;
|
||||
}
|
||||
// returns the number of bytes the project is offending by
|
||||
// will be negative if it is not an offender
|
||||
//
|
||||
double CLIENT_STATE::offender(PROJECT* p) {
|
||||
if (p->share_size == 0) {
|
||||
calc_all_proj_size();
|
||||
}
|
||||
return (p->size - p->share_size);
|
||||
}
|
||||
|
||||
// Computes the percentage of the actual resource share that
|
||||
// has been awarded to this project when compared with the totals
|
||||
// from all other projects
|
||||
//
|
||||
double CLIENT_STATE::compute_resource_share(PROJECT *p) {
|
||||
return p->resource_share/total_resource_share();
|
||||
}
|
||||
|
||||
// Computes the size of the allowed disk share in number of bytes.
|
||||
// This number may be smaller than the actual disk usage of the project
|
||||
// since projects are allowed to grow outside of their disk bounds if there
|
||||
// is space not utilzed by other projects
|
||||
//
|
||||
int CLIENT_STATE::compute_share_disk_size(PROJECT *p) {
|
||||
double disk_available;
|
||||
allowed_project_disk_usage(disk_available);
|
||||
p->share_size = disk_available * compute_resource_share(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// resets the checked flag for all projects in gstate to false;
|
||||
//
|
||||
int CLIENT_STATE::reset_checks() {
|
||||
unsigned int i;
|
||||
for (i=0; i<projects.size(); ++i) {
|
||||
projects[i]->checked = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CLIENT_STATE::total_potential_offender(PROJECT* p, double& tps) {
|
||||
PROJECT* other_p;
|
||||
unsigned int i;
|
||||
|
||||
garbage_collect();
|
||||
anything_free(tps);
|
||||
|
||||
for (i=0; i<projects.size(); i++) {
|
||||
other_p = projects[i];
|
||||
if (other_p != p) {
|
||||
tps += proj_potentially_free(other_p);
|
||||
}
|
||||
}
|
||||
if (tps > 0) {
|
||||
return 0;
|
||||
} else {
|
||||
tps = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int CLIENT_STATE::total_potential_self(PROJECT* p, double& tps) {
|
||||
FILE_INFO* fip;
|
||||
unsigned int i;
|
||||
total_potential_offender(p, tps);
|
||||
for (i=0; i<file_infos.size(); i++) {
|
||||
fip = file_infos[i];
|
||||
if (fip->ref_cnt == 0 && fip->project == p && fip->sticky) {
|
||||
if (!p->deletion_policy_expire) {
|
||||
tps += fip->nbytes;
|
||||
} else if (p->deletion_policy_expire && (fip->exp_date > gstate.now)) {
|
||||
tps += fip->nbytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tps > 0) {
|
||||
return 0;
|
||||
} else {
|
||||
tps = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
double CLIENT_STATE::proj_potentially_free(PROJECT* p) {
|
||||
double offend_share = offender(p);
|
||||
double tps = 0;
|
||||
FILE_INFO* fip;
|
||||
unsigned int i;
|
||||
if (offend_share <= 0) {
|
||||
return 0;
|
||||
}
|
||||
for (i=0; i<file_infos.size(); i++) {
|
||||
if (tps > offend_share) break;
|
||||
fip = file_infos[i];
|
||||
if (fip->ref_cnt==0 && fip->project == p && fip->sticky) {
|
||||
if (!p->deletion_policy_expire) {
|
||||
tps += fip->nbytes;
|
||||
} else if (p->deletion_policy_expire && (fip->exp_date > gstate.now)) {
|
||||
tps += fip->nbytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tps;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const char *BOINC_RCSID_c8458fed1c = "$Id$";
|
|
@ -167,7 +167,7 @@ int SCHEDULER_OP::init_op_project(PROJECT* p, int r) {
|
|||
// Master-file fetch errors for tentative (new) projects
|
||||
// are handled elsewhere; no need to detach from projects here.
|
||||
//
|
||||
void SCHEDULER_OP::backoff(PROJECT* p, const char *reason ) {
|
||||
void SCHEDULER_OP::backoff(PROJECT* p, const char *reason_msg) {
|
||||
char buf[1024];
|
||||
|
||||
if (p->master_fetch_failures >= gstate.master_fetch_retry_cap) {
|
||||
|
@ -203,7 +203,7 @@ void SCHEDULER_OP::backoff(PROJECT* p, const char *reason ) {
|
|||
n, gstate.sched_retry_delay_min, gstate.sched_retry_delay_max
|
||||
);
|
||||
//msg_printf(p, MSG_INFO, "simulating backoff of %f", exp_backoff);
|
||||
p->set_min_rpc_time(gstate.now + exp_backoff, reason);
|
||||
p->set_min_rpc_time(gstate.now + exp_backoff, reason_msg);
|
||||
}
|
||||
|
||||
// low-level routine to initiate an RPC
|
||||
|
|
|
@ -95,6 +95,7 @@ The following medium-to-large development projects are available:
|
|||
</ul>
|
||||
<li> Core client:
|
||||
<ul>
|
||||
<li> Compute disk usage (total, per-project) in a separate thread.
|
||||
<li> Don't enforce RAM limits unless free RAM is low
|
||||
<li> Do per-project disk-space measurements asynchronously (in a thread).
|
||||
<li> Extend general preferences to allow users to
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
<?
|
||||
|
||||
$project_news = array(
|
||||
array("January 24, 2007",
|
||||
"The <a href=http://boincfaq.mundayweb.com/>BOINC FAQ Service</a>
|
||||
answers many questions about using BOINC.
|
||||
It is available in English, German, and Dutch."
|
||||
),
|
||||
array("January 19, 2007",
|
||||
"Check out a
|
||||
<a href=http://youtube.com/watch?v=kCYlZ8-l5jc>TV news segment</a>
|
||||
|
|
|
@ -24,7 +24,8 @@ $wiki_sites = array(
|
|||
),
|
||||
array(
|
||||
"http://boincfaq.mundayweb.com/",
|
||||
"The BOINC FAQ Service"
|
||||
"The BOINC FAQ Service",
|
||||
"(English, German and Dutch)"
|
||||
),
|
||||
array(
|
||||
"http://boinc-wiki.ath.cx/",
|
||||
|
|
|
@ -1130,7 +1130,7 @@ int run_program(char* dir, char* file, int argc, char** argv) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int get_client_mutex(char* dir) {
|
||||
static int get_client_mutex(const char* dir) {
|
||||
#ifdef _WIN32
|
||||
char buf[MAX_PATH] = "";
|
||||
|
||||
|
@ -1157,7 +1157,7 @@ static int get_client_mutex(char* dir) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int wait_client_mutex(char* dir, double timeout) {
|
||||
int wait_client_mutex(const char* dir, double timeout) {
|
||||
double start = dtime();
|
||||
while (1) {
|
||||
int retval = get_client_mutex(dir);
|
||||
|
|
|
@ -146,6 +146,6 @@ extern int check_security(int use_sandbox, int isManager);
|
|||
#endif
|
||||
|
||||
extern int run_program(char* path, char* cdir, int argc, char** argv);
|
||||
extern int wait_client_mutex(char* dir, double timeout);
|
||||
extern int wait_client_mutex(const char* dir, double timeout);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue