Download raw body.
ref_resolve() leak
While I was tracking down a memory leak in ref_resolve(), I did this refactor to plug this leak in `got send`. Currently, got_send_pack() only uses got_pathlist_insert to keep a pathlist without any duplicates. The source of the leak is when a duplicate is to be inserted, got_pathlist_insert returns NULL and the caller leaks it (expecting it to be added to the list). So in order to plug this leak, we could - change the current behavior of the function (which the prototype's comment makes a point that the caller must free the memory) - pro: other function could preform the same leak (this would plug it) - con: a lot of work. - check to see if that path already exists within the pathlist before adding - pro: would prevent duplicates (plugging the leak) - con: we now are adding another linear operation - do the following Creating a new pathlist struct that is in a RB tree (rather than a TAILQ). We can use got_path_cmp() to compare each node in the tree. Since we can't have any duplicates in a RB tree, we don't need to search the tree separate from inserting into the tree. - pro: This plugs the leak. This also makes find_ref() O(log n) rather than O(n) (which may be more important once we get the bitset implementation going). - con: Slight refactor (mainly limited to send.c). Most of this code will be refactored for multi_ack support. Here is adding <sys/tree.h> diff e37a5589c16266235a9b0d3b6d7be7ec67b46390 7ebcb7fd36242f56e8e710155f09534c8da53891 commit - e37a5589c16266235a9b0d3b6d7be7ec67b46390 commit + 7ebcb7fd36242f56e8e710155f09534c8da53891 blob - 7864138db9fadd684f9cc01f99ab36941f60e2fd blob + 715d9e155d7119568bb7a61fe720c7b00036e10a --- cvg/cvg.c +++ cvg/cvg.c @@ -18,6 +18,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> blob - 8a69602e91a117f6b3b1826abfe7737979fbf616 blob + 190d9609f4e45a06227822e1dad228d0d42832a9 --- got/got.c +++ got/got.c @@ -17,6 +17,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> blob - 6678a9dd097384ee9c7b2545f4a1e9211a83054d blob + d415ed2ce1d52ef6268e933be665c9e761c8a75e --- gotadmin/gotadmin.c +++ gotadmin/gotadmin.c @@ -15,6 +15,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <sys/types.h> #include <ctype.h> blob - 31a952259533a6860e070a48fc3dfe2eed787c4f blob + cb4dac46aa51d6df7ed9d3d606dcf5100237e3d1 --- lib/commit_graph.c +++ lib/commit_graph.c @@ -17,6 +17,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/queue.h> +#include <sys/tree.h> #include <sys/stdint.h> #include <limits.h> blob - 11a24fdcbb22ef869c3b17bf02354c6f7a580e97 blob + 5ee4248318a070e5605e27ad3ee7e408896a2ce8 --- lib/deflate.c +++ lib/deflate.c @@ -15,6 +15,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <errno.h> #include <stdio.h> blob - e43d98ae41c70e48398afaded344bc66a394b968 blob + 2c3f8c2ebcd41b76c90f5701a0b1ffc43fbdccc3 --- lib/delta.c +++ lib/delta.c @@ -15,6 +15,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <stdio.h> #include <stdlib.h> blob - 8817fd84008c7497a2a44f44f5111f20ad3414e4 blob + 22b1e2814ecb1475ebeeddd084b4e218534eae7a --- lib/dial.c +++ lib/dial.c @@ -16,6 +16,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/uio.h> blob - 80f4c2ec4a2985d8604998f23f8761ab601b2514 blob + ccd0d097b68c4dab969f27d5080ae06baa8a95f5 --- lib/diff.c +++ lib/diff.c @@ -15,6 +15,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <sys/stat.h> #include <stdio.h> blob - ca1719dd8649b956e27783774efab623fdba7ed8 blob + 8698408e92d2b39903dd77cb9a1b42118eb87457 --- lib/gitproto.c +++ lib/gitproto.c @@ -16,6 +16,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <sys/types.h> #include <ctype.h> blob - e8f06f56c03a04d123c91c39f96c6bc046cb71d9 blob + 49f05411c2efb58063883962301c09d2319d19e6 --- lib/inflate.c +++ lib/inflate.c @@ -15,6 +15,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <errno.h> #include <stdio.h> blob - 0af419be5282778934e8a5369c5793756c35ecd3 blob + 8a796d4d28606f8e51d7207a19b3cb470facba06 --- lib/lockfile.c +++ lib/lockfile.c @@ -16,6 +16,7 @@ #include <sys/stat.h> #include <sys/queue.h> +#include <sys/tree.h> #include <errno.h> #include <fcntl.h> blob - c3f64cf304de14ee32b20d2d42f888f38bec81a0 blob + f9e780471a1fdecb54382af4af19d014f1100932 --- lib/object_create.c +++ lib/object_create.c @@ -17,6 +17,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/queue.h> +#include <sys/tree.h> #include <sys/wait.h> #include <ctype.h> blob - 8dc9adc210203ebedb74801ccf880e731d62df8b blob + ee7a9d71e39a2d65845c1ca018a7ca89d896837c --- lib/pack.c +++ lib/pack.c @@ -17,6 +17,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/queue.h> +#include <sys/tree.h> #include <sys/uio.h> #include <sys/mman.h> #include <sys/resource.h> blob - 199fbf39d0ab1b0f251632eac6e1152e9b8d27ae blob + e59cc910d0450082aba98c17861529c605803415 --- lib/patch.c +++ lib/patch.c @@ -22,6 +22,7 @@ #include <sys/types.h> #include <sys/queue.h> +#include <sys/tree.h> #include <sys/socket.h> #include <sys/stat.h> #include <sys/uio.h> blob - c91ca76066d628e1d12b7c66d86c8829e1b938be blob + edd13390e5e62ccd650fbcb1f02c92a328d766c6 --- lib/path.c +++ lib/path.c @@ -17,6 +17,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <sys/stat.h> #include <errno.h> blob - 25f3858f09dbd0bc936d97fc851892955ecf6623 blob + 5ce52b40ca0e7bb5c7565a9e9c9b02da4cc93f44 --- lib/privsep.c +++ lib/privsep.c @@ -17,6 +17,7 @@ #include <sys/types.h> #include <sys/queue.h> +#include <sys/tree.h> #include <sys/uio.h> #include <sys/wait.h> blob - 3b728f8e2874054c0698accbbe24e51d69d93929 blob + 886584e46d2e919733ce2c305607c36aac37ab3e --- lib/reference.c +++ lib/reference.c @@ -16,6 +16,7 @@ #include <sys/types.h> #include <sys/queue.h> +#include <sys/tree.h> #include <sys/stat.h> #include <errno.h> blob - 1855ba0c1a557ce16cfae9790d6cff44a4b71846 blob + 6ae0f96f5546d6f7eaac0b1b2d32dd6249c51d52 --- lib/worktree_open.c +++ lib/worktree_open.c @@ -16,6 +16,7 @@ #include <sys/stat.h> #include <sys/queue.h> +#include <sys/tree.h> #include <errno.h> #include <fcntl.h> blob - 920b8b12085e70e102a9c9f309d8eb555a2c9671 blob + 798d8f99cf1b256355e11bd85e7f5621ca315d39 --- libexec/got-fetch-http/got-fetch-http.c +++ libexec/got-fetch-http/got-fetch-http.c @@ -17,6 +17,7 @@ #include <sys/types.h> #include <sys/queue.h> +#include <sys/tree.h> #include <sys/socket.h> #include <err.h> blob - 6ec79e85a76b5ba40ce146e249e75e24f79d7df9 blob + 8334b2d07951936cd5692acb122771a2d4e3def6 --- libexec/got-fetch-pack/got-fetch-pack.c +++ libexec/got-fetch-pack/got-fetch-pack.c @@ -16,6 +16,7 @@ #include <sys/types.h> #include <sys/queue.h> +#include <sys/tree.h> #include <sys/uio.h> #include <sys/time.h> #include <sys/stat.h> blob - cc2cd7ee7882f8bf0a997b3e00e36419a15d76fc blob + b5b9532fe425af4eade0b847f25a4f4571c1281d --- libexec/got-index-pack/got-index-pack.c +++ libexec/got-index-pack/got-index-pack.c @@ -17,6 +17,7 @@ #include <sys/types.h> #include <sys/queue.h> +#include <sys/tree.h> #include <sys/mman.h> #include <sys/uio.h> blob - 44ae987193ae5d6ef34fa98f645dd0ab17cb8338 blob + 41c26a054226e82d81c24bfb7d30d580dbdbff30 --- libexec/got-read-gotconfig/got-read-gotconfig.c +++ libexec/got-read-gotconfig/got-read-gotconfig.c @@ -16,6 +16,7 @@ #include <sys/types.h> #include <sys/queue.h> +#include <sys/tree.h> #include <sys/uio.h> #include <sys/time.h> blob - 81b54dbe2110510c5611bd7e3319a1dabea52172 blob + 73d11a53803ce1ba875816666cb3a2c48504044e --- libexec/got-read-pack/got-read-pack.c +++ libexec/got-read-pack/got-read-pack.c @@ -17,6 +17,7 @@ #include <sys/stat.h> #include <sys/types.h> #include <sys/queue.h> +#include <sys/tree.h> #include <sys/uio.h> #include <sys/time.h> #include <sys/mman.h> blob - a9cd911be347a80abbe31861aa07381dcd97ccc0 blob + c7e6d524dcf2e2e98aa97732b125828d04fb2902 --- libexec/got-read-tree/got-read-tree.c +++ libexec/got-read-tree/got-read-tree.c @@ -16,6 +16,7 @@ #include <sys/types.h> #include <sys/queue.h> +#include <sys/tree.h> #include <sys/uio.h> #include <sys/time.h> blob - 2a2c22971801db07832f237f3969bc2e90a0c745 blob + dd4acd7d8447afc51816c47ab97d7a73b6376fc8 --- libexec/got-send-pack/got-send-pack.c +++ libexec/got-send-pack/got-send-pack.c @@ -17,6 +17,7 @@ #include <sys/types.h> #include <sys/queue.h> +#include <sys/tree.h> #include <sys/uio.h> #include <sys/time.h> #include <sys/stat.h> blob - 377ea9cd19e22c07f1348e7110a49defd8cb974d blob + b0b1593dc092b51883cce8fc1caf672b00d56560 --- regress/delta/delta_test.c +++ regress/delta/delta_test.c @@ -15,6 +15,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <stdio.h> #include <stdlib.h> blob - c024c69ae8a0fd18330ae5c8f6dc6b872026966e blob + e3b7eda734c43ae229647e428258d944538ab041 --- regress/fetch/fetch_test.c +++ regress/fetch/fetch_test.c @@ -15,6 +15,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <limits.h> #include <stdarg.h> blob - fad15574f54715f8f62105579fbc58c1ca5d1bf1 blob + bdf8f52499f3ff3ea50a58b637e8f5a56a31305f --- regress/path/path_test.c +++ regress/path/path_test.c @@ -15,6 +15,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <string.h> #include <stdlib.h> blob - baee88c98e9574ccb82d6365b7fe0935c8cc6a72 blob + 61793de291a3f0877e7f339d31ee856892eea43c --- tog/tog.c +++ tog/tog.c @@ -15,6 +15,7 @@ */ #include <sys/queue.h> +#include <sys/tree.h> #include <sys/stat.h> #include <sys/ioctl.h> Here is adding the new struct diff 7ebcb7fd36242f56e8e710155f09534c8da53891 33bf4ee0d21c680d725a921bdb6d67b8993b7eac commit - 7ebcb7fd36242f56e8e710155f09534c8da53891 commit + 33bf4ee0d21c680d725a921bdb6d67b8993b7eac blob - b2bcaa2b7774cab98d41dad2df3c7777d72b0d4b blob + dd20fc4db622694319973777a603d33b85c8de67 --- include/got_path.h +++ include/got_path.h @@ -147,3 +147,41 @@ const struct got_error *got_path_create_file(const cha * (Cross-mount-point moves are not yet implemented.) */ const struct got_error *got_path_move_file(const char *, const char *); + +struct got_pathtree_entry { + RB_ENTRY(got_pathtree_entry) entry; + const char *path; + size_t path_len; + void *data; +}; +int got_pathtree_cmp(const struct got_pathtree_entry * , const struct got_pathtree_entry *); + +RB_HEAD(got_pathtree, got_pathtree_entry); + + + +/* + * Insert a path into the tree of paths. + * The caller should already have initialized the tree head. This tree stores + * the pointer to the path as-is, i.e. the path is not copied internally and + * must remain available until the list is freed with got_pathlist_free(). + * If the first argument is not NULL, set it to a pointer to the newly inserted + * element, or to a NULL pointer in case the path was already on the list. + * If path to be inserted is a duplicate, then the memory of *data is freed. + */ +const struct got_error * +got_pathtree_insert(struct got_pathtree_entry **inserted, + struct got_pathtree *pathtree, const char *path, void *data); + +/* Flags passed to got_pathlist_free() to control which pointers are freed. */ +#define GOT_PATHTREE_FREE_NONE 0 /* pathlist entry only */ +#define GOT_PATHTREE_FREE_PATH (1 << 0) /* entry and path pointer */ +#define GOT_PATHTREE_FREE_DATA (1 << 1) /* entry and data pointer */ +#define GOT_PATHTREE_FREE_ALL (GOT_PATHLIST_FREE_PATH|GOT_PATHLIST_FREE_DATA) + +/* Free resources allocated for a path list. */ +void got_pathtree_free(struct got_pathtree *, int); + + + +RB_PROTOTYPE(got_pathtree, got_pathtree_entry, entry, got_pathtree_cmp); blob - 2a3413d75f8c6428f2b2737381dd72723b06f89a blob + 8fd91ca6f954b52225974d5469c085fb9eda2f4d --- lib/got_lib_privsep.h +++ lib/got_lib_privsep.h @@ -673,6 +673,7 @@ struct got_remote_repo; struct got_pack; struct got_packidx; struct got_pathlist_head; +struct got_pathtree; const struct got_error *got_send_ack(pid_t); const struct got_error *got_privsep_wait_for_child(pid_t); Finally, here is the actual refactor diff 33bf4ee0d21c680d725a921bdb6d67b8993b7eac 00932e0ce0a7f374eab1fa3ea73753d90af99626 commit - 33bf4ee0d21c680d725a921bdb6d67b8993b7eac commit + 00932e0ce0a7f374eab1fa3ea73753d90af99626 blob - 8fd91ca6f954b52225974d5469c085fb9eda2f4d blob + 3ffa8675fda6e72a906a3f706264aa01b0ccdf82 --- lib/got_lib_privsep.h +++ lib/got_lib_privsep.h @@ -715,9 +715,9 @@ const struct got_error *got_privsep_recv_fetch_progres struct got_object_id **, char **, struct got_pathlist_head *, char **, off_t *, uint8_t *, struct imsgbuf *); const struct got_error *got_privsep_send_send_req(struct imsgbuf *, int, - struct got_pathlist_head *, struct got_pathlist_head *, int); + struct got_pathtree *, struct got_pathlist_head *, int); const struct got_error *got_privsep_recv_send_remote_refs( - struct got_pathlist_head *, struct imsgbuf *); + struct got_pathtree *, struct imsgbuf *); const struct got_error *got_privsep_send_packfd(struct imsgbuf *, int); const struct got_error *got_privsep_recv_send_progress(int *, off_t *, int *, char **, char **, struct imsgbuf *); blob - edd13390e5e62ccd650fbcb1f02c92a328d766c6 blob + b1c77c02b38c238932bf9e487508769ffb63de01 --- lib/path.c +++ lib/path.c @@ -38,6 +38,7 @@ #define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b)) #endif + int got_path_is_absolute(const char *path) { @@ -214,7 +215,58 @@ got_path_cmp(const char *path1, const char *path2, siz return (unsigned char)path1[i] < (unsigned char)path2[i] ? -1 : 1; } +int +got_pathtree_cmp(const struct got_pathtree_entry *p1, const struct got_pathtree_entry *p2) +{ + return got_path_cmp(p1->path, p2->path, p1->path_len, p2->path_len); +} + const struct got_error * +got_pathtree_insert(struct got_pathtree_entry **inserted, + struct got_pathtree *pathlist, const char *path, void *data) +{ + struct got_pathtree_entry *new; + size_t path_len = strlen(path); + + if (inserted) + *inserted = NULL; + + new = malloc(sizeof(*new)); + if (new == NULL) + return got_error_from_errno("malloc"); + new->path = path; + new->path_len = path_len; + new->data = data; + if(RB_INSERT(got_pathtree, pathlist, new)){ + free(data); + free(new); + return NULL; + } + if (inserted) + *inserted = new; + return NULL; +} + +void +got_pathtree_free(struct got_pathtree *tree, int freemask) +{ + struct got_pathtree_entry *te, *temp; + RB_FOREACH_SAFE(te, got_pathtree, tree, temp) { + if (freemask & GOT_PATHLIST_FREE_PATH) { + free((char *)te->path); + te->path = NULL; + } + if (freemask & GOT_PATHLIST_FREE_DATA) { + free(te->data); + te->data = NULL; + } + RB_REMOVE(got_pathtree, tree, te); + free(te); + } +} + + +const struct got_error * got_pathlist_insert(struct got_pathlist_entry **inserted, struct got_pathlist_head *pathlist, const char *path, void *data) { @@ -291,6 +343,7 @@ got_pathlist_free(struct got_pathlist_head *pathlist, } } + static const struct got_error * make_parent_dirs(const char *abspath) { @@ -566,3 +619,5 @@ got_path_move_file(const char *oldpath, const char *ne return NULL; } + +RB_GENERATE(got_pathtree, got_pathtree_entry, entry, got_pathtree_cmp); blob - 5ce52b40ca0e7bb5c7565a9e9c9b02da4cc93f44 blob + ac0e9184a9045ed70bf88a6cc4e2dc3e47c8fe05 --- lib/privsep.c +++ lib/privsep.c @@ -885,19 +885,20 @@ send_send_ref(const char *name, size_t name_len, struc const struct got_error * got_privsep_send_send_req(struct imsgbuf *ibuf, int fd, - struct got_pathlist_head *have_refs, + struct got_pathtree *have_refs, struct got_pathlist_head *delete_refs, int verbosity) { const struct got_error *err = NULL; struct got_pathlist_entry *pe; + struct got_pathtree_entry *temp_pe; struct got_imsg_send_request sendreq; struct got_object_id zero_id; memset(&zero_id, 0, sizeof(zero_id)); memset(&sendreq, 0, sizeof(sendreq)); sendreq.verbosity = verbosity; - TAILQ_FOREACH(pe, have_refs, entry) + RB_FOREACH(temp_pe, got_pathtree ,have_refs) sendreq.nrefs++; TAILQ_FOREACH(pe, delete_refs, entry) sendreq.nrefs++; @@ -913,13 +914,13 @@ got_privsep_send_send_req(struct imsgbuf *ibuf, int fd if (err) goto done; - TAILQ_FOREACH(pe, have_refs, entry) { - const char *name = pe->path; - size_t name_len = pe->path_len; - struct got_object_id *id = pe->data; + RB_FOREACH(temp_pe, got_pathtree, have_refs) { + const char *name = temp_pe->path; + size_t name_len = temp_pe->path_len; + struct got_object_id *id = temp_pe->data; err = send_send_ref(name, name_len, id, 0, ibuf); if (err) - goto done; + goto done; } TAILQ_FOREACH(pe, delete_refs, entry) { @@ -936,7 +937,7 @@ done: } const struct got_error * -got_privsep_recv_send_remote_refs(struct got_pathlist_head *remote_refs, +got_privsep_recv_send_remote_refs(struct got_pathtree *remote_refs, struct imsgbuf *ibuf) { const struct got_error *err = NULL; @@ -945,7 +946,7 @@ got_privsep_recv_send_remote_refs(struct got_pathlist_ struct got_imsg_send_remote_ref iremote_ref; struct got_object_id *id = NULL; char *refname = NULL; - struct got_pathlist_entry *new; + struct got_pathtree_entry *new; while (1) { err = got_privsep_recv_imsg(&imsg, ibuf, 0); @@ -976,7 +977,7 @@ got_privsep_recv_send_remote_refs(struct got_pathlist_ err = got_error_from_errno("strndup"); goto done; } - err = got_pathlist_insert(&new, remote_refs, + err = got_pathtree_insert(&new, remote_refs, refname, id); if (err) goto done; blob - 1976fa9212d7b93d58eab0f3844f52e5f8d48f06 blob + fafedac2b346b4f2a79b9207dc0ac32cd8ef69da --- lib/send.c +++ lib/send.c @@ -166,7 +166,7 @@ pack_progress(void *arg, int ncolored, int nfound, int } static const struct got_error * -insert_sendable_ref(struct got_pathlist_head *refs, const char *refname, +insert_sendable_ref(struct got_pathtree *refs, const char *refname, const char *target_refname, struct got_repository *repo) { const struct got_error *err; @@ -200,7 +200,7 @@ insert_sendable_ref(struct got_pathlist_head *refs, co goto done; } - err = got_pathlist_insert(NULL, refs, target_refname, id); + err = got_pathtree_insert(NULL, refs, target_refname, id); done: if (ref) got_ref_close(ref); @@ -258,19 +258,14 @@ realloc_ids(struct got_object_id ***ids, size_t *nallo return NULL; } -static struct got_pathlist_entry * -find_ref(struct got_pathlist_head *refs, const char *refname) +static struct got_pathtree_entry * +find_ref(struct got_pathtree *refs, const char *refname) { - struct got_pathlist_entry *pe; - - TAILQ_FOREACH(pe, refs, entry) { - if (got_path_cmp(pe->path, refname, strlen(pe->path), - strlen(refname)) == 0) { - return pe; - } - } - - return NULL; + struct got_pathtree_entry find; + find.path = refname; + find.path_len = strlen(refname); + return RB_FIND(got_pathtree, refs, &find); + } static const struct got_error * @@ -290,7 +285,7 @@ get_remote_refname(char **remote_refname, const char * } static const struct got_error * -update_remote_ref(struct got_pathlist_entry *my_ref, const char *remote_name, +update_remote_ref(struct got_pathtree_entry *my_ref, const char *remote_name, struct got_repository *repo) { const struct got_error *err, *unlock_err; @@ -346,8 +341,9 @@ got_send_pack(const char *remote_name, struct got_path const struct got_error *err; struct imsgbuf sendibuf; pid_t sendpid = -1; - struct got_pathlist_head have_refs; - struct got_pathlist_head their_refs; + struct got_pathtree their_refs; + struct got_pathtree have_refs; + struct got_pathtree_entry *te = NULL; struct got_pathlist_entry *pe; struct got_object_id **our_ids = NULL; struct got_object_id **their_ids = NULL; @@ -361,8 +357,8 @@ got_send_pack(const char *remote_name, struct got_path FILE *delta_cache = NULL; char *s = NULL; - TAILQ_INIT(&have_refs); - TAILQ_INIT(&their_refs); + RB_INIT(&have_refs); + RB_INIT(&their_refs); if (got_repo_get_object_format(repo) != GOT_HASH_SHA1) return got_error_fmt(GOT_ERR_NOT_IMPL, @@ -394,19 +390,20 @@ got_send_pack(const char *remote_name, struct got_path TAILQ_FOREACH(pe, delete_branches, entry) { const char *branchname = pe->path; - struct got_pathlist_entry *ref; + struct got_pathtree_entry *temp_ref; if (strncmp(branchname, "refs/heads/", 11) != 0) { err = got_error_fmt(GOT_ERR_SEND_DELETE_REF, "%s", branchname); goto done; } - ref = find_ref(&have_refs, branchname); - if (ref) { + temp_ref = find_ref(&have_refs, branchname); + if (temp_ref) { err = got_error_fmt(GOT_ERR_SEND_DELETE_REF, - "changes on %s will be sent to server", - branchname); + "changes on %s will be sent to server", + branchname); goto done; - } + } + } TAILQ_FOREACH(pe, tag_names, entry) { @@ -425,10 +422,11 @@ got_send_pack(const char *remote_name, struct got_path err = insert_sendable_ref(&have_refs, s, s, repo); if (err) goto done; + s = NULL; } - if (TAILQ_EMPTY(&have_refs) && TAILQ_EMPTY(delete_branches)) { + if (RB_EMPTY(&have_refs) && TAILQ_EMPTY(delete_branches)) { err = got_error(GOT_ERR_SEND_EMPTY); goto done; } @@ -474,9 +472,8 @@ got_send_pack(const char *remote_name, struct got_path * Prepare the array of our object IDs which * will be needed for generating a pack file. */ - TAILQ_FOREACH(pe, &have_refs, entry) { - struct got_object_id *id = pe->data; - + RB_FOREACH(te, got_pathtree, &have_refs){ + struct got_object_id *id = te->data; err = realloc_ids(&our_ids, &nalloc_ours, nours + 1); if (err) goto done; @@ -499,12 +496,12 @@ got_send_pack(const char *remote_name, struct got_path * This array will be used to exclude objects which already * exist on the server from our pack file. */ - TAILQ_FOREACH(pe, &their_refs, entry) { - const char *refname = pe->path; - struct got_object_id *their_id = pe->data; + RB_FOREACH(te, got_pathtree, &their_refs) { + const char *refname = te->path; + struct got_object_id *their_id = te->data; int have_their_id; struct got_object *obj; - struct got_pathlist_entry *my_ref = NULL; + struct got_pathtree_entry *my_ref = NULL; int is_tag = 0; /* Don't blindly trust the server to send us valid names. */ @@ -592,8 +589,8 @@ got_send_pack(const char *remote_name, struct got_path } /* Account for any new references we are going to upload. */ - TAILQ_FOREACH(pe, &have_refs, entry) { - const char *refname = pe->path; + RB_FOREACH(te, got_pathtree, &have_refs){ + const char *refname = te->path; if (find_ref(&their_refs, refname) == NULL) refs_to_send++; } @@ -650,15 +647,17 @@ got_send_pack(const char *remote_name, struct got_path } err = got_privsep_recv_send_progress(&done, &bytes_sent, &success, &refname, &errmsg, &sendibuf); - if (err) + if (err) goto done; if (refname && got_ref_name_is_valid(refname) && success && strncmp(refname, "refs/tags/", 10) != 0) { - struct got_pathlist_entry *my_ref; + struct got_pathtree_entry *my_ref; + /* * The server has accepted our changes. * Update our reference in refs/remotes/ accordingly. */ + my_ref = find_ref(&have_refs, refname); if (my_ref) { err = update_remote_ref(my_ref, remote_name, @@ -700,8 +699,9 @@ done: if (npackfd != -1 && close(npackfd) == -1 && err == NULL) err = got_error_from_errno("close"); - got_pathlist_free(&have_refs, GOT_PATHLIST_FREE_ALL); - got_pathlist_free(&their_refs, GOT_PATHLIST_FREE_ALL); + got_pathtree_free(&have_refs, GOT_PATHTREE_FREE_ALL); + got_pathtree_free(&their_refs, GOT_PATHTREE_FREE_ALL); + /* * Object ids are owned by have_refs/their_refs and are already freed; * Only the arrays must be freed. If this is something wanted, I can look for other spots to use this new struct. All regressions have passed on my end. Thoughts/comments/sugguestions?
ref_resolve() leak