~ubuntu-branches/ubuntu/precise/boinc/precise

« back to all changes in this revision

Viewing changes to client/pers_file_xfer.cpp

Tags: 6.12.8+dfsg-1
* New upstream release.
* Simplified debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
#ifdef _WIN32
21
21
#include "boinc_win.h"
22
 
#endif
23
 
 
24
 
#ifndef _WIN32
 
22
#else
25
23
#include "config.h"
26
24
#include <cmath>
27
25
#include <cstdlib>
30
28
#include "error_numbers.h"
31
29
#include "md5_file.h"
32
30
#include "parse.h"
 
31
#include "util.h"
33
32
#include "str_util.h"
34
33
#include "filesys.h"
35
34
 
63
62
    fip = f;
64
63
    is_upload = is_file_upload;
65
64
    pers_xfer_done = false;
66
 
    const char* p = f->get_init_url(is_file_upload);
 
65
    const char* p = f->get_init_url();
67
66
    if (!p) {
68
67
        msg_printf(NULL, MSG_INTERNAL_ERROR, "No URL for file transfer of %s", f->name);
69
68
        return ERR_NULL;
94
93
        return ERR_IDLE_PERIOD;
95
94
    }
96
95
 
97
 
    // Does the file exist already? this could happen for example if we are
98
 
    // downloading an application which exists from a previous installation
 
96
    // if download, see if file already exists and is valid
99
97
    //
100
98
    if (!is_upload) {
101
99
        char pathname[256];
102
100
        get_pathname(fip, pathname, sizeof(pathname));
103
101
 
104
 
        // see if file already exists and is valid
105
 
        //
106
102
        if (!fip->verify_file(true, false)) {
107
103
            retval = fip->set_permissions();
108
104
            fip->status = FILE_PRESENT;
117
113
 
118
114
            return 0;
119
115
        } else {
 
116
            // Mark file as not present but don't delete it.
 
117
            // It might partly downloaded.
 
118
            //
120
119
            fip->status = FILE_NOT_PRESENT;
121
120
        }
122
121
    }
123
122
 
124
123
    file_xfer = new FILE_XFER;
125
 
    file_xfer->set_proxy(&gstate.proxy_info);
126
124
    fxp = file_xfer;
127
125
    retval = start_xfer();
128
126
    if (!retval) retval = gstate.file_xfers->insert(file_xfer);
129
127
    if (retval) {
130
128
        if (log_flags.http_debug) {
131
129
            msg_printf(
132
 
                fip->project, MSG_INFO, "[file_xfer_debug] Couldn't start %s of %s",
 
130
                fip->project, MSG_INFO, "[file_xfer] Couldn't start %s of %s",
133
131
                (is_upload ? "upload" : "download"), fip->name
134
132
            );
135
133
            msg_printf(
136
 
                fip->project, MSG_INFO, "[file_xfer_debug] URL %s: %s",
137
 
                fip->get_current_url(is_upload), boincerror(retval)
 
134
                fip->project, MSG_INFO, "[file_xfer] URL %s: %s",
 
135
                fip->get_current_url(), boincerror(retval)
138
136
            );
139
137
        }
140
138
 
151
149
        );
152
150
    }
