Commit f0d2ddbb by Carlos Martín Nieto

remote: support fetch cancelation

Introduce git_remote_stop() which sets a variable that is checked by
the fetch process in a few key places. If this is variable is set, the
fetch is aborted.
parent 4c47a8bc
...@@ -199,6 +199,14 @@ GIT_EXTERN(int) git_remote_download(git_remote *remote, git_off_t *bytes, git_in ...@@ -199,6 +199,14 @@ GIT_EXTERN(int) git_remote_download(git_remote *remote, git_off_t *bytes, git_in
GIT_EXTERN(int) git_remote_connected(git_remote *remote); GIT_EXTERN(int) git_remote_connected(git_remote *remote);
/** /**
* Cancel the operation
*
* At certain points in its operation, the network code checks whether
* the operation has been cancelled and if so stops the operation.
*/
GIT_EXTERN(void) git_remote_stop(git_remote *remote);
/**
* Disconnect from the remote * Disconnect from the remote
* *
* Close the connection to the remote and free the underlying * Close the connection to the remote and free the underlying
......
...@@ -152,7 +152,7 @@ int git_fetch_negotiate(git_remote *remote) ...@@ -152,7 +152,7 @@ int git_fetch_negotiate(git_remote *remote)
gitno_buffer *buf = &t->buffer; gitno_buffer *buf = &t->buffer;
git_buf data = GIT_BUF_INIT; git_buf data = GIT_BUF_INIT;
git_revwalk *walk = NULL; git_revwalk *walk = NULL;
int error, pkt_type; int error = -1, pkt_type;
unsigned int i; unsigned int i;
git_oid oid; git_oid oid;
...@@ -190,6 +190,12 @@ int git_fetch_negotiate(git_remote *remote) ...@@ -190,6 +190,12 @@ int git_fetch_negotiate(git_remote *remote)
git_pkt_buffer_have(&oid, &data); git_pkt_buffer_have(&oid, &data);
i++; i++;
if (i % 20 == 0) { if (i % 20 == 0) {
if (t->cancel.val) {
giterr_set(GITERR_NET, "The fetch was cancelled by the user");
error = GIT_EUSER;
goto on_error;
}
git_pkt_buffer_flush(&data); git_pkt_buffer_flush(&data);
if (git_buf_oom(&data)) if (git_buf_oom(&data))
goto on_error; goto on_error;
...@@ -254,6 +260,11 @@ int git_fetch_negotiate(git_remote *remote) ...@@ -254,6 +260,11 @@ int git_fetch_negotiate(git_remote *remote)
} }
git_pkt_buffer_done(&data); git_pkt_buffer_done(&data);
if (t->cancel.val) {
giterr_set(GITERR_NET, "The fetch was cancelled by the user");
error = GIT_EUSER;
goto on_error;
}
if (t->negotiation_step(t, data.ptr, data.size) < 0) if (t->negotiation_step(t, data.ptr, data.size) < 0)
goto on_error; goto on_error;
...@@ -288,7 +299,7 @@ int git_fetch_negotiate(git_remote *remote) ...@@ -288,7 +299,7 @@ int git_fetch_negotiate(git_remote *remote)
on_error: on_error:
git_revwalk_free(walk); git_revwalk_free(walk);
git_buf_free(&data); git_buf_free(&data);
return -1; return error;
} }
int git_fetch_download_pack(git_remote *remote, git_off_t *bytes, git_indexer_stats *stats) int git_fetch_download_pack(git_remote *remote, git_off_t *bytes, git_indexer_stats *stats)
...@@ -305,11 +316,16 @@ int git_fetch_download_pack(git_remote *remote, git_off_t *bytes, git_indexer_st ...@@ -305,11 +316,16 @@ int git_fetch_download_pack(git_remote *remote, git_off_t *bytes, git_indexer_st
} }
static int no_sideband(git_indexer_stream *idx, gitno_buffer *buf, git_off_t *bytes, git_indexer_stats *stats) static int no_sideband(git_transport *t, git_indexer_stream *idx, gitno_buffer *buf, git_off_t *bytes, git_indexer_stats *stats)
{ {
int recvd; int recvd;
do { do {
if (t->cancel.val) {
giterr_set(GITERR_NET, "The fetch was cancelled by the user");
return GIT_EUSER;
}
if (git_indexer_stream_add(idx, buf->data, buf->offset, stats) < 0) if (git_indexer_stream_add(idx, buf->data, buf->offset, stats) < 0)
return -1; return -1;
...@@ -337,6 +353,7 @@ int git_fetch__download_pack( ...@@ -337,6 +353,7 @@ int git_fetch__download_pack(
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
gitno_buffer *buf = &t->buffer; gitno_buffer *buf = &t->buffer;
git_indexer_stream *idx = NULL; git_indexer_stream *idx = NULL;
int error = -1;
if (git_buf_joinpath(&path, git_repository_path(repo), "objects/pack") < 0) if (git_buf_joinpath(&path, git_repository_path(repo), "objects/pack") < 0)
return -1; return -1;
...@@ -354,7 +371,7 @@ int git_fetch__download_pack( ...@@ -354,7 +371,7 @@ int git_fetch__download_pack(
* check which one belongs there. * check which one belongs there.
*/ */
if (!t->caps.side_band && !t->caps.side_band_64k) { if (!t->caps.side_band && !t->caps.side_band_64k) {
if (no_sideband(idx, buf, bytes, stats) < 0) if (no_sideband(t, idx, buf, bytes, stats) < 0)
goto on_error; goto on_error;
git_indexer_stream_free(idx); git_indexer_stream_free(idx);
...@@ -362,6 +379,12 @@ int git_fetch__download_pack( ...@@ -362,6 +379,12 @@ int git_fetch__download_pack(
} }
do { do {
if (t->cancel.val) {
giterr_set(GITERR_NET, "The fetch was cancelled by the user");
error = GIT_EUSER;
goto on_error;
}
git_pkt *pkt; git_pkt *pkt;
if (recv_pkt(&pkt, buf) < 0) if (recv_pkt(&pkt, buf) < 0)
goto on_error; goto on_error;
...@@ -395,7 +418,7 @@ int git_fetch__download_pack( ...@@ -395,7 +418,7 @@ int git_fetch__download_pack(
on_error: on_error:
git_buf_free(&path); git_buf_free(&path);
git_indexer_stream_free(idx); git_indexer_stream_free(idx);
return -1; return error;
} }
int git_fetch_setup_walk(git_revwalk **out, git_repository *repo) int git_fetch_setup_walk(git_revwalk **out, git_repository *repo)
......
...@@ -558,6 +558,11 @@ int git_remote_connected(git_remote *remote) ...@@ -558,6 +558,11 @@ int git_remote_connected(git_remote *remote)
return remote->transport == NULL ? 0 : remote->transport->connected; return remote->transport == NULL ? 0 : remote->transport->connected;
} }
void git_remote_stop(git_remote *remote)
{
git_atomic_set(&remote->transport->cancel, 1);
}
void git_remote_disconnect(git_remote *remote) void git_remote_disconnect(git_remote *remote)
{ {
assert(remote); assert(remote);
......
...@@ -91,6 +91,8 @@ struct git_transport { ...@@ -91,6 +91,8 @@ struct git_transport {
GIT_SOCKET socket; GIT_SOCKET socket;
git_transport_caps caps; git_transport_caps caps;
void *cb_data; void *cb_data;
git_atomic cancel;
/** /**
* Connect and store the remote heads * Connect and store the remote heads
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment