summaryrefslogtreecommitdiff
path: root/src/pack-objects.c
diff options
context:
space:
mode:
authorJameson Miller <jamill@microsoft.com>2013-10-02 13:45:32 -0400
committerJameson Miller <jamill@microsoft.com>2013-10-02 15:12:44 -0400
commit5b1882254551cc9031d919c2f31c05153a665762 (patch)
treea5a4b2fab8622f11bd70bd4388f14bc6557d07a1 /src/pack-objects.c
parent5bfead1dba919f6b47f52da675ea94407e8baf49 (diff)
downloadlibgit2-5b1882254551cc9031d919c2f31c05153a665762.tar.gz
Support cancellation in push operation
This commit adds cancellation for the push operation. This work consists of: 1) Support cancellation during push operation - During object counting phase - During network transfer phase - Propagate GIT_EUSER error code out to caller 2) Improve cancellation support during fetch - Handle cancellation request during network transfer phase - Clear error string when cancelled during indexing 3) Fix error handling in git_smart__download_pack Cancellation during push is still only handled in the pack building and network transfer stages of push (and not during packbuilding).
Diffstat (limited to 'src/pack-objects.c')
-rw-r--r--src/pack-objects.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/src/pack-objects.c b/src/pack-objects.c
index 2a2f36223..821f292b9 100644
--- a/src/pack-objects.c
+++ b/src/pack-objects.c
@@ -216,15 +216,19 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
assert(ret != 0);
kh_value(pb->object_ix, pos) = po;
+ pb->done = false;
+
if (pb->progress_cb) {
double current_time = git__timer();
if ((current_time - pb->last_progress_report_time) >= MIN_PROGRESS_UPDATE_INTERVAL) {
pb->last_progress_report_time = current_time;
- pb->progress_cb(GIT_PACKBUILDER_ADDING_OBJECTS, pb->nr_objects, 0, pb->progress_cb_payload);
+ if (pb->progress_cb(GIT_PACKBUILDER_ADDING_OBJECTS, pb->nr_objects, 0, pb->progress_cb_payload)) {
+ giterr_clear();
+ return GIT_EUSER;
+ }
}
}
- pb->done = false;
return 0;
}
@@ -591,49 +595,50 @@ static int write_pack(git_packbuilder *pb,
enum write_one_status status;
struct git_pack_header ph;
unsigned int i = 0;
+ int error = 0;
write_order = compute_write_order(pb);
- if (write_order == NULL)
- goto on_error;
+ if (write_order == NULL) {
+ error = -1;
+ goto done;
+ }
/* Write pack header */
ph.hdr_signature = htonl(PACK_SIGNATURE);
ph.hdr_version = htonl(PACK_VERSION);
ph.hdr_entries = htonl(pb->nr_objects);
- if (cb(&ph, sizeof(ph), data) < 0)
- goto on_error;
+ if ((error = cb(&ph, sizeof(ph), data)) < 0)
+ goto done;
- if (git_hash_update(&pb->ctx, &ph, sizeof(ph)) < 0)
- goto on_error;
+ if ((error = git_hash_update(&pb->ctx, &ph, sizeof(ph))) < 0)
+ goto done;
pb->nr_remaining = pb->nr_objects;
do {
pb->nr_written = 0;
for ( ; i < pb->nr_objects; ++i) {
po = write_order[i];
- if (write_one(&buf, pb, po, &status) < 0)
- goto on_error;
- if (cb(buf.ptr, buf.size, data) < 0)
- goto on_error;
+ if ((error = write_one(&buf, pb, po, &status)) < 0)
+ goto done;
+ if ((error = cb(buf.ptr, buf.size, data)) < 0)
+ goto done;
git_buf_clear(&buf);
}
pb->nr_remaining -= pb->nr_written;
} while (pb->nr_remaining && i < pb->nr_objects);
- git__free(write_order);
- git_buf_free(&buf);
- if (git_hash_final(&pb->pack_oid, &pb->ctx) < 0)
- goto on_error;
+ if ((error = git_hash_final(&pb->pack_oid, &pb->ctx)) < 0)
+ goto done;
- return cb(pb->pack_oid.id, GIT_OID_RAWSZ, data);
+ error = cb(pb->pack_oid.id, GIT_OID_RAWSZ, data);
-on_error:
+done:
git__free(write_order);
git_buf_free(&buf);
- return -1;
+ return error;
}
static int write_pack_buf(void *buf, size_t size, void *data)