Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- blob.c | 11 +++++++++-- commit.c | 12 +++++++++--- list-objects.c | 2 ++ object.c | 9 ++++++++- object.h | 6 ++++++ tag.c | 9 +++++++-- tree.c | 18 ++++++++++++++---- 7 files changed, 55 insertions(+), 12 deletions(-) diff --git a/blob.c b/blob.c index ae320bd..606e2be 100644 --- a/blob.c +++ b/blob.c @@ -6,8 +6,13 @@ const char *blob_type = "blob"; struct blob *lookup_blob(const unsigned char *sha1) { struct object *obj = lookup_object(sha1); - if (!obj) - return create_object(sha1, OBJ_BLOB, alloc_blob_node()); + LOCK(); + if (!obj) { + obj = create_object(sha1, OBJ_BLOB, alloc_blob_node()); + UNLOCK(); + return obj; + } + UNLOCK(); if (!obj->type) obj->type = OBJ_BLOB; if (obj->type != OBJ_BLOB) { @@ -20,6 +25,8 @@ struct blob *lookup_blob(const unsigned char *sha1) int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size) { + LOCK(); item->object.parsed = 1; + UNLOCK(); return 0; } diff --git a/commit.c b/commit.c index 4b39c19..f84152c 100644 --- a/commit.c +++ b/commit.c @@ -54,9 +54,15 @@ struct commit *lookup_commit_or_die(const unsigned char *sha1, const char *ref_n struct commit *lookup_commit(const unsigned char *sha1) { - struct object *obj = lookup_object(sha1); - if (!obj) - return create_object(sha1, OBJ_COMMIT, alloc_commit_node()); + struct object *obj; + LOCK(); + obj = lookup_object(sha1); + if (!obj) { + obj = create_object(sha1, OBJ_COMMIT, alloc_commit_node()); + UNLOCK(); + return (struct commit*)obj; + } + UNLOCK(); if (!obj->type) obj->type = OBJ_COMMIT; return check_commit(obj, sha1, 0); diff --git a/list-objects.c b/list-objects.c index 3dd4a96..2605b63 100644 --- a/list-objects.c +++ b/list-objects.c @@ -123,8 +123,10 @@ static void process_tree(struct rev_info *revs, cb_data); } strbuf_setlen(base, baselen); + LOCK(); free(tree->buffer); tree->buffer = NULL; + UNLOCK(); } static void mark_edge_parents_uninteresting(struct commit *commit, diff --git a/object.c b/object.c index 6b06297..05fb91f 100644 --- a/object.c +++ b/object.c @@ -8,6 +8,9 @@ static struct object **obj_hash; static int nr_objs, obj_hash_size; +int multithread_object_access; +pthread_mutex_t mtx; + unsigned int get_max_object_index(void) { return obj_hash_size; @@ -126,9 +129,13 @@ void *create_object(const unsigned char *sha1, int type, void *o) struct object *lookup_unknown_object(const unsigned char *sha1) { - struct object *obj = lookup_object(sha1); + struct object *obj; + + LOCK(); + obj = lookup_object(sha1); if (!obj) obj = create_object(sha1, OBJ_NONE, alloc_object_node()); + UNLOCK(); return obj; } diff --git a/object.h b/object.h index b6618d9..17c7c65 100644 --- a/object.h +++ b/object.h @@ -32,6 +32,12 @@ struct object { unsigned char sha1[20]; }; +extern int multithread_object_access; +extern pthread_mutex_t mtx; + +#define LOCK() { if (multithread_object_access) pthread_mutex_lock(&mtx); } +#define UNLOCK() { if (multithread_object_access) pthread_mutex_unlock(&mtx); } + extern const char *typename(unsigned int type); extern int type_from_string(const char *str); diff --git a/tag.c b/tag.c index 78d272b..4f16c5b 100644 --- a/tag.c +++ b/tag.c @@ -39,8 +39,13 @@ struct object *deref_tag_noverify(struct object *o) struct tag *lookup_tag(const unsigned char *sha1) { struct object *obj = lookup_object(sha1); - if (!obj) - return create_object(sha1, OBJ_TAG, alloc_tag_node()); + LOCK(); + if (!obj) { + obj = create_object(sha1, OBJ_TAG, alloc_tag_node()); + UNLOCK(); + return obj; + } + UNLOCK(); if (!obj->type) obj->type = OBJ_TAG; if (obj->type != OBJ_TAG) { diff --git a/tree.c b/tree.c index 676e9f7..6d3c6a2 100644 --- a/tree.c +++ b/tree.c @@ -180,9 +180,15 @@ int read_tree(struct tree *tree, int stage, struct pathspec *match) struct tree *lookup_tree(const unsigned char *sha1) { - struct object *obj = lookup_object(sha1); - if (!obj) - return create_object(sha1, OBJ_TREE, alloc_tree_node()); + struct object *obj; + LOCK(); + obj = lookup_object(sha1); + if (!obj) { + obj = create_object(sha1, OBJ_TREE, alloc_tree_node()); + UNLOCK(); + return obj; + } + UNLOCK(); if (!obj->type) obj->type = OBJ_TREE; if (obj->type != OBJ_TREE) { @@ -195,11 +201,15 @@ struct tree *lookup_tree(const unsigned char *sha1) int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size) { - if (item->object.parsed) + LOCK(); + if (item->object.parsed) { + UNLOCK(); return 0; + } item->object.parsed = 1; item->buffer = buffer; item->size = size; + UNLOCK(); return 0; } -- 1.7.8.36.g69ee2 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html