Skip to content

Commit 2a2dd0f

Browse files
committed
finalize implementation
1 parent 0078002 commit 2a2dd0f

File tree

11 files changed

+963
-434
lines changed

11 files changed

+963
-434
lines changed

Cargo.lock

Lines changed: 692 additions & 272 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,19 @@ name = "zenoh"
3434
crate-type = ["cdylib"]
3535

3636
[features]
37-
default = ["shared-memory", "zenoh/default", "zenoh-ext"]
37+
default = ["pyo3/abi3-py310", "shared-memory", "zenoh-ext", "zenoh/default"]
3838
shared-memory = ["zenoh/shared-memory"]
39-
zenoh-ext = ["dep:zenoh-ext", "zenoh-ext/unstable", "zenoh-ext/internal"]
39+
zenoh-ext = ["dep:zenoh-ext", "zenoh-ext/internal", "zenoh-ext/unstable"]
4040

4141
[badges]
4242
maintenance = { status = "actively-developed" }
4343

4444
[dependencies]
4545
paste = "1.0.14"
46-
pyo3 = { version = "0.25.1", features = [
47-
"extension-module",
48-
"abi3-py311",
49-
] }
50-
zenoh = { version = "1.5.1", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm-new-api", features = ["unstable", "internal"], default-features = false }
51-
zenoh-ext = { version = "1.5.1", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm-new-api", features = ["internal"], optional = true }
46+
pyo3 = { version = "0.25.1", features = ["extension-module"] }
47+
zenoh = { version = "1.5.1", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["internal", "unstable"], default-features = false }
48+
zenoh-ext = { version = "1.5.1", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["internal"], optional = true }
49+
50+
[build-dependencies]
51+
pyo3-build-config = { version = "0.25.1", features = ["resolve-config"] }
52+

build.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
pyo3_build_config::use_pyo3_cfgs();
3+
}

examples/z_pub_shm.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#
2+
# Copyright (c) 2022 ZettaScale Technology
3+
#
4+
# This program and the accompanying materials are made available under the
5+
# terms of the Eclipse Public License 2.0 which is available at
6+
# http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
#
9+
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
#
11+
# Contributors:
12+
# ZettaScale Zenoh Team, <[email protected]>
13+
#
14+
import time
15+
from typing import Optional
16+
17+
import zenoh
18+
19+
20+
def main(
21+
conf: zenoh.Config, key: str, payload: str, iter: Optional[int], interval: int
22+
):
23+
# initiate logging
24+
zenoh.init_log_from_env_or("error")
25+
26+
print("Opening session...")
27+
with zenoh.open(conf) as session:
28+
29+
print("Creating POSIX SHM provider...")
30+
provider = zenoh.shm.ShmProvider.default_backend(1024 * 1024)
31+
32+
print(f"Declaring Publisher on '{key}'...")
33+
pub = session.declare_publisher(key)
34+
35+
print("Press CTRL-C to quit...")
36+
for idx in itertools.count() if iter is None else range(iter):
37+
time.sleep(interval)
38+
prefix = f"[{idx:4d}] "
39+
sbuf = provider.alloc(
40+
len(prefix) + len(payload),
41+
policy=zenoh.shm.BlockOn(zenoh.shm.GarbageCollect()),
42+
)
43+
sbuf[: len(prefix)] = prefix.encode()
44+
sbuf[len(prefix) :] = payload.encode()
45+
46+
print(f"Putting Data ('{key}': '{sbuf}')...")
47+
pub.put(sbuf)
48+
49+
50+
# --- Command line argument parsing --- --- --- --- --- ---
51+
if __name__ == "__main__":
52+
import argparse
53+
import itertools
54+
55+
import common
56+
57+
parser = argparse.ArgumentParser(prog="z_pub", description="zenoh pub example")
58+
common.add_config_arguments(parser)
59+
parser.add_argument(
60+
"--key",
61+
"-k",
62+
dest="key",
63+
default="demo/example/zenoh-python-pub",
64+
type=str,
65+
help="The key expression to publish onto.",
66+
)
67+
parser.add_argument(
68+
"--payload",
69+
"-p",
70+
dest="payload",
71+
default="Pub from Python!",
72+
type=str,
73+
help="The payload to publish.",
74+
)
75+
parser.add_argument(
76+
"--iter", dest="iter", type=int, help="How many puts to perform"
77+
)
78+
parser.add_argument(
79+
"--interval",
80+
dest="interval",
81+
type=float,
82+
default=1.0,
83+
help="Interval between each put",
84+
)
85+
86+
args = parser.parse_args()
87+
conf = common.get_config_from_args(args)
88+
89+
main(conf, args.key, args.payload, args.iter, args.interval)

src/bytes.rs

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,16 @@
1111
// Contributors:
1212
// ZettaScale Zenoh Team, <[email protected]>
1313
//
14-
use std::{
15-
borrow::Cow,
16-
ffi::{c_int, c_void},
17-
io::Read,
18-
ptr,
19-
};
14+
use std::{borrow::Cow, io::Read};
2015

2116
use pyo3::{
22-
exceptions::{PyBufferError, PyTypeError, PyValueError},
17+
exceptions::{PyTypeError, PyValueError},
2318
prelude::*,
24-
types::{PyByteArray, PyBytes, PyString},
19+
types::{PyByteArray, PyBytes, PyMemoryView, PyString},
2520
};
2621

2722
use crate::{
2823
macros::{downcast_or_new, wrapper},
29-
shm::ZShmMut,
3024
utils::{IntoPyResult, MapInto},
3125
};
3226

@@ -46,52 +40,53 @@ impl ZBytes {
4640
Ok(Self(bytes.as_bytes().into()))
4741
} else if let Ok(string) = obj.downcast::<PyString>() {
4842
Ok(Self(string.to_string().into()))
49-
} else if let Ok(buf) = obj.downcast_exact::<ZShmMut>() {
50-
Ok(Self(buf.borrow_mut().take()?.into()))
5143
} else {
44+
#[cfg(feature = "shared-memory")]
45+
if let Ok(buf) = obj.downcast_exact::<crate::shm::ZShmMut>() {
46+
return Ok(Self(buf.borrow_mut().take()?.into()));
47+
}
48+
#[cfg(Py_3_11)]
49+
if let Ok(buffer) = pyo3::buffer::PyBuffer::<u8>::get(obj) {
50+
return Ok(Self(buffer.to_vec(obj.py())?.into()));
51+
}
5252
Err(PyTypeError::new_err(format!(
5353
"expected bytes/str type, found '{}'",
5454
obj.get_type().name().unwrap()
5555
)))
5656
}
5757
}
5858

