@@ -12,6 +12,7 @@ use std::{
1212} ;
1313
1414use rb_sys:: {
15+ rb_eval_string,
1516 rb_add_event_hook2, rb_cObject, rb_cRange, rb_cRegexp, rb_cStruct, rb_cThread, rb_cTime,
1617 rb_check_typeddata, rb_const_defined, rb_const_get, rb_data_type_struct__bindgen_ty_1,
1718 rb_data_type_t, rb_data_typed_object_wrap, rb_define_alloc_func, rb_define_class,
@@ -88,6 +89,7 @@ struct RecorderData {
8889 active : bool ,
8990 in_event_hook : bool ,
9091 thread_event_hook_installed : bool ,
92+ last_thread_id : Option < u64 > ,
9193 id : InternedSymbols ,
9294 set_class : VALUE ,
9395 open_struct_class : VALUE ,
@@ -223,6 +225,7 @@ unsafe extern "C" fn ruby_recorder_alloc(klass: VALUE) -> VALUE {
223225 active : false ,
224226 in_event_hook : false ,
225227 thread_event_hook_installed : false ,
228+ last_thread_id : None ,
226229 id : InternedSymbols :: new ( ) ,
227230 set_class : Qnil . into ( ) ,
228231 open_struct_class : Qnil . into ( ) ,
@@ -802,6 +805,19 @@ unsafe extern "C" fn event_hook_raw(data: VALUE, arg: *mut rb_trace_arg_t) {
802805 return ;
803806 }
804807
808+ let thread_id: u64 = rb_eval_string ( c"Thread.current" . as_ptr ( ) as * const c_char ) . try_into ( ) . unwrap ( ) ;
809+ let thread_changed = if let Some ( last_thread_id) = recorder. data . last_thread_id {
810+ last_thread_id != thread_id
811+ } else {
812+ true
813+ } ;
814+ if thread_changed {
815+ TraceWriter :: add_event (
816+ & mut * * locked_tracer,
817+ TraceLowLevelEvent :: ThreadSwitch ( ThreadId ( thread_id) ) ) ;
818+ recorder. data . last_thread_id = Some ( thread_id) ;
819+ }
820+
805821 if ( ev & RUBY_EVENT_LINE ) != 0 {
806822 let binding = rb_tracearg_binding ( arg) ;
807823 TraceWriter :: register_step ( & mut * * locked_tracer, Path :: new ( & path) , Line ( line) ) ;
0 commit comments