Issue #13486 has been updated by ko1 (Koichi Sasada).


I'm not sure what is the problem on your situation, but you can't call `rb_thread_wait_for` when you don't holding GVL.
Basically, you can't use any of `rb_...` APIs because they depend on GVL.

BTW, I'm not sure why you are using Ruby thread for a compilation thread.
You can ignore all of Ruby mechanism.

Thanks,
Koichi


----------------------------------------
Misc #13486: Using rb_thread_call_without_gvl{2}
https://bugs.ruby-lang.org/issues/13486#change-64394

* Author: magaudet (Matthew Gaudet)
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
I'm currently working on adding asynchronous compilation to [Ruby+OMR][1], and I'm trying to use the existing Ruby thread API. However, given that compilation shouldn't happen while holding the GVL, I've been playing with `rb_thread_call_without_gvl{2}`. I've encountered something I don't entirely understand however. It appears that if the unblocking function for a thread is actually invoked, the interpreter hangs on shutdown. 

With some tracing code elided, it's a pretty simple bit of code: 

```
static int compilation_thread_started = 0;
void unblock_compilation_thread(void* arg) {                                                          
   *(int*)arg  = 0; // interrupt compilation thread.                                                  
}                                                                                                     
                                                                                                      
void* vm_compile_thread(void *vm) {                                                                   
   while (compilation_thread_started) { // compile until interupted.
         rb_thread_wait_for(rb_time_interval(DBL2NUM(0.01))); // pretend to compile by sleeping.
   }                                                                                                  
   return NULL;                                                                                       
}                                                                                                     

VALUE releaseGVLandStartCompilationThread(rb_vm_t* vm)                                                
   {                                                                                                  
   compilation_thread_started = 1;                                                                    
   rb_thread_call_without_gvl2(vm_compile_thread,             /* func */ 
                               (void*)vm,                     /* func arg */                          
                               unblock_compilation_thread,    /* unblock func */
                               &compilation_thread_started);  /* unblock arg */
      
   return Qnil; 
   }
   
void                                                                                                  
kickoff_thread(rb_vm_t* vm)                                                                           
{
   typedef VALUE (*thread_function)(ANYARGS);                                                         
   rb_thread_create((thread_function)(releaseGVLandStartCompilationThread),vm);                       
}
```

I've attached a patch with a very simple reproducing test case that should apply to trunk as of today. If you run it, what you'll notice is that the unblock function runs, the thread code exits and then the interpreter hangs; in an interpreter, what I see is the spawned thread that released the GVL is waiting to re-aquire, but it appears to be held. The main thread on the other hand, is waiting for the final non-main thread to shut down before proceeding with shutdown. 

I've marked this as Misc, because I'm not entirely sure this isn't user error, but I'd love some guidance on how to spawn a thread that's not holding the GVL, but also have it participate in cleanup actions like regular threads. 



[1]: https://github.com/rubyomr-preview/ruby/issues/30 

---Files--------------------------------
gvl_thread_error.patch (3.29 KB)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>