Skip to content

Commit 70bcbb3

Browse files
committed
Unlock GVL around git_diff_tree_to_tree
This lets us execute Ruby code in parallel while making diffs.
1 parent f21d82c commit 70bcbb3

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

ext/rugged/rugged_tree.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424

2525
#include "rugged.h"
26+
#include <ruby/thread.h>
2627

2728
extern VALUE rb_mRugged;
2829
extern VALUE rb_cRuggedObject;
@@ -380,13 +381,31 @@ static VALUE rb_git_diff_tree_to_index(VALUE self, VALUE rb_repo, VALUE rb_self,
380381
return rugged_diff_new(rb_cRuggedDiff, rb_repo, diff);
381382
}
382383

384+
struct nogvl_diff_args {
385+
git_repository * repo;
386+
git_tree * tree;
387+
git_tree * other_tree;
388+
git_diff_options * opts;
389+
int error;
390+
};
391+
392+
static void * rb_git_diff_tree_to_tree_nogvl(void * _args)
393+
{
394+
struct nogvl_diff_args * args;
395+
git_diff *diff = NULL;
396+
397+
args = (struct nogvl_diff_args *)_args;
398+
args->error = git_diff_tree_to_tree(&diff, args->repo, args->tree, args->other_tree, args->opts);
399+
return diff;
400+
}
401+
383402
static VALUE rb_git_diff_tree_to_tree(VALUE self, VALUE rb_repo, VALUE rb_tree, VALUE rb_other_tree, VALUE rb_options) {
384403
git_tree *tree = NULL;
385404
git_tree *other_tree = NULL;
386405
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
387406
git_repository *repo = NULL;
388407
git_diff *diff = NULL;
389-
int error;
408+
struct nogvl_diff_args args;
390409

391410
Data_Get_Struct(rb_repo, git_repository, repo);
392411
Data_Get_Struct(rb_tree, git_tree, tree);
@@ -396,10 +415,15 @@ static VALUE rb_git_diff_tree_to_tree(VALUE self, VALUE rb_repo, VALUE rb_tree,
396415

397416
rugged_parse_diff_options(&opts, rb_options);
398417

399-
error = git_diff_tree_to_tree(&diff, repo, tree, other_tree, &opts);
418+
args.repo = repo;
419+
args.tree = tree;
420+
args.other_tree = other_tree;
421+
args.opts = &opts;
422+
423+
diff = rb_thread_call_without_gvl(rb_git_diff_tree_to_tree_nogvl, &args, RUBY_UBF_PROCESS, NULL);
400424

401425
xfree(opts.pathspec.strings);
402-
rugged_exception_check(error);
426+
rugged_exception_check(args.error);
403427

404428
return rugged_diff_new(rb_cRuggedDiff, rb_repo, diff);
405429
}

0 commit comments

Comments
 (0)