summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Straub <bs@github.com>2012-10-19 19:23:32 -0700
committerBen Straub <bs@github.com>2012-10-19 19:36:23 -0700
commit7bcd9e23e8f64c8622e9213ee0fa3d75d058053b (patch)
tree42d73408bb7e3df8d487d38ecfaf0efb9c0531c6 /src
parent25e8b20169a6f6919ad49cf32220975ab96b35c8 (diff)
downloadlibgit2-7bcd9e23e8f64c8622e9213ee0fa3d75d058053b.tar.gz
gitno_buffer: callback on each packet
The fetch code takes advantage of this to implement a progress callback every 100kb of transfer.
Diffstat (limited to 'src')
-rw-r--r--src/fetch.c33
-rw-r--r--src/netops.c3
-rw-r--r--src/netops.h2
-rw-r--r--src/transports/http.c2
4 files changed, 39 insertions, 1 deletions
diff --git a/src/fetch.c b/src/fetch.c
index 583c79a34..3f69c2cbf 100644
--- a/src/fetch.c
+++ b/src/fetch.c
@@ -19,6 +19,8 @@
#include "netops.h"
#include "pkt.h"
+#define NETWORK_XFER_THRESHOLD (100*1024)
+
struct filter_payload {
git_remote *remote;
const git_refspec *spec, *tagspec;
@@ -348,6 +350,28 @@ static int no_sideband(git_transport *t, git_indexer_stream *idx, gitno_buffer *
return 0;
}
+struct network_packetsize_payload
+{
+ git_indexer_progress_callback callback;
+ void *payload;
+ git_indexer_stats *stats;
+ git_off_t last_fired_bytes;
+};
+
+static void network_packetsize(int received, void *payload)
+{
+ struct network_packetsize_payload *npp = (struct network_packetsize_payload*)payload;
+
+ /* Accumulate bytes */
+ npp->stats->bytes += received;
+
+ /* Fire notification if the threshold is reached */
+ if ((npp->stats->bytes - npp->last_fired_bytes) > NETWORK_XFER_THRESHOLD) {
+ npp->last_fired_bytes = npp->stats->bytes;
+ npp->callback(npp->stats, npp->payload);
+ }
+}
+
/* Receiving data from a socket and storing it is pretty much the same for git and HTTP */
int git_fetch__download_pack(
git_transport *t,
@@ -361,6 +385,15 @@ int git_fetch__download_pack(
gitno_buffer *buf = &t->buffer;
git_indexer_stream *idx = NULL;
int error = -1;
+ struct network_packetsize_payload npp = {0};
+
+ if (progress_cb) {
+ npp.callback = progress_cb;
+ npp.payload = progress_payload;
+ npp.stats = stats;
+ buf->packetsize_cb = &network_packetsize;
+ buf->packetsize_payload = &npp;
+ }
if (git_buf_joinpath(&path, git_repository_path(repo), "objects/pack") < 0)
return -1;
diff --git a/src/netops.c b/src/netops.c
index df502e619..d9663e63c 100644
--- a/src/netops.c
+++ b/src/netops.c
@@ -117,6 +117,7 @@ static int gitno__recv_ssl(gitno_buffer *buf)
}
buf->offset += ret;
+ if (buf->packetsize_cb) buf->packetsize_cb(ret, buf->packetsize_payload);
return ret;
}
#endif
@@ -132,6 +133,7 @@ int gitno__recv(gitno_buffer *buf)
}
buf->offset += ret;
+ if (buf->packetsize_cb) buf->packetsize_cb(ret, buf->packetsize_payload);
return ret;
}
@@ -142,7 +144,6 @@ void gitno_buffer_setup_callback(
size_t len,
int (*recv)(gitno_buffer *buf), void *cb_data)
{
- memset(buf, 0x0, sizeof(gitno_buffer));
memset(data, 0x0, len);
buf->data = data;
buf->len = len;
diff --git a/src/netops.h b/src/netops.h
index 7c53fd0dc..64da7fba9 100644
--- a/src/netops.h
+++ b/src/netops.h
@@ -20,6 +20,8 @@ struct gitno_buffer {
#endif
int (*recv)(gitno_buffer *buffer);
void *cb_data;
+ void (*packetsize_cb)(int received, void *payload);
+ void *packetsize_payload;
};
void gitno_buffer_setup(git_transport *t, gitno_buffer *buf, char *data, size_t len);
diff --git a/src/transports/http.c b/src/transports/http.c
index 93dd0c326..0efd220c3 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -379,6 +379,8 @@ static int http_recv_cb(gitno_buffer *buf)
#ifndef GIT_WINHTTP
gitno_buffer_setup(transport, &inner, buffer, sizeof(buffer));
+ inner.packetsize_cb = buf->packetsize_cb;
+ inner.packetsize_payload = buf->packetsize_payload;
if ((error = gitno_recv(&inner)) < 0)
return -1;