diff --git a/checkin_notes b/checkin_notes index 264ff35561..44764c3e45 100644 --- a/checkin_notes +++ b/checkin_notes @@ -2581,3 +2581,13 @@ David 3 Mar 2009 freedc_icon.png boincstats_icon.png white.css + +David 3 Mar 2009 + - client: change garbage-collect logic. + old: reference-count files involved in a PERS_FILE_XFER + new: if a PERS_FILE_XFER refers to an unreferenced file, + delete it (and the associated FILE_XFER and HTTP_OP if present) + May fix #366 + + client/ + client_state.cpp diff --git a/client/client_state.cpp b/client/client_state.cpp index 1f941122e0..1f573a163d 100644 --- a/client/client_state.cpp +++ b/client/client_state.cpp @@ -1170,31 +1170,40 @@ bool CLIENT_STATE::garbage_collect_always() { } } - // reference count files involved in PERS_FILE_XFER or FILE_XFER - // (this seems redundant, but apparently not) - // - for (i=0; ifile_xfers.size(); i++) { - file_xfers->file_xfers[i]->fip->ref_cnt++; - } - for (i=0; ipers_file_xfers.size(); i++) { - pers_file_xfers->pers_file_xfers[i]->fip->ref_cnt++; - } - - // delete FILE_INFOs (and corresponding files) that are not referenced - // Don't do this if sticky and not marked for delete + // reference-count sticky files not marked for deletion // fi_iter = file_infos.begin(); while (fi_iter != file_infos.end()) { fip = *fi_iter; - bool exempt = fip->sticky; - if (fip->status < 0) exempt = false; - if (fip->marked_for_delete) exempt = false; - if (fip->ref_cnt==0 && !exempt) { - if (fip->pers_file_xfer) { - pers_file_xfers->remove(fip->pers_file_xfer); - delete fip->pers_file_xfer; - fip->pers_file_xfer = 0; - } + if (!fip->sticky) continue; + if (fip->status < 0) continue; + if (fip->marked_for_delete) continue; + fip->ref_cnt++; + fi_iter++; + } + + // remove PERS_FILE_XFERs (and associated FILE_XFERs and HTTP_OPs) + // for unreferenced files + // + vector::iterator pfx_iter; + pfx_iter = pers_file_xfers->pers_file_xfers.begin(); + while (pfx_iter != pers_file_xfers->pers_file_xfers.end()) { + PERS_FILE_XFER* pfx = *pfx_iter; + if (pfx->fip->ref_cnt == 0) { + pfx->suspend(); + delete pfx; + pfx_iter = pers_file_xfers->pers_file_xfers.erase(pfx_iter); + } else { + pfx_iter++; + } + } + + // delete FILE_INFOs (and corresponding files) that are not referenced + // + fi_iter = file_infos.begin(); + while (fi_iter != file_infos.end()) { + fip = *fi_iter; + if (fip->ref_cnt==0) { fip->delete_file(); if (log_flags.state_debug) { msg_printf(0, MSG_INFO,