11// Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/
22// SPDX-License-Identifier: Apache-2.0
33
4- use super :: datatypes:: {
5- ddog_prof_EncodedProfile_drop, Period , ProfileResult , SampleType , SerializeResult ,
6- } ;
4+ use super :: datatypes:: { Period , ProfileResult , SampleType , SerializeResult } ;
75use crate :: arc_handle:: ArcHandle ;
86use anyhow:: Context ;
97use function_name:: named;
108use libdd_common_ffi:: slice:: { AsBytes , CharSlice , Slice } ;
11- use libdd_common_ffi:: { wrap_with_ffi_result, Error , Result , Timespec } ;
9+ use libdd_common_ffi:: { wrap_with_ffi_result, Handle , Result , Timespec , ToInner } ;
1210use libdd_profiling:: dynamic:: {
1311 DynamicFunction as InnerDynamicFunction , DynamicFunctionIndex as InnerDynamicFunctionIndex ,
14- DynamicLabel as InnerDynamicLabel , DynamicLocation as InnerDynamicLocation ,
15- DynamicProfile as InnerDynamicProfile ,
16- DynamicProfilesDictionary as InnerDynamicProfilesDictionary ,
17- DynamicSample as InnerDynamicSample , DynamicStackTraceIndex as InnerDynamicStackTraceIndex ,
12+ DynamicLabel as InnerDynamicLabel , DynamicLocation as InnerDynamicLocation , DynamicProfile ,
13+ DynamicProfilesDictionary , DynamicSample as InnerDynamicSample ,
14+ DynamicStackTraceIndex as InnerDynamicStackTraceIndex ,
1815 DynamicStringIndex as InnerDynamicStringIndex ,
1916} ;
2017use std:: str;
2118use std:: time:: Duration ;
2219
23- /// Represents a dynamic profile. Do not access its member directly.
24- #[ repr( C ) ]
25- pub struct DynamicProfile {
26- inner : * mut InnerDynamicProfile ,
27- }
28-
29- impl DynamicProfile {
30- fn new ( profile : InnerDynamicProfile ) -> Self {
31- Self {
32- inner : Box :: into_raw ( Box :: new ( profile) ) ,
33- }
34- }
35-
36- fn take ( & mut self ) -> Option < Box < InnerDynamicProfile > > {
37- let raw = std:: mem:: replace ( & mut self . inner , std:: ptr:: null_mut ( ) ) ;
38- if raw. is_null ( ) {
39- None
40- } else {
41- Some ( unsafe { Box :: from_raw ( raw) } )
42- }
43- }
44- }
45-
46- impl Drop for DynamicProfile {
47- fn drop ( & mut self ) {
48- drop ( self . take ( ) )
49- }
50- }
51-
52- #[ allow( dead_code) ]
53- #[ repr( C ) ]
54- pub enum DynamicProfileNewResult {
55- Ok ( DynamicProfile ) ,
56- Err ( Error ) ,
57- }
58-
5920#[ repr( C ) ]
6021#[ derive( Copy , Clone , Debug , Default , Eq , PartialEq , Hash , Ord , PartialOrd ) ]
6122pub struct DynamicStringIndex {
@@ -166,28 +127,13 @@ pub struct DynamicSample<'a> {
166127 pub labels : Slice < ' a , DynamicLabel < ' a > > ,
167128}
168129
169- #[ cfg( test) ]
170- impl From < DynamicProfileNewResult > for std:: result:: Result < DynamicProfile , Error > {
171- fn from ( value : DynamicProfileNewResult ) -> Self {
172- match value {
173- DynamicProfileNewResult :: Ok ( profile) => Ok ( profile) ,
174- DynamicProfileNewResult :: Err ( err) => Err ( err) ,
175- }
176- }
177- }
178-
179130unsafe fn dynamic_profile_ptr_to_inner < ' a > (
180- profile_ptr : * mut DynamicProfile ,
181- ) -> anyhow:: Result < & ' a mut InnerDynamicProfile > {
182- match profile_ptr. as_mut ( ) {
183- None => anyhow:: bail!( "dynamic profile pointer was null" ) ,
184- Some ( inner_ptr) => match inner_ptr. inner . as_mut ( ) {
185- Some ( profile) => Ok ( profile) ,
186- None => {
187- anyhow:: bail!( "dynamic profile inner pointer was null (indicates use-after-free)" )
188- }
189- } ,
190- }
131+ profile_ptr : * mut Handle < DynamicProfile > ,
132+ ) -> anyhow:: Result < & ' a mut DynamicProfile > {
133+ profile_ptr
134+ . as_mut ( )
135+ . context ( "dynamic profile handle pointer was null" ) ?
136+ . to_inner_mut ( )
191137}
192138
193139fn ffi_labels_to_inner < ' a > (
@@ -220,8 +166,8 @@ fn ffi_sample_to_parts<'a>(
220166#[ must_use]
221167#[ no_mangle]
222168pub unsafe extern "C" fn ddog_prof_DynamicProfile_with_dictionary (
223- out : * mut DynamicProfile ,
224- dict : & ArcHandle < InnerDynamicProfilesDictionary > ,
169+ out : * mut Handle < DynamicProfile > ,
170+ dict : & ArcHandle < DynamicProfilesDictionary > ,
225171 sample_types : Slice < SampleType > ,
226172 period : Option < & Period > ,
227173 start_time : Option < & Timespec > ,
@@ -237,33 +183,30 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_with_dictionary(
237183}
238184
239185unsafe fn dynamic_profile_with_dictionary (
240- dict : & ArcHandle < InnerDynamicProfilesDictionary > ,
186+ dict : & ArcHandle < DynamicProfilesDictionary > ,
241187 sample_types : Slice < SampleType > ,
242188 period : Option < & Period > ,
243189 start_time : Option < & Timespec > ,
244- ) -> std:: result:: Result < DynamicProfile , crate :: ProfileError > {
190+ ) -> std:: result:: Result < Handle < DynamicProfile > , crate :: ProfileError > {
245191 let sample_types = sample_types. try_as_slice ( ) ?;
246192 let period = period. copied ( ) ;
247193 let start_time = start_time. map ( Into :: into) ;
248194 let dict = dict. try_clone_into_arc ( ) ?;
249- let profile =
250- InnerDynamicProfile :: try_new_with_dictionary ( sample_types, period, start_time, dict)
251- . map_err ( crate :: ProfileError :: from_display) ?;
252- Ok ( DynamicProfile :: new ( profile) )
195+ let profile = DynamicProfile :: try_new_with_dictionary ( sample_types, period, start_time, dict)
196+ . map_err ( crate :: ProfileError :: from_display) ?;
197+ Ok ( Handle :: from ( profile) )
253198}
254199
255200#[ no_mangle]
256- pub unsafe extern "C" fn ddog_prof_DynamicProfile_drop ( profile : * mut DynamicProfile ) {
257- if !profile. is_null ( ) {
258- drop ( ( * profile) . take ( ) )
259- }
201+ pub unsafe extern "C" fn ddog_prof_DynamicProfile_drop ( mut profile : * mut Handle < DynamicProfile > ) {
202+ drop ( profile. take ( ) )
260203}
261204
262205#[ must_use]
263206#[ no_mangle]
264207#[ named]
265208pub unsafe extern "C" fn ddog_prof_DynamicProfile_intern_stacktrace (
266- profile : * mut DynamicProfile ,
209+ profile : * mut Handle < DynamicProfile > ,
267210 locations : Slice < DynamicLocation > ,
268211) -> Result < DynamicStackTraceIndex > {
269212 wrap_with_ffi_result ! ( {
@@ -278,7 +221,7 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_intern_stacktrace(
278221#[ must_use]
279222#[ no_mangle]
280223pub unsafe extern "C" fn ddog_prof_DynamicProfile_add_sample_by_stacktrace (
281- profile : * mut DynamicProfile ,
224+ profile : * mut Handle < DynamicProfile > ,
282225 stacktrace : DynamicStackTraceIndex ,
283226 sample : DynamicSample ,
284227 timestamp_ns : i64 ,
@@ -300,7 +243,7 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_add_sample_by_stacktrace(
300243#[ must_use]
301244#[ no_mangle]
302245pub unsafe extern "C" fn ddog_prof_DynamicProfile_add_sample_by_locations (
303- profile : * mut DynamicProfile ,
246+ profile : * mut Handle < DynamicProfile > ,
304247 locations : Slice < DynamicLocation > ,
305248 sample : DynamicSample ,
306249 timestamp_ns : i64 ,
@@ -323,7 +266,7 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_add_sample_by_locations(
323266#[ must_use]
324267#[ no_mangle]
325268pub unsafe extern "C" fn ddog_prof_DynamicProfile_set_endpoint (
326- profile : * mut DynamicProfile ,
269+ profile : * mut Handle < DynamicProfile > ,
327270 local_root_span_id : u64 ,
328271 endpoint : CharSlice ,
329272) -> ProfileResult {
@@ -340,7 +283,7 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_set_endpoint(
340283#[ must_use]
341284#[ no_mangle]
342285pub unsafe extern "C" fn ddog_prof_DynamicProfile_add_endpoint_count (
343- profile : * mut DynamicProfile ,
286+ profile : * mut Handle < DynamicProfile > ,
344287 endpoint : CharSlice ,
345288 value : i64 ,
346289) -> ProfileResult {
@@ -357,7 +300,7 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_add_endpoint_count(
357300#[ must_use]
358301#[ no_mangle]
359302pub unsafe extern "C" fn ddog_prof_DynamicProfile_add_upscaling_rule_poisson (
360- profile : * mut DynamicProfile ,
303+ profile : * mut Handle < DynamicProfile > ,
361304 offset_values : Slice < usize > ,
362305 label_key : DynamicStringIndex ,
363306 label_value : CharSlice ,
@@ -385,7 +328,7 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_add_upscaling_rule_poisson(
385328#[ must_use]
386329#[ no_mangle]
387330pub unsafe extern "C" fn ddog_prof_DynamicProfile_add_upscaling_rule_poisson_non_sample_type_count (
388- profile : * mut DynamicProfile ,
331+ profile : * mut Handle < DynamicProfile > ,
389332 offset_values : Slice < usize > ,
390333 label_key : DynamicStringIndex ,
391334 label_value : CharSlice ,
@@ -413,7 +356,7 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_add_upscaling_rule_poisson_non
413356#[ must_use]
414357#[ no_mangle]
415358pub unsafe extern "C" fn ddog_prof_DynamicProfile_add_upscaling_rule_proportional (
416- profile : * mut DynamicProfile ,
359+ profile : * mut Handle < DynamicProfile > ,
417360 offset_values : Slice < usize > ,
418361 label_key : DynamicStringIndex ,
419362 label_value : CharSlice ,
@@ -437,7 +380,7 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_add_upscaling_rule_proportiona
437380#[ must_use]
438381#[ no_mangle]
439382pub unsafe extern "C" fn ddog_prof_DynamicProfile_serialize_and_clear_period_local_data (
440- profile : * mut DynamicProfile ,
383+ profile : * mut Handle < DynamicProfile > ,
441384 end_time : Option < & Timespec > ,
442385 duration_nanos : i64 ,
443386) -> SerializeResult {
@@ -460,7 +403,7 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_serialize_and_clear_period_loc
460403#[ must_use]
461404#[ no_mangle]
462405pub unsafe extern "C" fn ddog_prof_DynamicProfile_clear_period_local_data (
463- profile : * mut DynamicProfile ,
406+ profile : * mut Handle < DynamicProfile > ,
464407) -> ProfileResult {
465408 ( || {
466409 dynamic_profile_ptr_to_inner ( profile) ?. clear_period_local_data ( ) ?;
@@ -473,7 +416,7 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_clear_period_local_data(
473416#[ must_use]
474417#[ no_mangle]
475418pub unsafe extern "C" fn ddog_prof_DynamicProfile_clear_all_data (
476- profile : * mut DynamicProfile ,
419+ profile : * mut Handle < DynamicProfile > ,
477420) -> ProfileResult {
478421 ( || {
479422 dynamic_profile_ptr_to_inner ( profile) ?. clear_all_data ( ) ?;
@@ -485,7 +428,9 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_clear_all_data(
485428
486429#[ cfg( test) ]
487430mod tests {
431+ use super :: super :: datatypes:: ddog_prof_EncodedProfile_drop;
488432 use super :: * ;
433+ use libdd_common_ffi:: Error ;
489434 use libdd_common_ffi:: ToInner ;
490435 use libdd_profiling_protobuf:: prost_impls:: Message ;
491436
@@ -504,7 +449,7 @@ mod tests {
504449 fn ffi_roundtrip_serializes_dynamic_profile ( ) -> std:: result:: Result < ( ) , Error > {
505450 unsafe {
506451 let sample_type = SampleType :: WallTime ;
507- let mut dict = ArcHandle :: < InnerDynamicProfilesDictionary > :: default ( ) ;
452+ let mut dict = ArcHandle :: < DynamicProfilesDictionary > :: default ( ) ;
508453 std:: result:: Result :: < ( ) , _ > :: from (
509454 crate :: profiles:: dynamic_profiles_dictionary:: ddog_prof_DynamicProfilesDictionary_new (
510455 & mut dict,
@@ -557,9 +502,7 @@ mod tests {
557502 )
558503 . unwrap ( ) ;
559504
560- let mut profile = DynamicProfile {
561- inner : std:: ptr:: null_mut ( ) ,
562- } ;
505+ let mut profile = Handle :: < DynamicProfile > :: empty ( ) ;
563506 std:: result:: Result :: < ( ) , _ > :: from ( ddog_prof_DynamicProfile_with_dictionary (
564507 & mut profile,
565508 & dict,
0 commit comments