diff --git a/btpd/tlib.c b/btpd/tlib.c index be1f281..3debe85 100644 --- a/btpd/tlib.c +++ b/btpd/tlib.c @@ -183,7 +183,8 @@ save_info(struct tlib *tl) btpd_err("failed to open '%s' (%s).\n", wpath, strerror(errno)); dct_subst_save(fp, "de", iob.buf); buf_free(&iob); - if (ferror(fp) || fclose(fp) != 0) + if ((fflush(fp) == EOF || fsync(fileno(fp)) != 0 + || ferror(fp) || fclose(fp) != 0)) btpd_err("failed to write '%s'.\n", wpath); if (rename(wpath, path) != 0) btpd_err("failed to rename: '%s' -> '%s' (%s).\n", wpath, path, @@ -191,9 +192,14 @@ save_info(struct tlib *tl) } void -tlib_update_info(struct tlib *tl) +tlib_update_info(struct tlib *tl, int only_file) { + struct tlib tmp; assert(tl->tp != NULL); + if (only_file) { + tmp = *tl; + tl = &tmp; + } tl->tot_down += tl->tp->net->downloaded; tl->tot_up += tl->tp->net->uploaded; tl->content_have = cm_content(tl->tp); diff --git a/btpd/tlib.h b/btpd/tlib.h index 74ae6f0..0147c36 100644 --- a/btpd/tlib.h +++ b/btpd/tlib.h @@ -28,7 +28,7 @@ struct tlib *tlib_add(const uint8_t *hash, const char *mi, size_t mi_size, const char *content, char *name); int tlib_del(struct tlib *tl); -void tlib_update_info(struct tlib *tl); +void tlib_update_info(struct tlib *tl, int only_file); struct tlib *tlib_by_hash(const uint8_t *hash); struct tlib *tlib_by_num(unsigned num); diff --git a/btpd/torrent.c b/btpd/torrent.c index 18eedba..d99cd80 100644 --- a/btpd/torrent.c +++ b/btpd/torrent.c @@ -16,9 +16,14 @@ #include "tracker_req.h" #include "stream.h" +#define SAVE_INTERVAL 300 + static unsigned m_ntorrents; static struct torrent_tq m_torrents = BTPDQ_HEAD_INITIALIZER(m_torrents); +static unsigned m_tsave; +static struct torrent *m_savetp; + const struct torrent_tq * torrent_get_all(void) { @@ -113,6 +118,10 @@ torrent_start(struct tlib *tl) m_ntorrents++; cm_start(tp, 0); free(mi); + if (m_ntorrents == 1) { + m_tsave = btpd_seconds + SAVE_INTERVAL; + m_savetp = tp; + } return IPC_OK; } else { mi_free_files(tp->nfiles, tp->files); @@ -137,6 +146,9 @@ torrent_kill(struct torrent *tp) net_kill(tp); cm_kill(tp); mi_free_files(tp->nfiles, tp->files); + if (m_savetp == tp) + if ((m_savetp = BTPDQ_NEXT(tp, entry)) == NULL) + m_savetp = BTPDQ_FIRST(&m_torrents); free(tp); } @@ -157,7 +169,7 @@ torrent_stop(struct torrent *tp, int delete) if (cm_active(tp)) cm_stop(tp); if (!delete) - tlib_update_info(tp->tl); + tlib_update_info(tp->tl, 0); break; case T_STOPPING: if (tr_active(tp)) @@ -211,4 +223,15 @@ torrent_on_tick_all(void) struct torrent *tp, *next; BTPDQ_FOREACH_MUTABLE(tp, &m_torrents, entry, next) torrent_on_tick(tp); + + if (m_savetp != NULL && m_tsave <= btpd_seconds) { + if (m_savetp->state == T_LEECH || m_savetp->state == T_SEED) { + tlib_update_info(m_savetp->tl, 1); + if ((m_savetp = BTPDQ_NEXT(m_savetp, entry)) == NULL) + m_savetp = BTPDQ_FIRST(&m_torrents); + if (m_ntorrents > 0) + m_tsave = btpd_seconds + + max(m_ntorrents, SAVE_INTERVAL) / m_ntorrents; + } + } }