Skip to content

Commit e812aff

Browse files
committed
put in ddcommon-ffi
1 parent b6c2198 commit e812aff

File tree

8 files changed

+70
-14
lines changed

8 files changed

+70
-14
lines changed

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ddcommon-ffi/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ cbindgen = ["build_common/cbindgen"]
1919
build_common = { path = "../build-common" }
2020

2121
[dependencies]
22-
ddcommon = { path = "../ddcommon" }
2322
anyhow = "1.0"
23+
crossbeam-queue = "0.3.11"
24+
ddcommon = { path = "../ddcommon" }
2425
hyper = {version = "0.14", default-features = false}

ddcommon-ffi/cbindgen.toml

+6
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ rename_types = "PascalCase"
5454
[export.rename]
5555
"ParseTagsResult" = "ddog_Vec_Tag_ParseResult"
5656
"PushTagResult" = "ddog_Vec_Tag_PushResult"
57+
"ArrayQueueNewResult" = "ddog_ArrayQueue_NewResult"
58+
"ArrayQueuePushResult" = "ddog_ArrayQueue_PushResult"
59+
"ArrayQueuePopResult" = "ddog_ArrayQueue_PopResult"
60+
"ArrayQueueIsEmptyResult" = "ddog_ArrayQueue_IsEmptyResult"
61+
"ArrayQueueLenResult" = "ddog_ArrayQueue_LenResult"
62+
5763

5864
[enum]
5965
prefix_with_name = true

profiling-ffi/src/array_queue.rs renamed to ddcommon-ffi/src/array_queue.rs

+60-5
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,42 @@
11
// Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/
22
// SPDX-License-Identifier: Apache-2.0
33

4+
use crate::Error;
45
use anyhow::Context;
5-
use ddcommon_ffi::Error;
66
use std::ffi::c_void;
77

88
#[repr(C)]
9+
// A simple wrapper around crossbeam_queue::ArrayQueue<*mut c_void>, which is a lock free
10+
// bounded multi-producer and multi-consumer (MPMC) queue.
911
pub struct ArrayQueue {
12+
// The actual type here should be *mut crossbeam_queue::ArrayQueue<*mut c_void>.
13+
// However, cbindgen does not use the module name crossbeam_queue to generate the C header.
14+
// So we use *mut c_void here and cast it to the correct type in the FFI functions.
1015
inner: *mut c_void,
16+
item_delete_fn: unsafe extern "C" fn(*mut c_void) -> c_void,
1117
}
1218

1319
impl ArrayQueue {
14-
pub fn new(inner: *mut c_void) -> Self {
15-
Self { inner }
20+
pub fn new(
21+
inner: *mut c_void,
22+
item_delete_fn: unsafe extern "C" fn(*mut c_void) -> c_void,
23+
) -> Self {
24+
Self {
25+
inner,
26+
item_delete_fn,
27+
}
28+
}
29+
}
30+
31+
impl Drop for ArrayQueue {
32+
fn drop(&mut self) {
33+
unsafe {
34+
let queue = self.inner as *mut crossbeam_queue::ArrayQueue<*mut c_void>;
35+
while let Some(item) = (*queue).pop() {
36+
(self.item_delete_fn)(item);
37+
}
38+
drop(Box::from_raw(queue));
39+
}
1640
}
1741
}
1842

@@ -23,15 +47,23 @@ pub enum ArrayQueueNewResult {
2347
Err(Error),
2448
}
2549

50+
/// Creates a new ArrayQueue with the given capacity and item_delete_fn.
51+
/// The item_delete_fn is called when an item is dropped from the queue.
2652
#[no_mangle]
27-
pub unsafe extern "C" fn array_queue_new(capacity: usize) -> ArrayQueueNewResult {
53+
pub extern "C" fn array_queue_new(
54+
capacity: usize,
55+
item_delete_fn: unsafe extern "C" fn(*mut c_void) -> c_void,
56+
) -> ArrayQueueNewResult {
2857
let internal_queue: crossbeam_queue::ArrayQueue<*mut c_void> =
2958
crossbeam_queue::ArrayQueue::new(capacity);
3059
let internal_queue_ptr = Box::into_raw(Box::new(internal_queue));
31-
let ffi_queue = ArrayQueue::new(internal_queue_ptr as *mut c_void);
60+
let ffi_queue = ArrayQueue::new(internal_queue_ptr as *mut c_void, item_delete_fn);
3261
ArrayQueueNewResult::Ok(ffi_queue)
3362
}
3463

64+
/// Converts a *mut ArrayQueue to a &mut crossbeam_queue::ArrayQueue<*mut c_void>.
65+
/// # Safety
66+
/// The pointer is null or points to a valid memory location allocated by array_queue_new.
3567
unsafe fn array_queue_ptr_to_inner<'a>(
3668
queue_ptr: *mut ArrayQueue,
3769
) -> anyhow::Result<&'a mut crossbeam_queue::ArrayQueue<*mut c_void>> {
@@ -46,6 +78,16 @@ unsafe fn array_queue_ptr_to_inner<'a>(
4678
}
4779
}
4880

