Skip to content

Commit 531d82f

Browse files
committed
removed arc from keyexpr
1 parent bbbcf5a commit 531d82f

4 files changed

Lines changed: 45 additions & 45 deletions

File tree

zenoh-flat/src/keyexpr.rs

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,33 @@
1111
// ZettaScale Zenoh Team, <zenoh@zettascale.tech>
1212
//
1313

14-
use std::sync::Arc;
15-
1614
use crate::{errors::ZResult, zerror};
1715
use prebindgen_proc_macro::prebindgen;
1816
use zenoh::key_expr::{KeyExpr as ZKeyExpr, SetIntersectionLevel};
1917

2018
/// Universal key-expression handle shared across the flat layer.
2119
///
2220
/// `ptr` is `None` for string-only expressions built via [`try_from`] /
23-
/// [`autocanonize`]. `Some(md)` holds an `Arc<ZKeyExpr<'static>>` wrapped
24-
/// in `ManuallyDrop` so it never auto-drops when the struct is destroyed:
25-
/// the caller is responsible for releasing the Arc either by calling
26-
/// `drop_key_expr` / `undeclare_key_expr` (session-declared) or simply
27-
/// letting the undeclared variant be discarded (no-op).
21+
/// [`autocanonize`]. `Some(md)` holds a session-declared zenoh
22+
/// `ZKeyExpr<'static>`.
2823
///
2924
/// Field order (`ptr` first) matches the `KeyExpr(ptr: Long, string: String)`
3025
/// Kotlin constructor so positional call sites need no update.
3126
#[prebindgen_proc_macro::prebindgen]
3227
#[derive(Debug)]
3328
pub struct KeyExpr {
34-
pub ptr: Option<Arc<ZKeyExpr<'static>>>,
29+
pub ptr: Option<ZKeyExpr<'static>>,
3530
pub string: String,
3631
}
3732

