@@ -105,7 +105,7 @@ static gvl_hook_t * rb_gvl_hooks = NULL;
105105static  pthread_rwlock_t  rb_gvl_hooks_rw_lock  =  PTHREAD_RWLOCK_INITIALIZER ;
106106
107107gvl_hook_t  * 
108- rb_gvl_event_new (void  * callback , uint32_t  event ) {
108+ rb_gvl_event_new (void  * callback , rb_event_flag_t  event ) {
109109    gvl_hook_t  * hook  =  ALLOC_N (gvl_hook_t , 1 );
110110    hook -> callback  =  callback ;
111111    hook -> event  =  event ;
@@ -155,25 +155,21 @@ rb_gvl_event_delete(gvl_hook_t * hook) {
155155}
156156
157157void 
158- rb_gvl_execute_hooks (uint32_t  event ) {
159-     if  (!rb_gvl_hooks ) {
160-         return ;
161-     }
162- 
158+ rb_gvl_execute_hooks (rb_event_flag_t  event , unsigned long  waiting ) {
163159    if  (pthread_rwlock_rdlock (& rb_gvl_hooks_rw_lock )) {
164160        // TODO: better way to deal with error? 
165161        return ;
166162    }
167163
168-     gvl_hook_t   * h   =   rb_gvl_hooks ; 
169-     struct   gvl_hook_event_args   args   =  {} ;
170- 
171-     do  {
172-         if  (h -> event  &  event ) {
173-             (* h -> callback )(event , args );
174-         }
175-     } while ((h  =  h -> next ));
176- 
164+     if  ( rb_gvl_hooks ) { 
165+          gvl_hook_t   * h   =   rb_gvl_hooks ;
166+          gvl_hook_event_args_t   args   =  { . waiting   =   waiting  }; 
167+          do  {
168+              if  (h -> event  &  event ) {
169+                  (* h -> callback )(event , args );
170+              }
171+          } while ((h  =  h -> next ));
172+     } 
177173    pthread_rwlock_unlock (& rb_gvl_hooks_rw_lock );
178174}
179175
@@ -366,6 +362,10 @@ gvl_acquire_common(rb_global_vm_lock_t *gvl, rb_thread_t *th)
366362	          "we must not be in ubf_list and GVL waitq at the same time" );
367363
368364        list_add_tail (& gvl -> waitq , & nd -> node .gvl );
365+         gvl -> waiting ++ ;
366+         if  (rb_gvl_hooks ) {
367+             rb_gvl_execute_hooks (RUBY_INTERNAL_EVENT_GVL_ACQUIRE_ENTER , gvl -> waiting );
368+         }
369369
370370        do  {
371371            if  (!gvl -> timer ) {
@@ -377,6 +377,7 @@ gvl_acquire_common(rb_global_vm_lock_t *gvl, rb_thread_t *th)
377377        } while  (gvl -> owner );
378378
379379        list_del_init (& nd -> node .gvl );
380+         gvl -> waiting -- ;
380381
381382        if  (gvl -> need_yield ) {
382383            gvl -> need_yield  =  0 ;
@@ -387,6 +388,11 @@ gvl_acquire_common(rb_global_vm_lock_t *gvl, rb_thread_t *th)
387388        gvl -> timer_err  =  ETIMEDOUT ;
388389    }
389390    gvl -> owner  =  th ;
391+ 
392+     if  (rb_gvl_hooks ) {
393+         rb_gvl_execute_hooks (RUBY_INTERNAL_EVENT_GVL_ACQUIRE_EXIT , gvl -> waiting );
394+     }
395+ 
390396    if  (!gvl -> timer ) {
391397        if  (!designate_timer_thread (gvl ) &&  !ubf_threads_empty ()) {
392398            rb_thread_wakeup_timer_thread (-1 );
@@ -405,6 +411,10 @@ gvl_acquire(rb_global_vm_lock_t *gvl, rb_thread_t *th)
405411static  const  native_thread_data_t  * 
406412gvl_release_common (rb_global_vm_lock_t  * gvl )
407413{
414+     if  (rb_gvl_hooks ) {
415+         rb_gvl_execute_hooks (RUBY_INTERNAL_EVENT_GVL_RELEASE , gvl -> waiting );
416+     }
417+ 
408418    native_thread_data_t  * next ;
409419    gvl -> owner  =  0 ;
410420    next  =  list_top (& gvl -> waitq , native_thread_data_t , node .ubf );
@@ -466,6 +476,7 @@ rb_gvl_init(rb_global_vm_lock_t *gvl)
466476    rb_native_cond_initialize (& gvl -> switch_wait_cond );
467477    list_head_init (& gvl -> waitq );
468478    gvl -> owner  =  0 ;
479+     gvl -> waiting  =  0 ;
469480    gvl -> timer  =  0 ;
470481    gvl -> timer_err  =  ETIMEDOUT ;
471482    gvl -> need_yield  =  0 ;
0 commit comments