Skip to content

Commit b872d03

Browse files
author
Yorhel
committed
dl: Fix download of 0-byte files + resume finalize on priority change
The latter is required to recover from errors in download finalization. (Errors will be properly handled in next commit) 0-byte files also take a shorter route, no attempt to open a connection to the user is made.
1 parent 30cdd25 commit b872d03

File tree

2 files changed

+52
-42
lines changed

2 files changed

+52
-42
lines changed

src/dl.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,9 @@ static gboolean dl_queue_addfile(guint64 uid, char *hash, guint64 size, char *fn
586586
dl_queue_insert(dl, FALSE);
587587
dl_user_add(dl, uid, 0, NULL);
588588
db_dl_adduser(dl->hash, uid, 0, NULL);
589+
// Empty files get a shortcut here
590+
if(!size)
591+
dlfile_finished(dl);
589592
return TRUE;
590593
}
591594

@@ -715,9 +718,13 @@ void dl_queue_setprio(dl_t *dl, signed char prio) {
715718
int i;
716719
for(i=0; i<dl->u->len; i++)
717720
g_sequence_sort_changed(g_ptr_array_index(dl->u, i), dl_user_dl_sort, NULL);
718-
// Start the download if it is enabled
719-
if(enabled)
720-
dl_queue_start();
721+
// Start downloading or re-attempt finalization if it is enabled
722+
if(enabled) {
723+
if(!dl->active_threads && (dl->hassize || !dl->islist) && dl->have == dl->size)
724+
dlfile_finished(dl);
725+
else
726+
dl_queue_start();
727+
}
721728
/* TODO: Disconnect active users if the dl item is disabled */
722729
}
723730

src/dlfile.c

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,49 @@ void dlfile_rm(dl_t *dl) {
341341
}
342342

343343

344+
/* Create the inc file and initialize the necessary structs to prepare for
345+
* handling downloaded data. */
346+
static gboolean dlfile_open(dl_t *dl) {
347+
if(dl->incfd <= 0)
348+
dl->incfd = open(dl->inc, O_WRONLY|O_CREAT, 0666);
349+
if(dl->incfd < 0) {
350+
g_warning("Error opening %s: %s", dl->inc, g_strerror(errno));
351+
dl_queue_seterr(dl, DLE_IO_INC, g_strerror(errno));
352+
return FALSE;
353+
}
354+
355+
/* Everything else has already been initialized if we have a thread */
356+
if(dl->threads)
357+
return TRUE;
358+
359+
if(!dl->islist) {
360+
dl->bitmap = bita_new(dlfile_chunks(dl->size));
361+
if(!dlfile_save_bitmap(dl, dl->incfd)) {
362+
g_warning("Error writing bitmap for `%s': %s.", dl->dest, g_strerror(errno));
363+
dl_queue_seterr(dl, DLE_IO_INC, g_strerror(errno));
364+
free(dl->bitmap);
365+
dl->bitmap = NULL;
366+
return FALSE;
367+
}
368+
}
369+
370+
dlfile_thread_t *t = g_slice_new0(dlfile_thread_t);
371+
t->dl = dl;
372+
t->chunk = 0;
373+
t->allocated = 0;
374+
if(!dl->islist)
375+
t->avail = dlfile_chunks(dl->size);
376+
tth_init(&t->hash_tth);
377+
dl->threads = g_slist_prepend(dl->threads, t);
378+
return TRUE;
379+
}
380+
381+
344382
/* XXX: This function may block in the main thread for a while. Perhaps do it in a threadpool? */
345-
static void dlfile_finished(dl_t *dl) {
383+
void dlfile_finished(dl_t *dl) {
384+
if(dl->incfd <= 0 && !dlfile_open(dl))
385+
return;
386+
346387
/* Regular files: Remove bitmap from the file
347388
* File lists: Ensure that the file size is correct after we've downloaded a
348389
* longer file list before that got interrupted. */
@@ -386,44 +427,6 @@ static void dlfile_finished(dl_t *dl) {
386427
}
387428

388429

389-
/* Create the inc file and initialize the necessary structs to prepare for
390-
* handling downloaded data. */
391-
static gboolean dlfile_open(dl_t *dl) {
392-
if(dl->incfd <= 0)
393-
dl->incfd = open(dl->inc, O_WRONLY|O_CREAT, 0666);
394-
if(dl->incfd < 0) {
395-
g_warning("Error opening %s: %s", dl->inc, g_strerror(errno));
396-
dl_queue_seterr(dl, DLE_IO_INC, g_strerror(errno));
397-
return FALSE;
398-
}
399-
400-
/* Everything else has already been initialized if we have a thread */
401-
if(dl->threads)
402-
return TRUE;
403-
404-
if(!dl->islist) {
405-
dl->bitmap = bita_new(dlfile_chunks(dl->size));
406-
if(!dlfile_save_bitmap(dl, dl->incfd)) {
407-
g_warning("Error writing bitmap for `%s': %s.", dl->dest, g_strerror(errno));
408-
dl_queue_seterr(dl, DLE_IO_INC, g_strerror(errno));
409-
free(dl->bitmap);
410-
dl->bitmap = NULL;
411-
return FALSE;
412-
}
413-
}
414-
415-
dlfile_thread_t *t = g_slice_new0(dlfile_thread_t);
416-
t->dl = dl;
417-
t->chunk = 0;
418-
t->allocated = 0;
419-
if(!dl->islist)
420-
t->avail = dlfile_chunks(dl->size);
421-
tth_init(&t->hash_tth);
422-
dl->threads = g_slist_prepend(dl->threads, t);
423-
return TRUE;
424-
}
425-
426-
427430
/* The 'speed' argument should be a pessimistic estimate of the peers' speed,
428431
* in bytes/s. I think this is best obtained from a 30 second average.
429432
* Returns the thread pointer. */

0 commit comments

Comments
 (0)