int send_dir_ndx = -1, send_dir_depth = -1;
int flist_cnt = 0; /* how many (non-tmp) file list objects exist */
int file_total = 0; /* total of all active items over all file-lists */
+int file_old_total = 0; /* total of active items that will soon be gone */
int flist_eof = 0; /* all the file-lists are now known */
#define NORMAL_NAME 0
struct file_list *flist;
int64 start_write;
uint16 prev_flags;
- int old_cnt, save_io_error = io_error;
+ int save_io_error = io_error;
if (flist_eof)
return;
+ if (at_least < 0)
+ at_least = file_total - file_old_total + 1;
+
/* Keep sending data until we have the requested number of
* files in the upcoming file-lists. */
- old_cnt = cur_flist->used;
- for (flist = first_flist; flist != cur_flist; flist = flist->next)
- old_cnt += flist->used;
- while (file_total - old_cnt < at_least) {
+ while (file_total - file_old_total < at_least) {
struct file_struct *file = dir_flist->sorted[send_dir_ndx];
int dir_ndx, dstart = stats.num_dirs;
const char *pathname = F_PATHNAME(file);
break;
write_ndx(sock_f_out, NDX_DONE);
- if (!read_batch)
- maybe_flush_socket(1);
+ if (!read_batch && !flist_eof) {
+ int old_total = 0;
+ for (flist = first_flist; flist != cur_flist; flist = flist->next)
+ old_total += flist->used;
+ maybe_flush_socket(!flist_eof && file_total - old_total < MIN_FILECNT_LOOKAHEAD/2);
+ }
if (delete_during == 2 || !dir_tweaking) {
/* Skip directory touch-up. */
do {
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links && inc_recurse) {
- while (!flist_eof && file_total < FILECNT_LOOKAHEAD/2)
+ while (!flist_eof && file_total < MIN_FILECNT_LOOKAHEAD/2)
wait_for_receiver();
}
#endif
extern int io_error;
extern int eol_nulls;
extern int flist_eof;
+extern int file_total;
+extern int file_old_total;
extern int list_only;
extern int read_batch;
extern int protect_args;
maxfd = new_fd;
}
- tv.tv_sec = select_timeout;
+ if (am_sender && inc_recurse && !flist_eof && !defer_forwarding_messages && !cnt
+ && file_total - file_old_total < MAX_FILECNT_LOOKAHEAD
+ && file_total - file_old_total >= MIN_FILECNT_LOOKAHEAD)
+ tv.tv_sec = 0;
+ else
+ tv.tv_sec = select_timeout;
tv.tv_usec = 0;
errno = 0;
defer_forwarding_messages = 0;
exit_cleanup(RERR_SOCKETIO);
}
- check_timeout();
+ if (am_sender && tv.tv_sec == 0)
+ send_extra_file_list(sock_f_out, -1);
+ else
+ check_timeout();
continue;
}
extern int inc_recurse;
extern int inplace;
extern int flist_eof;
+extern int file_old_total;
extern int msgs2stderr;
extern int keep_dirlinks;
extern int make_backups;
goto read_loop;
}
- cur_flist = flist_for_ndx(ndx, "read_ndx_and_attrs");
+ flist = flist_for_ndx(ndx, "read_ndx_and_attrs");
+ if (flist != cur_flist) {
+ cur_flist = flist;
+ if (am_sender) {
+ file_old_total = cur_flist->used;
+ for (flist = first_flist; flist != cur_flist; flist = flist->next)
+ file_old_total += flist->used;
+ }
+ }
if (iflags & ITEM_BASIS_TYPE_FOLLOWS)
fnamecmp_type = read_byte(f_in);
#define OLD_PROTOCOL_VERSION 25
#define MAX_PROTOCOL_VERSION 40
-#define FILECNT_LOOKAHEAD 1000
+#define MIN_FILECNT_LOOKAHEAD 1000
+#define MAX_FILECNT_LOOKAHEAD 10000
#define RSYNC_PORT 873
while (1) {
if (inc_recurse)
- send_extra_file_list(f_out, FILECNT_LOOKAHEAD);
+ send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD);
/* This call also sets cur_flist. */
ndx = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
}
if (inc_recurse)
- send_extra_file_list(f_out, FILECNT_LOOKAHEAD);
+ send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD);
if (ndx - cur_flist->ndx_start >= 0)
file = cur_flist->files[ndx - cur_flist->ndx_start];