153
151
    if (log_flags.file_xfer_debug) {
154
 
        msg_printf(0, MSG_INFO,
155
 
            "[file_xfer_debug] URL: %s\n",
156
 
            fip->get_current_url(is_upload)
 
152
        msg_printf(fip->project, MSG_INFO,
 
153
            "[file_xfer] URL: %s\n",
 
154
            fip->get_current_url()
157
155
        );
158
156
    }
159
157
    return 0;
177
175
        if (gstate.now < next_request_time) {
178
176
            return false;
179
177
        }
 
178
        FILE_XFER_BACKOFF& fxb = fip->project->file_xfer_backoff(is_upload);
 
179
        if (!fxb.ok_to_transfer()) {
180
180
#if 0
181
 
        if (gstate.now < fip->project->next_file_xfer_time(is_upload)) {
 
181
            if (log_flags.file_xfer_debug) {
 
182
                msg_printf(fip->project, MSG_INFO,
 
183
                    "[file_xfer] delaying %s of %s: project-wide backoff %f sec",
 
184
                    is_upload?"upload":"download", fip->name,
 
185
                    fxb.next_xfer_time - gstate.now
 
186
                );
 
187
            }
 
188
#endif
182
189
            return false;
183
190
        }
184
 
#endif
185
191
        last_time = gstate.now;
186
 
        fip->upload_offset = -1;
187
192
        retval = create_xfer();
188
193
        return (retval == 0);
189
194
    }
205
210
 
206
211
    if (fxp->file_xfer_done) {
207
212
        if (log_flags.file_xfer_debug) {
208
 
            msg_printf(0, MSG_INFO,
209
 
                "[file_xfer_debug] file transfer status %d",
 
213
            msg_printf(fip->project, MSG_INFO,
 
214
                "[file_xfer] file transfer status %d",
210
215
                fxp->file_xfer_retval
211
216
            );
212
217
        }
213
218
        switch (fxp->file_xfer_retval) {
214
219
        case 0:
215
 
            fip->project->file_xfer_succeeded(is_upload);
 
220
            fip->project->file_xfer_backoff(is_upload).file_xfer_succeeded();
216
221
            if (log_flags.file_xfer) {
217
222
                msg_printf(
218
223
                    fip->project, MSG_INFO, "Finished %s of %s",
221
226
            }
222
227
            if (log_flags.file_xfer_debug) {
223
228
                if (fxp->xfer_speed < 0) {
224
 
                    msg_printf(fip->project, MSG_INFO, "[file_xfer_debug] No data transferred");
 
229
                    msg_printf(fip->project, MSG_INFO, "[file_xfer] No data transferred");
225
230
                } else {
226
231
                    msg_printf(
227
 
                        fip->project, MSG_INFO, "[file_xfer_debug] Throughput %d bytes/sec",
 
232
                        fip->project, MSG_INFO, "[file_xfer] Throughput %d bytes/sec",
228
233
                        (int)fxp->xfer_speed
229
234
                    );
230
235
                }
261
266
            transient_failure(fxp->file_xfer_retval);
262
267
        }
263
268
 
 
269
        // If we transferred any bytes, or there are >1 URLs,
 
270
        // set upload_offset back to -1
 
271
        // so that we'll query file size on next retry.
 
272
        // Otherwise leave it as is, avoiding unnecessary size query.
 
273
        //
 
274
        if (last_bytes_xferred || (fip->urls.size() > 1)) {
 
275
            fip->upload_offset = -1;
 
276
        }
 
277
 
264
278
        // fxp could have already been freed and zeroed above
265
279
        // so check before trying to remove
266
280
        //
311
325
    // Otherwise immediately try the next URL
312
326
    //
313
327
 
314
 
    if (fip->get_next_url(is_upload)) {
 
328
    if (fip->get_next_url()) {
315
329
        start_xfer();
316
330
    } else {
317
331
        do_backoff();
331
345
 
332
346
    // keep track of transient failures per project (not currently used)
333
347
    //
334
 
    fip->project->file_xfer_failed(is_upload);
 
348
    PROJECT* p = fip->project;
 
349
    p->file_xfer_backoff(is_upload).file_xfer_failed(p);
335
350
 
336
351
    // Do an exponential backoff of e^nretry seconds,
337
352
    // keeping within the bounds of pers_retry_delay_min and
430
445
        delete fxp;
431
446
        fxp = 0;
432
447
    }
 
448
    fip->upload_offset = -1;
433
449
}
434
450
 
435
451
PERS_FILE_XFER_SET::PERS_FILE_XFER_SET(FILE_XFER_SET* p) {
444
460
    bool action = false;
445
461
    static double last_time=0;
446
462
 
447
 
    if (gstate.now - last_time < 1.0) return false;
 
463
    if (gstate.now - last_time < PERS_FILE_XFER_POLL_PERIOD) return false;
448
464
    last_time = gstate.now;
449
465
 
450
 
    for (i=0; i<pers_file_xfers.size(); i++) {
 
466
    // try to finish ones we've already started
 
467
    //
 
468
    for (i=0; i<pers_file_xfers.size(); i++) {
 
469
        if (!pers_file_xfers[i]->last_bytes_xferred) continue;
 
470
        action |= pers_file_xfers[i]->poll();
 
471
    }
 
472
    for (i=0; i<pers_file_xfers.size(); i++) {
 
473
        if (pers_file_xfers[i]->last_bytes_xferred) continue;
451
474
        action |= pers_file_xfers[i]->poll();
452
475
    }
453
476
 
489
512
//
490
513
void PERS_FILE_XFER_SET::suspend() {
491
514
    unsigned int i;
492
 
 
493
515
    for (i=0; i<pers_file_xfers.size(); i++) {
494
516
        pers_file_xfers[i]->suspend();
495
517
    }
496
518
}
497
519
 
498
 
const char *BOINC_RCSID_76edfcfb49 = "$Id: pers_file_xfer.cpp 16069 2008-09-26 18:20:24Z davea $";
 
520
// add a random delay 0..x to all transfers
 
521
// (used when emerging from bandwidth quota suspension)
 
522
//
 
523
void PERS_FILE_XFER_SET::add_random_delay(double x) {
 
524
    unsigned int i;
 
525
    double y = gstate.now + x*drand();
 
526
    for (i=0; i<pers_file_xfers.size(); i++) {
 
527
        if (y > pers_file_xfers[i]->next_request_time) {
 
528
            pers_file_xfers[i]->next_request_time = y;
 
529
        }
 
530
    }
 
531
}