59+
#[cfg(Py_3_11)]
5960
unsafe fn __getbuffer__(
60-
this: Bound<'_, Self>,
61+
mut this: PyRefMut<Self>,
6162
view: *mut pyo3::ffi::Py_buffer,
62-
flags: c_int,
63+
flags: std::ffi::c_int,
6364
) -> PyResult<()> {
6465
if view.is_null() {
65-
return Err(PyBufferError::new_err("Buffer ptr is null"));
66+
return Err(pyo3::exceptions::PyBufferError::new_err(
67+
"Buffer ptr is null",
68+
));
6669
}
6770
if flags & pyo3::ffi::PyBUF_WRITABLE != 0 {
68-
return Err(PyBufferError::new_err("ZBytes is not writable"));
71+
return Err(pyo3::exceptions::PyBufferError::new_err(
72+
"ZBytes is not writable",
73+
));
6974
}
70-
let mut borrow = this.borrow_mut();
71-
let (buf, len) = match borrow.0.to_bytes() {
75+
let (buf, len) = match this.0.to_bytes() {
7276
Cow::Borrowed(bytes) => (bytes.as_ptr(), bytes.len()),
7377
Cow::Owned(bytes) => {
7478
let (buf, len) = (bytes.as_ptr(), bytes.len());
75-
borrow.0 = bytes.into();
79+
this.0 = bytes.into();
7680
(buf, len)
7781
}
7882
};
7983
unsafe {
80-
(*view).buf = buf as *mut c_void;
81-
(*view).obj = this.into_ptr();
82-
(*view).len = len as isize;
83-
(*view).readonly = 1;
84-
(*view).itemsize = 1;
85-
(*view).format = ptr::null_mut();
86-
(*view).ndim = 1;
87-
(*view).shape = ptr::null_mut();
88-
(*view).strides = ptr::null_mut();
89-
(*view).suboffsets = ptr::null_mut();
90-
(*view).internal = ptr::null_mut();
91-
}
84+
crate::utils::init_buffer(view, flags, buf.cast_mut(), len, true, this.into_ptr())
85+
};
9286
Ok(())
9387
}
9488

89+
#[cfg(Py_3_11)]
9590
unsafe fn __releasebuffer__(&mut self, _view: *mut pyo3::ffi::Py_buffer) {}
9691

9792
fn to_bytes<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
@@ -107,6 +102,13 @@ impl ZBytes {
107102
.map_err(|_| PyValueError::new_err("not an UTF8 error"))
108103
}
109104

105+
fn __getitem__<'py>(
106+
this: &Bound<'py, Self>,
107+
obj: &Bound<'py, PyAny>,
108+
) -> PyResult<Bound<'py, PyAny>> {
109+
PyMemoryView::from(this.as_any())?.get_item(obj)
110+
}
111+
110112
fn __len__(&self) -> usize {
111113
self.0.len()
112114
}

src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ pub(crate) mod zenoh {
9797

9898
#[cfg(feature = "shared-memory")]
9999
#[pymodule]
100-
mod _shm {
100+
mod shm {
101101
#[pymodule_export]
102102
use crate::shm::{
103-
AllocAlignment, BlockOn, DeallocEldest, DeallocOptimal, DeallocYoungest, Deallocate,
104-
Defragment, GarbageCollect, JustAlloc, ShmProvider, ZShmMut,
103+
AllocAlignment, BlockOn, Deallocate, Defragment, GarbageCollect, JustAlloc,
104+
ShmProvider, ZShmMut,
105105
};
106106
}
107107

@@ -112,7 +112,7 @@ pub(crate) mod zenoh {
112112
#[cfg(feature = "zenoh-ext")]
113113
sys_modules.set_item("zenoh._ext", m.getattr("_ext")?)?;
114114
#[cfg(feature = "shared-memory")]
115-
sys_modules.set_item("zenoh._shm", m.getattr("_shm")?)?;
115+
sys_modules.set_item("zenoh.shm", m.getattr("shm")?)?;
116116
// TODO
117117
// crate::logging::init_logger(m.py())?;
118118
Ok(())

0 commit comments

Comments
 (0)