Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework ffi with new logging, error handling and some improvements in arch and safe #10

Open
wants to merge 77 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
7333525
Remove ffi with new `logging` and some improvements in arch and safe
uselessgoddess Aug 14, 2022
4d59bae
Improve logging (via `instrument`s) and naming
uselessgoddess Aug 14, 2022
e0edd83
Add ffi context to callbacks
uselessgoddess Aug 14, 2022
e8691c2
Add ffi `examples` crate
uselessgoddess Aug 15, 2022
63be554
Fix too long ptr cast
uselessgoddess Aug 17, 2022
b1a3d77
Improve safety docs
uselessgoddess Aug 17, 2022
f4c7cb4
Improve error handling:
uselessgoddess Aug 18, 2022
a40e21e
Use `thread_local` attribute for `ERROR_PLACE`
uselessgoddess Aug 19, 2022
7dd3cd9
Improve `warn` message in `query_from_raw`
uselessgoddess Aug 19, 2022
4600061
Improvements list:
uselessgoddess Aug 19, 2022
4f6b95b
Improvements list:
uselessgoddess Aug 19, 2022
a11188f
Update outdated data
uselessgoddess Aug 19, 2022
edd0b87
Use `NonNull` instead of raw pointer
uselessgoddess Aug 22, 2022
646f1ae
`cargo fix` unused imports
uselessgoddess Aug 23, 2022
6d7c353
`cargo fix` unused imports
uselessgoddess Aug 23, 2022
abee06b
Improve `ffi-attributes`:
uselessgoddess Aug 23, 2022
8420a12
Remove forgotten comment
uselessgoddess Aug 23, 2022
4ec685a
Fix type `lit` => `ty`
uselessgoddess Aug 23, 2022
6c71760
Add `attributes` keyword to delegate some attrs to parent function im…
uselessgoddess Aug 24, 2022
cc2eee1
Fix some externs
uselessgoddess Aug 24, 2022
2c10ab3
Add some doc comments to `Range`
uselessgoddess Aug 24, 2022
fdc90c9
Fix brackets in `error-handling` example
uselessgoddess Aug 24, 2022
f48486c
Use `usize` instead of `c_size_t`
uselessgoddess Aug 24, 2022
b7e8a25
Use modern `StoreHandle` without `Box::from_raw/into_raw`
uselessgoddess Aug 24, 2022
7454ec0
Add error handling without bottleneck (`ERROR_PLACE`) and `take_last_…
uselessgoddess Aug 24, 2022
d54db5d
Improve `OpaqueSlice` in favor of `OwnedSlice`
uselessgoddess Aug 24, 2022
fba6e78
Fix some typos in readme
uselessgoddess Aug 25, 2022
d5025c0
Revert changes in README.md
uselessgoddess Aug 26, 2022
0890293
Fix some typos in readme
uselessgoddess Aug 26, 2022
56ae6bc
Use `Box` instead of raw ptrs
uselessgoddess Aug 26, 2022
7061c37
Stop logging if channel is disconnected
uselessgoddess Aug 26, 2022
2de822a
Remove useless `todo` message
uselessgoddess Aug 26, 2022
0f4d4fa
Improve repr of `StoreHandle`
uselessgoddess Aug 26, 2022
9c58bb0
Fix macro error message
uselessgoddess Aug 28, 2022
f570601
Change pair from Ident => Ident to Type => Ident
Mitron57 Aug 28, 2022
a2ba506
Make code more cleaned and self-doc+friendly for parsing
uselessgoddess Aug 28, 2022
4752904
Some improvements:
uselessgoddess Aug 30, 2022
18ed088
Fix useless `.clone` in `ffi-attributes`
uselessgoddess Aug 31, 2022
6a7a90f
Fix imports and useless in examples
uselessgoddess Aug 31, 2022
a57cec3
Add `backtrace` feature and make `doublets-ffi` features-free:
uselessgoddess Aug 31, 2022
67afd89
Update building guide
uselessgoddess Aug 31, 2022
367b05a
Fix copy typo in readme
uselessgoddess Aug 31, 2022
74fbc82
Install stable rust in readme
uselessgoddess Aug 31, 2022
804823b
Add `Off` for `Level` and simplify `EnvFilter` to `match`
uselessgoddess Sep 1, 2022
056c7e2
Add colored shows to `log-context` example
uselessgoddess Sep 1, 2022
4adab77
Fix typo in example
uselessgoddess Sep 1, 2022
6b1345a
Improve colors and reset
uselessgoddess Sep 3, 2022
3338ba8
Start queries reworking
uselessgoddess Sep 4, 2022
78cf083
Merge remote-tracking branch 'origin/ffi-rework' into ffi-rework
uselessgoddess Sep 4, 2022
97c2640
Revert queries reworking
uselessgoddess Sep 4, 2022
918d255
Forbid dynamic lib to ffi
uselessgoddess Sep 4, 2022
26927a7
Add docs to `FFICallbackContextWrapper`
uselessgoddess Sep 4, 2022
8561b07
Improve `Range` and add `Maybe` to simplify constants conversion
uselessgoddess Sep 4, 2022
903d07e
Fix typo
uselessgoddess Sep 4, 2022
ae182b5
Improve `backtrace` feature in favor of `unstable_backtrace`
uselessgoddess Sep 4, 2022
3eb54ef
Fix `if-else-let` lint
uselessgoddess Sep 4, 2022
d6de95a
Add marker<Box<[T]>> to `OwnedSlice`
uselessgoddess Sep 6, 2022
c2a4813
allow(clippy::borrowed_box) for `assume_ref`
uselessgoddess Sep 6, 2022
766df15
Use `while let` instead of `loop { if let }` in logging loop
uselessgoddess Sep 6, 2022
2e7e592
Use slice as queries
uselessgoddess Sep 6, 2022
155f475
Add error handling to store creation
uselessgoddess Sep 7, 2022
d619560
explain `if let` to `.is_ok`
uselessgoddess Sep 7, 2022
af3fef0
Use shortest error messages
uselessgoddess Sep 7, 2022
722094c
Shortest ptr cast
uselessgoddess Sep 7, 2022
8da33d5
Improve error handling in favor of Rust looks like
uselessgoddess Sep 9, 2022
3bf0a7e
Fix priv `utils` mod
uselessgoddess Sep 9, 2022
0e71c0e
Disable clippy with bug
uselessgoddess Sep 9, 2022
8433376
Fix fallible example
uselessgoddess Sep 9, 2022
a5156ed
Really disable clippy
uselessgoddess Sep 9, 2022
a95d580
Use shortest names
uselessgoddess Sep 9, 2022
fb70b9c
Improve code for future readers
uselessgoddess Sep 9, 2022
9042ce8
Improve code for future readers - two-step
uselessgoddess Sep 9, 2022
3754990
Add `cbindgen` config for cxx (but with problems):
uselessgoddess Sep 10, 2022
3b272d9
Cosmetic improvements
uselessgoddess Sep 12, 2022
fb2aad6
Remove unused imports
uselessgoddess Nov 27, 2022
ce9449a
Improve `Fallible` messages and idioms
uselessgoddess Nov 27, 2022
97e12b2
Remove type - useless import
uselessgoddess Nov 27, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
[workspace]

members = [
"doublets-ffi",
"doublets",
"doublets-ffi",
"doublets-ffi/examples/rust",

# dev
"dev-deps/mem-rs",
Expand Down
15 changes: 8 additions & 7 deletions doublets-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "staticlib"]
crate-type = ["cdylib", "staticlib", "lib"]

[dependencies]
log = "0.4.14"
libc = "0.2.100"
tracing-subscriber = "0.3.3"
tracing-log = "0.1.2"
tracing = "0.1.29"
doublets = { path = "../doublets" }
ffi-attributes = { path = "ffi-attributes" }
env-decorators = { path = "env-decorators" }

tap = { version = "1.0.1" }
log-panics = { version = "2.1.0" }

crossbeam-channel = { version = "0.5.6" }
tracing = { version = "0.1.36" }
tracing-subscriber = { version = "0.3.15", features = ["env-filter", "json"] }

[package.log]
features = ["release_max_level_error"]
12 changes: 0 additions & 12 deletions doublets-ffi/env-decorators/Cargo.toml

This file was deleted.

78 changes: 0 additions & 78 deletions doublets-ffi/env-decorators/src/lib.rs

This file was deleted.

10 changes: 10 additions & 0 deletions doublets-ffi/examples/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "doublets-ffi-examples"
version = "0.0.0"
edition = "2021"
publish = false

[dependencies]
doublets-ffi = { path = "../../../doublets-ffi" }
doublets = { path = "../../../doublets" }
tracing = { version = "0.1.36" }
31 changes: 31 additions & 0 deletions doublets-ffi/examples/rust/examples/all-logs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use doublets_ffi::{
export::{doublets_create_log_handle, doublets_free_log_handle},
FFICallbackContext,
};
use std::{
ffi::{c_char, CStr, CString},
ptr,
};

unsafe extern "C" fn callback(_: FFICallbackContext, ptr: *const c_char) {
let cstr = CStr::from_ptr(ptr);
print!("{}", cstr.to_str().unwrap());
Comment on lines +14 to +15
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let cstr = CStr::from_ptr(ptr);
print!("{}", cstr.to_str().unwrap());
let cstr = CStr::from_ptr(ptr).to_str().unwrap();
print!("{}", cstr);

}

fn main() {
let ctx = ptr::null_mut();
let level = CString::new("trace").unwrap();
let use_ansi = true;
let use_json = false;
unsafe {
let handle = doublets_create_log_handle(ctx, callback, level.as_ptr(), use_ansi, use_json);

tracing::error!("SOMETHING IS SERIOUSLY WRONG!!!");
tracing::warn!("important informational messages; might indicate an error");
tracing::info!("general informational messages relevant to users");
tracing::debug!("diagnostics used for internal debugging of a library or application");
tracing::trace!("very verbose diagnostic events");
Comment on lines +37 to +41
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move logs out unsafe context. It's confusing


doublets_free_log_handle(handle);
}
}
59 changes: 59 additions & 0 deletions doublets-ffi/examples/rust/examples/doublets-context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use doublets::{
data::{Flow, LinksConstants},
Link,
};
use doublets_ffi::{
constants::Constants,
errors::DoubletsErrorKind,
export::{doublets_create_log_handle, doublets_free_log_handle},
store::{create, doublets_constants_u64, doublets_create_united_store_u64},
FFICallbackContext,
};
use std::{
ffi::{c_char, c_void, CStr, CString},
fs,
ptr::{null, null_mut},
};

unsafe extern "C" fn callback(_: FFICallbackContext, ptr: *const c_char) {
print!("{}", CStr::from_ptr(ptr).to_str().unwrap());
}

extern "C" fn create_cb<F>(ctx: FFICallbackContext, before: Link<u64>, after: Link<u64>) -> Flow
where
F: FnMut(Link<u64>, Link<u64>),
{
unsafe {
let handler = &mut *(ctx as *mut F);
(*handler)(before, after);
Flow::Continue
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsafe context is too long

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
unsafe {
let handler = &mut *(ctx as *mut F);
(*handler)(before, after);
Flow::Continue
}
let handler = unsafe { &mut *(ctx as *mut F) };
(*handler)(before, after);
Flow::Continue

}

unsafe fn magic_create<F>(ptr: *mut c_void, handler: F)
where
F: FnMut(Link<u64>, Link<u64>),
{
let ctx = &mut (ptr, handler);
let _ = create(ptr, null(), 0, ctx as *mut _ as *mut _, create_cb::<F>);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could supplement this example almost to the level of real use


fn main() {
let level = CString::new("trace").unwrap();
unsafe {
let handle = doublets_create_log_handle(null_mut(), callback, level.as_ptr(), true, false);

let path = CString::new("doublets.links").unwrap();
let mut store = doublets_create_united_store_u64(
path.as_ptr(),
Constants::from(LinksConstants::external()),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add ffi functions to create external/internal constants

);

magic_create(store.assume() as *mut _ as *mut _, |before, after| {
print!("{before:?}\n{after:?}\n");
});

doublets_free_log_handle(handle);
}
let _ = fs::remove_file("doublets.links");
}
72 changes: 72 additions & 0 deletions doublets-ffi/examples/rust/examples/error-handling.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use doublets::{
data::{Flow, LinksConstants},
Link,
};
use doublets_ffi::{
constants::Constants,
errors::{
doublets_read_error, doublets_read_error_as_not_found, doublets_read_error_message,
DoubletsErrorKind,
},
export::{doublets_create_log_handle, doublets_free_log_handle},
store::{constants_for_store, create_unit_store, delete, free_store},
FFICallbackContext,
};
use std::{
ffi::{c_char, CStr, CString},
fs,
ptr::{null, null_mut},
};

unsafe extern "C" fn callback(_: FFICallbackContext, ptr: *const c_char) {
print!("{}", CStr::from_ptr(ptr).to_str().unwrap());
}

extern "C" fn create_cb(_: FFICallbackContext, _: Link<u64>, _: Link<u64>) -> Flow {
Flow::Continue
}

fn main() {
let level = CString::new("trace").unwrap();
unsafe {
let handle = doublets_create_log_handle(null_mut(), callback, level.as_ptr(), true, false);

let path = CString::new("doublets.links").unwrap();
let mut store =
create_unit_store::<u64>(path.as_ptr(), Constants::from(LinksConstants::external()));

let ptr = store.assume() as *mut _ as *mut _;

let any = constants_for_store::<u64>(ptr).any;

let query = [1 /* not exists index */, any, any];
let result = delete::<u64>(ptr, query.as_ptr(), 3, null_mut(), create_cb);

if result as u8 != DoubletsErrorKind::None as u8 {
let memchr = |buf: &[u8]| buf.iter().position(|x| *x == 0).unwrap();

// last error - DON'T USE PTR AFTER NEW DOUBLETS OPERATION
let err = doublets_read_error();
let mut msg_buf = vec![0u8; 256];

doublets_read_error_message(msg_buf.as_mut_ptr().cast(), 256, err);

msg_buf.drain(memchr(&msg_buf) + 1..);

let cstring = CString::from_vec_with_nul(msg_buf).unwrap();
let str = cstring.to_str().unwrap();
tracing::error!("{}", str);

// forget `err` ptr - we not in manage it deallocation
let not_exists = doublets_read_error_as_not_found(err);
tracing::error!("duplication: link {} does not exists", not_exists);

// forget `err` ptr - we not in manage it deallocation
}

free_store::<u64>(ptr);

doublets_free_log_handle(handle);
}
let _ = fs::remove_file("doublets.links");
}
33 changes: 33 additions & 0 deletions doublets-ffi/examples/rust/examples/log-context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use doublets_ffi::{
export::{doublets_create_log_handle, doublets_free_log_handle},
FFICallbackContext,
};
use std::ffi::{c_char, CStr, CString};

unsafe extern "C" fn callback(ctx: FFICallbackContext, ptr: *const c_char) {
let str = CStr::from_ptr(ptr).to_str().unwrap();
let ctx = &mut *(ctx as *mut usize);
*ctx += 1;

if *ctx % 2 == 0 {
print!("{str}");
} else {
eprint!("{str}");
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference between print and eprint is not noticeable. Use something more different

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More panic!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bro, panic abort my example :(

}

fn main() {
let ctx = &mut 0usize as *mut usize;
let level = CString::new("trace").unwrap();
unsafe {
let handle = doublets_create_log_handle(ctx.cast(), callback, level.as_ptr(), true, false);

tracing::error!("SOMETHING IS SERIOUSLY WRONG!!!");
tracing::warn!("important informational messages; might indicate an error");
tracing::info!("general informational messages relevant to users");
tracing::debug!("diagnostics used for internal debugging of a library or application");
tracing::trace!("very verbose diagnostic events");
Comment on lines +54 to +58
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move logs out unsafe context. It's confusing


doublets_free_log_handle(handle);
}
}
19 changes: 19 additions & 0 deletions doublets-ffi/ffi-attributes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,28 @@ fn csharp_convention(s: String) -> String {
.to_string()
}

fn rust_convention(s: String) -> String {
match s.as_str() {
"i8" => "i8",
"u8" => "u8",
"i16" => "i16",
"u16" => "u16",
"i32" => "i32",
"u32" => "u32",
"i64" => "i64",
"u64" => "u64",
s => {
panic!("{} is incompatible with doublets-ffi type", s)
}
}
.to_string()
}

#[derive(FromMeta, PartialEq, Eq, Debug)]
#[allow(non_camel_case_types)]
enum Conventions {
csharp,
rust,
}

#[derive(FromMeta)]
Expand Down Expand Up @@ -136,6 +154,7 @@ pub fn specialize_for(args: TokenStream, input: TokenStream) -> TokenStream {
'*',
match &args.convention {
Conventions::csharp => csharp_convention(ty.clone()),
Conventions::rust => rust_convention(ty.clone()),
_ => {
panic!("unknown convention")
}
Expand Down
Loading