81+
/// Drops the ArrayQueue.
82+
/// # Safety
83+
/// The pointer is null or points to a valid memory location allocated by array_queue_new.
84+
#[no_mangle]
85+
pub unsafe extern "C" fn array_queue_drop(queue_ptr: *mut ArrayQueue) {
86+
if !queue_ptr.is_null() {
87+
drop(Box::from_raw(queue_ptr));
88+
}
89+
}
90+
4991
#[allow(unused)]
5092
#[repr(C)]
5193
pub enum ArrayQueuePushResult {
@@ -62,6 +104,10 @@ impl From<Result<(), anyhow::Error>> for ArrayQueuePushResult {
62104
}
63105
}
64106

107+
/// Pushes an item into the ArrayQueue.
108+
/// # Safety
109+
/// The pointer is null or points to a valid memory location allocated by array_queue_new. The value
110+
/// is null or points to a valid memory location that can be deallocated by the item_delete_fn.
65111
#[no_mangle]
66112
pub unsafe extern "C" fn array_queue_push(
67113
queue_ptr: *mut ArrayQueue,
@@ -93,6 +139,9 @@ impl From<anyhow::Result<*mut c_void>> for ArrayQueuePopResult {
93139
}
94140
}
95141

142+
/// Pops an item from the ArrayQueue.
143+
/// # Safety
144+
/// The pointer is null or points to a valid memory location allocated by array_queue_new.
96145
#[no_mangle]
97146
pub unsafe extern "C" fn array_queue_pop(queue_ptr: *mut ArrayQueue) -> ArrayQueuePopResult {
98147
(|| {
@@ -121,6 +170,9 @@ impl From<anyhow::Result<bool>> for ArrayQueueIsEmptyResult {
121170
}
122171
}
123172

173+
/// Checks if the ArrayQueue is empty.
174+
/// # Safety
175+
/// The pointer is null or points to a valid memory location allocated by array_queue_new.
124176
#[no_mangle]
125177
pub unsafe extern "C" fn array_queue_is_empty(
126178
queue_ptr: *mut ArrayQueue,
@@ -149,6 +201,9 @@ impl From<anyhow::Result<usize>> for ArrayQueueLenResult {
149201
}
150202
}
151203

204+
/// Returns the length of the ArrayQueue.
205+
/// # Safety
206+
/// The pointer is null or points to a valid memory location allocated by array_queue_new.
152207
#[no_mangle]
153208
pub unsafe extern "C" fn array_queue_len(queue_ptr: *mut ArrayQueue) -> ArrayQueueLenResult {
154209
(|| {

ddcommon-ffi/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
mod error;
55

6+
pub mod array_queue;
67
pub mod endpoint;
78
pub mod option;
89
pub mod slice;

profiling-ffi/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ build_common = { path = "../build-common" }
2727
[dependencies]
2828
anyhow = "1.0"
2929
chrono = {version = "0.4", default-features = false }
30-
crossbeam-queue = "0.3.11"
3130
datadog-crashtracker = { path = "../crashtracker" }
3231
datadog-profiling = { path = "../profiling" }
3332
hyper = { version = "0.14", default-features = false }

profiling-ffi/cbindgen.toml

-5
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,6 @@ renaming_overrides_prefixing = true
3333
"Vec_Tag" = "ddog_Vec_Tag"
3434
"Vec_U8" = "ddog_Vec_U8"
3535

36-
"ArrayQueueNewResult" = "ddog_prof_ArrayQueue_NewResult"
37-
"ArrayQueuePushResult" = "ddog_prof_ArrayQueue_PushResult"
38-
"ArrayQueuePopResult" = "ddog_prof_ArrayQueue_PopResult"
39-
"ArrayQueueIsEmptyResult" = "ddog_prof_ArrayQueue_IsEmptyResult"
40-
"ArrayQueueLenResult" = "ddog_prof_ArrayQueue_LenResult"
4136
"ProfilingEndpoint" = "ddog_prof_Endpoint"
4237
"ExporterNewResult" = "ddog_prof_Exporter_NewResult"
4338
"File" = "ddog_prof_Exporter_File"

profiling-ffi/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use std::time::SystemTime;
99

1010
use chrono::{DateTime, TimeZone, Utc};
1111

12-
mod array_queue;
1312
mod crashtracker;
1413
mod exporter;
1514
mod profiles;

0 commit comments

Comments
 (0)