vendor/libgit2/src/pack-objects.c in rugged-1.1.1 vs vendor/libgit2/src/pack-objects.c in rugged-1.2.0

- old
+ new

@@ -10,11 +10,11 @@ #include "zstream.h" #include "delta.h" #include "iterator.h" #include "netops.h" #include "pack.h" -#include "thread-utils.h" +#include "thread.h" #include "tree.h" #include "util.h" #include "revwalk.h" #include "commit_list.h" @@ -46,23 +46,15 @@ unsigned int uninteresting:1, seen:1; }; #ifdef GIT_THREADS - -#define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) do { \ - int result = git_mutex_##op(&(pb)->mtx); \ - assert(!result); \ - GIT_UNUSED(result); \ - } while (0) - +# define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) git_mutex_##op(&(pb)->mtx) #else +# define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) git__noop() +#endif -#define GIT_PACKBUILDER__MUTEX_OP(pb,mtx,op) GIT_UNUSED(pb) - -#endif /* GIT_THREADS */ - #define git_packbuilder__cache_lock(pb) GIT_PACKBUILDER__MUTEX_OP(pb, cache_mutex, lock) #define git_packbuilder__cache_unlock(pb) GIT_PACKBUILDER__MUTEX_OP(pb, cache_mutex, unlock) #define git_packbuilder__progress_lock(pb) GIT_PACKBUILDER__MUTEX_OP(pb, progress_mutex, lock) #define git_packbuilder__progress_unlock(pb) GIT_PACKBUILDER__MUTEX_OP(pb, progress_mutex, unlock) @@ -175,17 +167,17 @@ return -1; } unsigned int git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n) { - assert(pb); + GIT_ASSERT_ARG(pb); #ifdef GIT_THREADS pb->nr_threads = n; #else GIT_UNUSED(n); - assert(1 == pb->nr_threads); + GIT_ASSERT(pb->nr_threads == 1); #endif return pb->nr_threads; } @@ -209,11 +201,12 @@ { git_pobject *po; size_t newsize; int ret; - assert(pb && oid); + GIT_ASSERT_ARG(pb); + GIT_ASSERT_ARG(oid); /* If the object already exists in the hash table, then we don't * have any work to do */ if (git_oidmap_exists(pb->object_ix, oid)) return 0; @@ -256,11 +249,11 @@ if (pb->progress_cb) { double current_time = git__timer(); double elapsed = current_time - pb->last_progress_report_time; - if (elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) { + if (elapsed < 0 || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) { pb->last_progress_report_time = current_time; ret = pb->progress_cb( GIT_PACKBUILDER_ADDING_OBJECTS, pb->nr_objects, 0, pb->progress_cb_payload); @@ -345,14 +338,13 @@ data_len = git_odb_object_size(obj); type = git_odb_object_type(obj); } /* Write header */ - hdr_len = git_packfile__object_header(hdr, data_len, type); - - if ((error = write_cb(hdr, hdr_len, cb_data)) < 0 || - (error = git_hash_update(&pb->ctx, hdr, hdr_len)) < 0) + if ((error = git_packfile__object_header(&hdr_len, hdr, data_len, type)) < 0 || + (error = write_cb(hdr, hdr_len, cb_data)) < 0 || + (error = git_hash_update(&pb->ctx, hdr, hdr_len)) < 0) goto done; if (type == GIT_OBJECT_REF_DELTA) { if ((error = write_cb(po->delta->id.id, GIT_OID_RAWSZ, cb_data)) < 0 || (error = git_hash_update(&pb->ctx, po->delta->id.id, GIT_OID_RAWSZ)) < 0) @@ -523,17 +515,22 @@ /* TODO: peel objects */ return 0; } -static git_pobject **compute_write_order(git_packbuilder *pb) +static int compute_write_order(git_pobject ***out, git_packbuilder *pb) { size_t i, wo_end, last_untagged; git_pobject **wo; + *out = NULL; + + if (!pb->nr_objects) + return 0; + if ((wo = git__mallocarray(pb->nr_objects, sizeof(*wo))) == NULL) - return NULL; + return -1; for (i = 0; i < pb->nr_objects; i++) { git_pobject *po = pb->object_list + i; po->tagged = 0; po->filled = 0; @@ -558,11 +555,11 @@ /* * Mark objects that are at the tip of tags. */ if (git_tag_foreach(pb->repo, &cb_tag_foreach, pb) < 0) { git__free(wo); - return NULL; + return -1; } /* * Give the objects in the original recency order until * we see a tagged tip. @@ -615,14 +612,15 @@ } if (wo_end != pb->nr_objects) { git__free(wo); git_error_set(GIT_ERROR_INVALID, "invalid write order"); - return NULL; + return -1; } - return wo; + *out = wo; + return 0; } static int write_pack(git_packbuilder *pb, int (*write_cb)(void *buf, size_t size, void *cb_data), void *cb_data) @@ -631,19 +629,19 @@ git_pobject *po; enum write_one_status status; struct git_pack_header ph; git_oid entry_oid; size_t i = 0; - int error = 0; + int error; - write_order = compute_write_order(pb); - if (write_order == NULL) - return -1; + if ((error = compute_write_order(&write_order, pb)) < 0) + return error; if (!git__is_uint32(pb->nr_objects)) { git_error_set(GIT_ERROR_INVALID, "too many objects"); - return -1; + error = -1; + goto done; } /* Write pack header */ ph.hdr_signature = htonl(PACK_SIGNATURE); ph.hdr_version = htonl(PACK_VERSION); @@ -850,33 +848,34 @@ git__free(delta_buf); return 0; } } - git_packbuilder__cache_lock(pb); + GIT_ASSERT(git_packbuilder__cache_lock(pb) == 0); + if (trg_object->delta_data) { git__free(trg_object->delta_data); - assert(pb->delta_cache_size >= trg_object->delta_size); + GIT_ASSERT(pb->delta_cache_size >= trg_object->delta_size); pb->delta_cache_size -= trg_object->delta_size; trg_object->delta_data = NULL; } if (delta_cacheable(pb, src_size, trg_size, delta_size)) { bool overflow = git__add_sizet_overflow( &pb->delta_cache_size, pb->delta_cache_size, delta_size); - git_packbuilder__cache_unlock(pb); + GIT_ASSERT(git_packbuilder__cache_unlock(pb) == 0); if (overflow) { git__free(delta_buf); return -1; } trg_object->delta_data = git__realloc(delta_buf, delta_size); GIT_ERROR_CHECK_ALLOC(trg_object->delta_data); } else { /* create delta when writing the pack */ - git_packbuilder__cache_unlock(pb); + GIT_ASSERT(git_packbuilder__cache_unlock(pb) == 0); git__free(delta_buf); } trg_object->delta = src_object; trg_object->delta_size = delta_size; @@ -927,11 +926,11 @@ if (pb->progress_cb) { double current_time = git__timer(); double elapsed = current_time - pb->last_progress_report_time; - if (force || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) { + if (force || elapsed < 0 || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) { pb->last_progress_report_time = current_time; ret = pb->progress_cb( GIT_PACKBUILDER_DELTAFICATION, count, pb->nr_objects, pb->progress_cb_payload); @@ -960,22 +959,22 @@ for (;;) { struct unpacked *n = array + idx; size_t max_depth, j, best_base = SIZE_MAX; - git_packbuilder__progress_lock(pb); + GIT_ASSERT(git_packbuilder__progress_lock(pb) == 0); if (!*list_size) { - git_packbuilder__progress_unlock(pb); + GIT_ASSERT(git_packbuilder__progress_unlock(pb) == 0); break; } pb->nr_deltified += 1; report_delta_progress(pb, pb->nr_deltified, false); po = *list++; (*list_size)--; - git_packbuilder__progress_unlock(pb); + GIT_ASSERT(git_packbuilder__progress_unlock(pb) == 0); mem_usage -= free_unpacked(n); n->object = po; while (pb->window_memory_limit && @@ -1046,14 +1045,14 @@ memcpy(po->delta_data, zbuf.ptr, zbuf.size); po->z_delta_size = zbuf.size; git_buf_clear(&zbuf); - git_packbuilder__cache_lock(pb); + GIT_ASSERT(git_packbuilder__cache_lock(pb) == 0); pb->delta_cache_size -= po->delta_size; pb->delta_cache_size += po->z_delta_size; - git_packbuilder__cache_unlock(pb); + GIT_ASSERT(git_packbuilder__cache_unlock(pb) == 0); } /* * If we made n a delta, and if n is already at max * depth, leaving it in the window is pointless. we @@ -1127,14 +1126,14 @@ if (find_deltas(me->pb, me->list, &me->remaining, me->window, me->depth) < 0) { ; /* TODO */ } - git_packbuilder__progress_lock(me->pb); + GIT_ASSERT_WITH_RETVAL(git_packbuilder__progress_lock(me->pb) == 0, NULL); me->working = 0; git_cond_signal(&me->pb->progress_cond); - git_packbuilder__progress_unlock(me->pb); + GIT_ASSERT_WITH_RETVAL(git_packbuilder__progress_unlock(me->pb) == 0, NULL); if (git_mutex_lock(&me->mutex)) { git_error_set(GIT_ERROR_THREAD, "unable to lock packfile condition mutex"); return NULL; } @@ -1163,11 +1162,11 @@ struct thread_params *p; size_t i; int ret, active_threads = 0; if (!pb->nr_threads) - pb->nr_threads = git_online_cpus(); + pb->nr_threads = git__online_cpus(); if (pb->nr_threads <= 1) { find_deltas(pb, list, &list_size, window, depth); return 0; } @@ -1235,11 +1234,11 @@ /* Start by locating a thread that has transitioned its * 'working' flag from 1 -> 0. This indicates that it is * ready to receive more work using our work-stealing * algorithm. */ - git_packbuilder__progress_lock(pb); + GIT_ASSERT(git_packbuilder__progress_lock(pb) == 0); for (;;) { for (i = 0; !target && i < pb->nr_threads; i++) if (!p[i].working) target = &p[i]; if (target) @@ -1278,11 +1277,11 @@ victim->remaining -= sub_size; } target->list_size = sub_size; target->remaining = sub_size; target->working = 1; - git_packbuilder__progress_unlock(pb); + GIT_ASSERT(git_packbuilder__progress_unlock(pb) == 0); if (git_mutex_lock(&target->mutex)) { git_error_set(GIT_ERROR_THREAD, "unable to lock packfile condition mutex"); git__free(p); return -1; @@ -1361,12 +1360,17 @@ return write_pack(pb, cb, payload); } int git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb) { + int error; + + if ((error = git_buf_sanitize(buf)) < 0) + return error; + PREPARE_PACK; - git_buf_sanitize(buf); + return write_pack(pb, &write_pack_buf, buf); } static int write_cb(void *buf, size_t len, void *payload) { @@ -1484,11 +1488,12 @@ int git_packbuilder_insert_recur(git_packbuilder *pb, const git_oid *id, const char *name) { git_object *obj; int error; - assert(pb && id); + GIT_ASSERT_ARG(pb); + GIT_ASSERT_ARG(id); if ((error = git_object_lookup(&obj, pb->repo, id, GIT_OBJECT_ANY)) < 0) return error; switch (git_object_type(obj)) { @@ -1725,10 +1730,11 @@ { int error; git_oid id; struct walk_object *obj; - assert(pb && walk); + GIT_ASSERT_ARG(pb); + GIT_ASSERT_ARG(walk); if ((error = mark_edges_uninteresting(pb, walk->user_input)) < 0) return error; /*