Browse Source

o Fixed: cm->active was not set to 0 in cm_stop.

o Since we only use the mtime and size field of the stat struct for resume
  info, we now use a struct with only those two fields. This reduces stack
  usage.
master
Richard Nyberg 19 years ago
parent
commit
44165a86d0
1 changed files with 28 additions and 19 deletions
  1. +28
    -19
      btpd/content.c

+ 28
- 19
btpd/content.c View File

@@ -199,7 +199,7 @@ void
cm_stop(struct torrent *tp) cm_stop(struct torrent *tp)
{ {
struct content *cm = tp->cm; struct content *cm = tp->cm;
cm->active = 0;
struct cm_op *op = BTPDQ_FIRST(&cm->todoq); struct cm_op *op = BTPDQ_FIRST(&cm->todoq);
if (op != NULL && op->type == CM_START) { if (op != NULL && op->type == CM_START) {
pthread_mutex_lock(&m_long_comm.lock); pthread_mutex_lock(&m_long_comm.lock);
@@ -562,22 +562,31 @@ test_torrent(struct torrent *tp, volatile sig_atomic_t *cancel)
return err; return err;
} }


struct rstat {
time_t mtime;
off_t size;
};

int int
stat_and_adjust(struct torrent *tp, struct stat ret[]) stat_and_adjust(struct torrent *tp, struct rstat ret[])
{ {
char path[PATH_MAX]; char path[PATH_MAX];
struct stat sb;
for (int i = 0; i < tp->meta.nfiles; i++) { for (int i = 0; i < tp->meta.nfiles; i++) {
snprintf(path, PATH_MAX, "library/%s/content/%s", tp->relpath, snprintf(path, PATH_MAX, "library/%s/content/%s", tp->relpath,
tp->meta.files[i].path); tp->meta.files[i].path);
again: again:
if (stat(path, &ret[i]) == -1) { if (stat(path, &sb) == -1) {
if (errno == ENOENT) { if (errno == ENOENT) {
ret[i].st_mtime = -1; ret[i].mtime = -1;
ret[i].st_size = -1; ret[i].size = -1;
} else } else
return errno; return errno;
} else {
ret[i].mtime = sb.st_mtime;
ret[i].size = sb.st_size;
} }
if (ret[i].st_size > tp->meta.files[i].length) { if (ret[i].size > tp->meta.files[i].length) {
if (truncate(path, tp->meta.files[i].length) != 0) if (truncate(path, tp->meta.files[i].length) != 0)
return errno; return errno;
goto again; goto again;
@@ -587,7 +596,7 @@ again:
} }


static int static int
load_resume(struct torrent *tp, struct stat sbs[]) load_resume(struct torrent *tp, struct rstat sbs[])
{ {
int err, ver; int err, ver;
FILE *fp; FILE *fp;
@@ -606,7 +615,7 @@ load_resume(struct torrent *tp, struct stat sbs[])
time_t time; time_t time;
if (fscanf(fp, "%qd %ld\n", &size, &time) != 2) if (fscanf(fp, "%qd %ld\n", &size, &time) != 2)
goto invalid; goto invalid;
if (sbs[i].st_size != size || sbs[i].st_mtime != time) if (sbs[i].size != size || sbs[i].mtime != time)
err = EINVAL; err = EINVAL;
} }
if (fread(tp->cm->piece_field, 1, pfsiz, fp) != pfsiz) if (fread(tp->cm->piece_field, 1, pfsiz, fp) != pfsiz)
@@ -623,18 +632,15 @@ invalid:
} }


static int static int
save_resume(struct torrent *tp) save_resume(struct torrent *tp, struct rstat sbs[])
{ {
int err; int err;
FILE *fp; FILE *fp;
struct stat sbs[tp->meta.nfiles];
if ((err = stat_and_adjust(tp, sbs)) != 0)
return err;
if ((err = vfopen(&fp, "wb", "library/%s/resume", tp->relpath)) != 0) if ((err = vfopen(&fp, "wb", "library/%s/resume", tp->relpath)) != 0)
return err; return err;
fprintf(fp, "%d\n", 1); fprintf(fp, "%d\n", 1);
for (int i = 0; i < tp->meta.nfiles; i++) for (int i = 0; i < tp->meta.nfiles; i++)
fprintf(fp, "%qd %ld\n", (long long)sbs[i].st_size, sbs[i].st_mtime); fprintf(fp, "%qd %ld\n", (long long)sbs[i].size, sbs[i].mtime);
fwrite(tp->cm->piece_field, 1, ceil(tp->meta.npieces / 8.0), fp); fwrite(tp->cm->piece_field, 1, ceil(tp->meta.npieces / 8.0), fp);
fwrite(tp->cm->block_field, 1, tp->meta.npieces * tp->cm->bppbf, fp); fwrite(tp->cm->block_field, 1, tp->meta.npieces * tp->cm->bppbf, fp);
if (fclose(fp) != 0) if (fclose(fp) != 0)
@@ -645,14 +651,17 @@ save_resume(struct torrent *tp)
static void static void
cm_td_save(struct cm_op *op) cm_td_save(struct cm_op *op)
{ {
save_resume(op->tp); struct torrent *tp = op->tp;
struct rstat sbs[tp->meta.nfiles];
if (stat_and_adjust(tp, sbs) == 0)
save_resume(tp, sbs);
} }


static void static void
cm_td_start(struct cm_op *op) cm_td_start(struct cm_op *op)
{ {
int err, resume_clean = 0, tested_torrent = 0; int err, resume_clean = 0, tested_torrent = 0;
struct stat sbs[op->tp->meta.nfiles]; struct rstat sbs[op->tp->meta.nfiles];
struct torrent *tp = op->tp; struct torrent *tp = op->tp;
struct content *cm = tp->cm; struct content *cm = tp->cm;


@@ -664,7 +673,7 @@ cm_td_start(struct cm_op *op)
memset(cm->pos_field, 0xff, ceil(tp->meta.npieces / 8.0)); memset(cm->pos_field, 0xff, ceil(tp->meta.npieces / 8.0));
off_t off = 0; off_t off = 0;
for (int i = 0; i < tp->meta.nfiles; i++) { for (int i = 0; i < tp->meta.nfiles; i++) {
if (sbs[i].st_size == -1 || sbs[i].st_size == 0) { if (sbs[i].size == -1 || sbs[i].size == 0) {
uint32_t start = off / tp->meta.piece_length; uint32_t start = off / tp->meta.piece_length;
uint32_t end = (off + tp->meta.files[i].length - 1) / uint32_t end = (off + tp->meta.files[i].length - 1) /
tp->meta.piece_length; tp->meta.piece_length;
@@ -674,8 +683,8 @@ cm_td_start(struct cm_op *op)
bzero(cm->block_field + start * cm->bppbf, cm->bppbf); bzero(cm->block_field + start * cm->bppbf, cm->bppbf);
start++; start++;
} }
} else if (sbs[i].st_size < tp->meta.files[i].length) { } else if (sbs[i].size < tp->meta.files[i].length) {
uint32_t start = (off + sbs[i].st_size) / uint32_t start = (off + sbs[i].size) /
tp->meta.piece_length; tp->meta.piece_length;
uint32_t end = (off + tp->meta.files[i].length - 1) / uint32_t end = (off + tp->meta.files[i].length - 1) /
tp->meta.piece_length; tp->meta.piece_length;
@@ -729,7 +738,7 @@ cm_td_start(struct cm_op *op)
} }


if (!resume_clean) if (!resume_clean)
save_resume(tp); save_resume(tp, sbs);


out: out:
if (!op->u.start.cancel && err != 0) if (!op->u.start.cancel && err != 0)


||||||
x
 
000:0
Loading…
Cancel
Save