3833
impl KeyExpr {
3934
/// Materialize a borrowed zenoh `KeyExpr` for one-shot zenoh calls.
4035
///
41-
/// When `ptr != 0`, bumps the Arc strong count, clones the inner
42-
/// `ZKeyExpr`, then drops the temporary Arc (net count unchanged).
36+
/// When `ptr != 0`, clones the stored `ZKeyExpr`.
4337
/// When `ptr == 0`, constructs from the already-validated string.
4438
pub(crate) fn as_zenoh(&self) -> ZKeyExpr<'static> {
4539
if let Some(md) = &self.ptr {
46-
md.as_ref().clone()
40+
md.clone()
4741
} else {
4842
// SAFETY: every `KeyExpr` is built via the validating
4943
// constructors (`try_from`, `autocanonize`, join, concat).
@@ -105,7 +99,7 @@ pub fn join(a: &KeyExpr, other: String) -> ZResult<KeyExpr> {
10599
.map_err(|err| zerror!(err))?;
106100
let string = joined.to_string();
107101
let ptr = if a.ptr.is_some() {
108-
Some(Arc::new(ZKeyExpr::from(joined)))
102+
Some(ZKeyExpr::from(joined))
109103
} else {
110104
None
111105
};
@@ -123,22 +117,18 @@ pub fn concat(a: &KeyExpr, other: String) -> ZResult<KeyExpr> {
123117
.map_err(|err| zerror!(err))?;
124118
let string = concatenated.to_string();
125119
let ptr = if a.ptr.is_some() {
126-
Some(Arc::new(ZKeyExpr::from(concatenated)))
120+
Some(ZKeyExpr::from(concatenated))
127121
} else {
128122
None
129123
};
130124
Ok(KeyExpr { ptr, string })
131125
}
132126

133127
/// Drop a [`KeyExpr`] handle obtained from a session-declared key
134-
/// expression. When `ptr != 0`, takes ownership of the `Arc<ZKeyExpr>`
135-
/// (decrementing the strong count). String-only expressions are a no-op.
128+
/// expression. With value-owned storage, this is always a no-op because the
129+
/// wrapper drops naturally when consumed.
136130
#[prebindgen]
137131
pub fn drop_key_expr(key_expr: KeyExpr) -> ZResult<()> {
138-
if let Some(ptr) = key_expr.ptr {
139-
// SAFETY: `ptr` was produced by `Arc::into_raw`; taking ownership
140-
// here and letting the Arc drop releases the Java-side strong ref.
141-
drop(ptr);
142-
}
132+
let _ = key_expr;
143133
Ok(())
144134
}

zenoh-flat/src/session.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
use crate::keyexpr::KeyExpr;
1515
use crate::{errors::ZResult, zerror};
16-
use std::sync::Arc;
1716
use std::time::Duration;
1817
use tracing::{error, trace};
1918

@@ -110,8 +109,7 @@ pub fn declare_key_expr(session: &Session, key_expr: String) -> ZResult<KeyExpr>
110109
.map(|ke| {
111110
trace!("Declared key expression '{}'.", key_expr_clone);
112111
KeyExpr {
113-
// SAFETY: transfers Arc ownership to the Java caller.
114-
ptr: Some(Arc::new(ke)),
112+
ptr: Some(ke),
115113
string: key_expr,
116114
}
117115
})

zenoh-jni/build.rs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,7 @@ macro_rules! decode_option_arc_from_raw {
8787
if #input != 0 {
8888
Some(unsafe {
8989
let raw = #input as *const $inner;
90-
std::sync::Arc::increment_strong_count(raw);
91-
std::sync::Arc::from_raw(raw)
90+
(*raw).clone()
9291
})
9392
} else {
9493
None
@@ -122,6 +121,26 @@ macro_rules! encode_arc_into_raw {
122121
};
123122
}
124123

124+
/// Encode an `Option<T>` (where `T: Clone`) into a `jlong` Arc-handle.
125+
///
126+
/// `Some(v)` becomes `Arc::into_raw(Arc::new(v.clone())) as i64`.
127+
/// `None` maps to `0`.
128+
macro_rules! encode_option_clone_into_arc_raw_jlong {
129+
() => {
130+
OutputFn::new(|output: Option<&syn::Ident>| -> TokenStream {
131+
match output {
132+
Some(output) => quote! {
133+
#output
134+
.as_ref()
135+
.map(|value| std::sync::Arc::into_raw(std::sync::Arc::new(value.clone())) as i64)
136+
.unwrap_or(0)
137+
},
138+
None => quote! { 0 },
139+
}
140+
})
141+
};
142+
}
143+
125144
/// Emit `<result> as <wire>` on success and `<on_err> as <wire>` on the
126145
/// throw-path. Used for primitive wire types that map straight from the
127146
/// Rust return value (e.g. `bool` → `jboolean`, `i32` → `jint`).
@@ -182,24 +201,15 @@ fn shared_bindings() -> TypeRegistry {
182201
// FlatKeyExpr (zenoh_flat::keyexpr::KeyExpr) — auto-generated as a
183202
// Kotlin data class; `ptr: Long` carries the raw Arc pointer (0 =
184203
// string-only). The flat Rust struct now stores
185-
// `Option<Arc<ZKeyExpr<'static>>>`, so decode the primitive field
186-
// into an owned `Arc` only when a non-zero pointer is present.
204+
// `Option<ZKeyExpr<'static>>`, so decode the primitive field by
205+
// temporarily materializing an Arc-handle (from raw), cloning the
206+
// inner key expression, then dropping the temporary Arc.
187207
//
188208
// `"KeyExpr"` (by-value) is auto-registered by the struct_conv pass
189209
// below, so only the borrow and return variants need manual entries.
190-
.type_pair("Option<Arc<ZKeyExpr<'static>>>", "jni::sys::jlong")
210+
.type_pair("Option<ZKeyExpr<'static>>", "jni::sys::jlong")
191211
.input(decode_option_arc_from_raw!(zenoh::key_expr::KeyExpr<'static>))
192-
.output(OutputFn::new(|output: Option<&syn::Ident>| -> TokenStream {
193-
match output {
194-
Some(output) => quote! {
195-
#output
196-
.as_ref()
197-
.map(|ptr| std::sync::Arc::into_raw(ptr.clone()) as i64)
198-
.unwrap_or(0)
199-
},
200-
None => quote! { 0 },
201-
}
202-
}))
212+
.output(encode_option_clone_into_arc_raw_jlong!())
203213
.type_pair("&KeyExpr", "jni::objects::JObject")
204214
.input(decode_env_ref_mut!(decode_KeyExpr))
205215
.type_pair("ZResult<KeyExpr>", "jni::sys::jobject")
@@ -287,7 +297,7 @@ fn shared_kotlin_types() -> KotlinTypeMap {
287297
.add("QueryTarget", "Int")
288298
.add("ConsolidationMode", "Int")
289299
.add("ReplyKeyExpr", "Int")
290-
.add("Option<Arc<ZKeyExpr<'static>>>", "Long")
300+
.add("Option<ZKeyExpr<'static>>", "Long")
291301
.add("&KeyExpr", "KeyExpr")
292302
.add("ZResult<KeyExpr>", "KeyExpr")
293303
.add("ZResult<SetIntersectionLevel>", "Int")

zenoh-jni/src/key_expr.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,18 @@ use zenoh_flat::keyexpr::KeyExpr as FlatKeyExpr;
2222

2323
use crate::errors::ZResult;
2424

25+
unsafe fn clone_key_expr_from_arc_ptr(ptr: i64) -> ZResult<ZKeyExpr<'static>> {
26+
let raw = ptr as *const ZKeyExpr<'static>;
27+
Ok((*raw).clone())
28+
}
29+
2530
/// Encode a [`FlatKeyExpr`] as a freshly-constructed
2631
/// `io.zenoh.jni.KeyExpr` Java object. When `ptr` is non-zero, the strong
2732
/// `Arc` reference (already owned by this value) is transferred to Java.
2833
pub(crate) fn encode_jni_keyexpr(env: &mut JNIEnv, k: FlatKeyExpr) -> ZResult<jobject> {
2934
let raw_ptr = k
3035
.ptr
31-
.map(|ptr| Arc::into_raw(ptr) as i64)
36+
.map(|key_expr| Arc::into_raw(Arc::new(key_expr)) as i64)
3237
.unwrap_or(0);
3338
let jstr = env
3439
.new_string(k.string)
@@ -58,10 +63,7 @@ pub(crate) unsafe fn decode_jni_key_expr(
5863
.and_then(|v| v.j())
5964
.map_err(|err| zerror!("KeyExpr.ptr: {}", err))?;
6065
if ptr != 0 {
61-
let raw = ptr as *const ZKeyExpr<'static>;
62-
Arc::increment_strong_count(raw);
63-
let arc = Arc::from_raw(raw);
64-
Ok((*arc).clone())
66+
clone_key_expr_from_arc_ptr(ptr)
6567
} else {
6668
let str_obj = env
6769
.get_field(obj, "string", "Ljava/lang/String;")

0 commit comments

Comments
 (0)