29
#include "commit-graph.h"
30
#include "commit-reach.h"
31
#include "shallow.h"
32
+#include "trace.h"
33
#include "write-or-die.h"
34
#include "json-writer.h"
35
#include "strmap.h"
219
};
220
221
static int relay_pack_data(int pack_objects_out, struct output_state *os,
221
- int use_sideband, int write_packfile_line)
222
+ int use_sideband, int write_packfile_line,
223
+ bool *did_send_data)
224
{
225
/*
226
* We keep the last byte to ourselves
234
*/
235
ssize_t readsz;
236
237
+ *did_send_data = false;
238
+
239
readsz = xread(pack_objects_out, os->buffer + os->used,
240
sizeof(os->buffer) - os->used);
241
if (readsz < 0) {
251
if (os->packfile_uris_started)
252
packet_delim(1);
253
packet_write_fmt(1, "\1packfile\n");
254
+ *did_send_data = true;
255
}
256
break;
257
}
264
}
265
*p = '\0';
266
packet_write_fmt(1, "\1%s\n", os->buffer);
267
+ *did_send_data = true;
268
269
os->used -= p - os->buffer + 1;
270
memmove(os->buffer, p + 1, os->used);
285
os->used = 0;
286
}
287
288
+ *did_send_data = true;
289
return readsz;
290
}
291
297
char progress[128];
298
char abort_msg[] = "aborting due to possible repository "
299
"corruption on the remote side.";
300
+ uint64_t last_sent_ms = 0;
301
ssize_t sz;
302
int i;
303
FILE *pipe_fd;
373
*/
374
375
while (1) {
376
+ uint64_t now_ms = getnanotime() / 1000000;
377
struct pollfd pfd[2];
369
- int pe, pu, pollsize, polltimeout;
378
+ int pe, pu, pollsize, polltimeout_ms;
379
int ret;
380
381
+ if (!last_sent_ms)
382
+ last_sent_ms = now_ms;
383
+
384
reset_timeout(pack_data->timeout);
385
386
pollsize = 0;
402
if (!pollsize)
403
break;
404
393
- polltimeout = pack_data->keepalive < 0
394
- ? -1
395
- : 1000 * pack_data->keepalive;
405
+ if (pack_data->keepalive < 0) {
406
+ polltimeout_ms = -1;
407
+ } else {
408
+ /*
409
+ * The polling timeout needs to be adjusted based on
410
+ * the time we have sent our last package. The longer
411
+ * it's been in the past, the shorter the timeout
412
+ * becomes until we eventually don't block at all.
413
+ */
414
+ polltimeout_ms = 1000 * pack_data->keepalive - (now_ms - last_sent_ms);
415
+ if (polltimeout_ms < 0)
416
+ polltimeout_ms = 0;
417
+ }
418
397
- ret = poll(pfd, pollsize, polltimeout);
419
+ ret = poll(pfd, pollsize, polltimeout_ms);
420
421
if (ret < 0) {
422
if (errno != EINTR) {
425
}
426
continue;
427
}
428
+
429
if (0 <= pe && (pfd[pe].revents & (POLLIN|POLLHUP))) {
430
/* Status ready; we ship that in the side-band
431
* or dump to the standard error.
432
*/
433
sz = xread(pack_objects.err, progress,
434
sizeof(progress));
412
- if (0 < sz)
435
+ if (0 < sz) {
436
send_client_data(2, progress, sz,
437
pack_data->use_sideband);
415
- else if (sz == 0) {
438
+ last_sent_ms = now_ms;
439
+ } else if (sz == 0) {
440
close(pack_objects.err);
441
pack_objects.err = -1;
442
}
445
/* give priority to status messages */
446
continue;
447
}
448
+
449
if (0 <= pu && (pfd[pu].revents & (POLLIN|POLLHUP))) {
450
+ bool did_send_data;
451
int result = relay_pack_data(pack_objects.out,
452
output_state,
453
pack_data->use_sideband,
428
- !!uri_protocols);
454
+ !!uri_protocols,
455
+ &did_send_data);
456
457
if (result == 0) {
458
close(pack_objects.out);
460
} else if (result < 0) {
461
goto fail;
462
}
463
+
464
+ if (did_send_data)
465
+ last_sent_ms = now_ms;
466
}
467
468
/*
478
if (!ret && pack_data->use_sideband) {
479
static const char buf[] = "0005\1";
480
write_or_die(1, buf, 5);
481
+ last_sent_ms = now_ms;
482
}
483
}
484