@@ -77,6 +77,14 @@ namespace Rice::detail {
7777 };
7878} // namespace Rice::detail
7979
80+ void with_gvl (std::function<void ()> f) {
81+ auto ruby_wrapper = [](void * arg) -> void * {
82+ (*static_cast <decltype (f)*>(arg))();
83+ return nullptr ;
84+ };
85+ rb_thread_call_with_gvl (ruby_wrapper, &f);
86+ }
87+
8088void init_constraint (Rice::Module& m) {
8189 Rice::define_class_under<Domain>(m, " Domain" )
8290 .define_constructor (Rice::Constructor<Domain, int64_t , int64_t >())
@@ -439,9 +447,8 @@ void init_constraint(Rice::Module& m) {
439447 Rice::Object ruby_thread;
440448 std::optional<Rice::Exception> exception;
441449
442- // TODO release GVL when not calling Ruby
443450 auto ruby_observer = [&]() {
444- try {
451+ return Rice::detail::no_gvl ([&]() {
445452 while (true ) {
446453 if (done.load ()) {
447454 std::lock_guard<std::mutex> guard (mutex);
@@ -463,28 +470,29 @@ void init_constraint(Rice::Module& m) {
463470 }
464471
465472 bool stop = false ;
466- try {
467- callback.call (" response=" , r);
468- callback.call (" on_solution_callback" );
469- stop = static_cast <bool >(callback.attr_get (" @stopped" ));
470- } catch (const Rice::Exception& e) {
471- exception = e;
472- stop = true ;
473- }
473+ with_gvl ([&]() {
474+ try {
475+ callback.call (" response=" , r);
476+ callback.call (" on_solution_callback" );
477+ stop = static_cast <bool >(callback.attr_get (" @stopped" ));
478+ } catch (const Rice::Exception& e) {
479+ exception = e;
480+ stop = true ;
481+ }
482+ });
474483
475484 if (stop) {
476485 StopSearch (&m);
477486 return Qnil;
478487 }
479488 }
480489
481- Rice::detail::protect (rb_thread_schedule);
490+ with_gvl ([]() {
491+ Rice::detail::protect (rb_thread_schedule);
492+ });
482493 }
483- } catch (const std::exception& e) {
484- exception = Rice::Exception (rb_eRuntimeError, e.what ());
485- StopSearch (&m);
486- }
487- return Qnil;
494+ return Qnil;
495+ });
488496 };
489497
490498 auto ruby_wrapper = [](void * arg) {
0 commit comments