delays are now a chain instead of a stack

This commit is contained in:
Axel Kittenberger 2010-08-14 21:44:58 +00:00
parent 477292d75c
commit f7b6450c2e

115
lsyncd.c
View File

@ -42,7 +42,7 @@
/** /**
* Define for debug memchecking. * Define for debug memchecking.
*/ */
//#define MEMCHECK #define MEMCHECK
/** /**
* Number of inotifies to read max. at once from the kernel. * Number of inotifies to read max. at once from the kernel.
@ -397,36 +397,24 @@ struct watch_vector {
size_t len; size_t len;
}; };
/**
* TODO
*/
struct file_delay {
char *filename;
struct watch *watch;
};
/**
* TODO
*/
struct file_vector {
struct file_delay *data;
size_t size;
size_t len;
};
/** /**
* A delayed entry * A delayed entry
*/ */
struct delay { struct delay {
/** /**
* Pointer the watch * Pointer the watch.
*/ */
struct watch *watch; struct watch *watch;
/** /**
* Alarm time for the delay * Alarm time for the delay.
*/ */
clock_t alarm; clock_t alarm;
/**
* Pointer to the next delay.
*/
struct delay * next;
}; };
/** /**
@ -434,19 +422,14 @@ struct delay {
*/ */
struct delay_vector { struct delay_vector {
/** /**
* list of pointers to all delays * pointer to first delay
*/ */
struct delay *data; struct delay *first;
/** /**
* number of entries allocated * pointer to last delay
*/ */
size_t size; struct delay *last;
/**
* number of entries used
*/
size_t len;
}; };
/** /**
@ -1057,20 +1040,24 @@ append_delay(const struct log *log,
struct watch *watch, struct watch *watch,
clock_t alarm) clock_t alarm)
{ {
struct delay * newd;
if (watch->delayed) { if (watch->delayed) {
return false; return false;
} }
watch->delayed = true; watch->delayed = true;
newd = s_calloc(log, 1, sizeof(struct delay), "a delay");
newd->watch = watch;
newd->alarm = alarm;
newd->next = NULL;
// extend the delays vector if needed if (!delays->first) {
if (delays->len + 1 >= delays->size) { // delays vector was empty
delays->size *= 2; delays->first = delays->last = newd;
delays->data = s_realloc(log, delays->data, delays->size * sizeof(struct delay)); } else {
delays->last->next = newd;
delays->last = newd;
} }
delays->data[delays->len].watch = watch;
delays->data[delays->len].alarm = alarm;
delays->len++;
return true; return true;
} }
@ -1082,8 +1069,13 @@ append_delay(const struct log *log,
void void
remove_first_delay(struct delay_vector *delays) remove_first_delay(struct delay_vector *delays)
{ {
delays->data[0].watch->delayed = false; struct delay *fd = delays->first;
memmove(delays->data, delays->data + 1, (--delays->len) * sizeof(struct delay)); fd->watch->delayed = false;
delays->first = fd->next;
if (!delays->first) {
delays->last = NULL;
}
s_free(fd);
} }
/*--------------------------------------------------------------------------* /*--------------------------------------------------------------------------*
@ -1715,15 +1707,27 @@ remove_dirwatch(const struct global_options *opts,
// remove a possible delay // remove a possible delay
// (this dir is on the to do/delay list) // (this dir is on the to do/delay list)
if (delays->len > 0 && w->delayed) { if (w->delayed) {
int i; struct delay *d, *bd; // the current and the pointer before.
for(i = 0; i < delays->len; i++) { bd = NULL;
if (delays->data[i].watch == w) { d = delays->first;
// move the list up. while (d) {
memmove(delays->data + i, delays->data + i + 1, (delays->len - i - 1) * sizeof(struct delay)); if (d->watch == w) {
delays->len--; // remove this entry
if (bd) {
bd->next = d->next;
} else {
// this is the first;
delays->first = d->next;
}
if (delays->last == d) {
delays->last = bd;
}
s_free(d);
break; break;
} }
bd = d;
d = d->next;
} }
} }
@ -1875,17 +1879,17 @@ master_loop(const struct global_options *opts,
while (keep_going) { while (keep_going) {
int do_read; int do_read;
if (delays->len > 0 && time_after_eq(times(NULL), delays->data[0].alarm)) { if (delays->first && time_after_eq(times(NULL), delays->first->alarm)) {
// there is a delay that wants to be handled already // there is a delay that wants to be handled already
// do not read from inotify_fd and jump directly to delay handling // do not read from inotify_fd and jump directly to delay handling
printlogf(log, DEBUG, "immediately handling delayed entries"); printlogf(log, DEBUG, "immediately handling delayed entries");
do_read = 0; do_read = 0;
} else if (opts->delay > 0 && delays->len > 0) { } else if (opts->delay > 0 && delays->first) {
// use select() to determine what happens first // use select() to determine what happens first
// a new event or "alarm" of an event to actually // a new event or "alarm" of an event to actually
// call its binary. The delay with the index 0 // call its binary. The delay with the index 0
// should have the nearest alarm time. // should have the nearest alarm time.
alarm = delays->data[0].alarm; alarm = delays->first->alarm;
now = times(NULL); now = times(NULL);
tv.tv_sec = (alarm - now) / clocks_per_sec; tv.tv_sec = (alarm - now) / clocks_per_sec;
tv.tv_usec = (alarm - now) * 1000000 / clocks_per_sec % 1000000; tv.tv_usec = (alarm - now) * 1000000 / clocks_per_sec % 1000000;
@ -1942,8 +1946,8 @@ master_loop(const struct global_options *opts,
// until one item is found whose expiry time has not yet come // until one item is found whose expiry time has not yet come
// or the stack is empty. Using now time - times(NULL) - everytime // or the stack is empty. Using now time - times(NULL) - everytime
// again as time may progresses while handling delayed entries. // again as time may progresses while handling delayed entries.
while (delays->len > 0 && time_after_eq(times(NULL), delays->data[0].alarm)) { while (delays->first && time_after_eq(times(NULL), delays->first->alarm)) {
rsync_dir(opts, delays->data[0].watch, "delay expired"); rsync_dir(opts, delays->first->watch, "delay expired");
remove_first_delay(delays); remove_first_delay(delays);
} }
} }
@ -2710,8 +2714,7 @@ one_main(int argc, char **argv)
watches.size = VECT_INIT_SIZE; watches.size = VECT_INIT_SIZE;
watches.data = s_calloc(log, watches.size, sizeof(struct watch *), "watches vector"); watches.data = s_calloc(log, watches.size, sizeof(struct watch *), "watches vector");
delays.size = VECT_INIT_SIZE; delays.first = delays.last = NULL;
delays.data = s_calloc(log, delays.size, sizeof(struct delay), "delays vector");
{ {
// add all watches // add all watches
@ -2759,6 +2762,8 @@ one_main(int argc, char **argv)
{ {
// memory clean up // memory clean up
int i; int i;
struct delay * d;
reset_options(&opts); reset_options(&opts);
for(i = 0; i < watches.len; i++) { for(i = 0; i < watches.len; i++) {
if (watches.data[i]->dirname) { if (watches.data[i]->dirname) {
@ -2767,7 +2772,9 @@ one_main(int argc, char **argv)
s_free(watches.data[i]); s_free(watches.data[i]);
} }
s_free(watches.data); s_free(watches.data);
s_free(delays.data); for(d = delays.first; d; d = d->next) {
s_free(d);
}
for(i = 0; i < excludes.len; i++) { for(i = 0; i < excludes.len; i++) {
s_free(excludes.data[i]); s_free(excludes.data[i]);
} }