@@ -6,7 +6,6 @@ use std::{
66 os:: raw:: { c_char, c_void} ,
77 path:: Path ,
88 ptr,
9- sync:: Mutex ,
109} ;
1110
1211use rb_sys:: {
@@ -17,6 +16,7 @@ use rb_sys::{
1716 rb_tracearg_event_flag, rb_tracearg_lineno, rb_tracearg_path,
1817 rb_cObject, VALUE , ID , RUBY_EVENT_LINE ,
1918 RSTRING_PTR , RSTRING_LEN ,
19+ rb_raise, rb_eIOError,
2020} ;
2121use runtime_tracing:: { Tracer , Line } ;
2222
@@ -56,7 +56,7 @@ extern "C" {
5656}
5757
5858struct Recorder {
59- tracer : Mutex < Tracer > ,
59+ tracer : Tracer ,
6060 active : bool ,
6161}
6262
@@ -86,16 +86,11 @@ unsafe fn get_recorder(obj: VALUE) -> *mut Recorder {
8686}
8787
8888unsafe extern "C" fn ruby_recorder_alloc ( klass : VALUE ) -> VALUE {
89- let recorder = Box :: new ( Recorder { tracer : Mutex :: new ( Tracer :: new ( "ruby" , & vec ! [ ] ) ) , active : false } ) ;
89+ let recorder = Box :: new ( Recorder { tracer : Tracer :: new ( "ruby" , & vec ! [ ] ) , active : false } ) ;
9090 let ty = std:: ptr:: addr_of!( RECORDER_TYPE ) as * const rb_data_type_t ;
9191 rb_data_typed_object_wrap ( klass, Box :: into_raw ( recorder) as * mut c_void , ty)
9292}
9393
94- unsafe extern "C" fn ruby_recorder_initialize ( _self : VALUE ) -> VALUE {
95- // nothing special for now
96- rb_sys:: Qnil . into ( )
97- }
98-
9994unsafe extern "C" fn enable_tracing ( self_val : VALUE ) -> VALUE {
10095 let recorder = & mut * get_recorder ( self_val) ;
10196 if !recorder. active {
@@ -118,14 +113,15 @@ unsafe extern "C" fn disable_tracing(self_val: VALUE) -> VALUE {
118113 rb_sys:: Qnil . into ( )
119114}
120115
121- fn flush_to_dir ( tracer : & Tracer , dir : & Path ) {
122- let _ = std:: fs:: create_dir_all ( dir) ;
116+ fn flush_to_dir ( tracer : & Tracer , dir : & Path ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
117+ std:: fs:: create_dir_all ( dir) ? ;
123118 let events = dir. join ( "trace.json" ) ;
124119 let metadata = dir. join ( "trace_metadata.json" ) ;
125120 let paths = dir. join ( "trace_paths.json" ) ;
126- let _ = tracer. store_trace_events ( & events) ;
127- let _ = tracer. store_trace_metadata ( & metadata) ;
128- let _ = tracer. store_trace_paths ( & paths) ;
121+ tracer. store_trace_events ( & events) ?;
122+ tracer. store_trace_metadata ( & metadata) ?;
123+ tracer. store_trace_paths ( & paths) ?;
124+ Ok ( ( ) )
129125}
130126
131127unsafe extern "C" fn flush_trace ( self_val : VALUE , out_dir : VALUE ) -> VALUE {
@@ -134,14 +130,16 @@ unsafe extern "C" fn flush_trace(self_val: VALUE, out_dir: VALUE) -> VALUE {
134130 let ptr = RSTRING_PTR ( out_dir) as * const u8 ;
135131 let len = RSTRING_LEN ( out_dir) as usize ;
136132 let slice = std:: slice:: from_raw_parts ( ptr, len) ;
137- if let Ok ( path_str) = std:: str:: from_utf8 ( slice) {
138- if let Ok ( t) = recorder. tracer . lock ( ) {
139- flush_to_dir ( & t, Path :: new ( path_str) ) ;
133+
134+ match std:: str:: from_utf8 ( slice) {
135+ Ok ( path_str) => {
136+ if let Err ( e) = flush_to_dir ( & recorder. tracer , Path :: new ( path_str) ) {
137+ rb_raise ( rb_eIOError, b"Failed to flush trace: %s\0 " . as_ptr ( ) as * const c_char , e. to_string ( ) . as_ptr ( ) as * const c_char ) ;
138+ }
140139 }
140+ Err ( e) => rb_raise ( rb_eIOError, b"Invalid UTF-8 in path: %s\0 " . as_ptr ( ) as * const c_char , e. to_string ( ) . as_ptr ( ) as * const c_char ) ,
141141 }
142- drop ( Box :: from_raw ( recorder_ptr) ) ;
143- let rdata = self_val as * mut RTypedData ;
144- ( * rdata) . data = ptr:: null_mut ( ) ;
142+
145143 rb_sys:: Qnil . into ( )
146144}
147145
@@ -172,9 +170,7 @@ unsafe extern "C" fn event_hook_raw(data: VALUE, arg: *mut rb_trace_arg_t) {
172170
173171 if !path_ptr. is_null ( ) {
174172 if let Ok ( path) = CStr :: from_ptr ( path_ptr) . to_str ( ) {
175- if let Ok ( mut t) = recorder. tracer . lock ( ) {
176- t. register_step ( Path :: new ( path) , Line ( line) ) ;
177- }
173+ recorder. tracer . register_step ( Path :: new ( path) , Line ( line) ) ;
178174 }
179175 }
180176}
@@ -184,11 +180,9 @@ pub extern "C" fn Init_codetracer_ruby_recorder() {
184180 unsafe {
185181 let class = rb_define_class ( b"RubyRecorder\0 " . as_ptr ( ) as * const c_char , rb_cObject) ;
186182 rb_define_alloc_func ( class, Some ( ruby_recorder_alloc) ) ;
187- let init_cb: unsafe extern "C" fn ( VALUE ) -> VALUE = ruby_recorder_initialize;
188183 let enable_cb: unsafe extern "C" fn ( VALUE ) -> VALUE = enable_tracing;
189184 let disable_cb: unsafe extern "C" fn ( VALUE ) -> VALUE = disable_tracing;
190185 let flush_cb: unsafe extern "C" fn ( VALUE , VALUE ) -> VALUE = flush_trace;
191- rb_define_method ( class, b"initialize\0 " . as_ptr ( ) as * const c_char , Some ( transmute ( init_cb) ) , 0 ) ;
192186 rb_define_method ( class, b"enable_tracing\0 " . as_ptr ( ) as * const c_char , Some ( transmute ( enable_cb) ) , 0 ) ;
193187 rb_define_method ( class, b"disable_tracing\0 " . as_ptr ( ) as * const c_char , Some ( transmute ( disable_cb) ) , 0 ) ;
194188 rb_define_method ( class, b"flush_trace\0 " . as_ptr ( ) as * const c_char , Some ( transmute ( flush_cb) ) , 1 ) ;
0 commit comments