diff options
author | Jameson Miller <jamill@microsoft.com> | 2013-10-02 13:45:32 -0400 |
---|---|---|
committer | Jameson Miller <jamill@microsoft.com> | 2013-10-02 15:12:44 -0400 |
commit | 5b1882254551cc9031d919c2f31c05153a665762 (patch) | |
tree | a5a4b2fab8622f11bd70bd4388f14bc6557d07a1 /src/pack-objects.c | |
parent | 5bfead1dba919f6b47f52da675ea94407e8baf49 (diff) | |
download | libgit2-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.c | 43 |
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) |