sqlx (rust): this functionality requires a Tokio context

Recently I started playing around with rust ffi. I’m trying to wrap a small postgres driver and provide a c interop interface. I’m using the sqlx pg driver under the hood.

I’m having the following piece of code.

static mut SQLX4K: OnceLock<Sqlx4k> = OnceLock::new();

#[derive(Debug)]
struct Sqlx4k<'a> {
    runtime: Runtime,
    pool: PgPool,
    tx_id: RwLock<Vec<u8>>,
    tx: &'a mut [*mut Transaction<'a, Postgres>],
}

impl<'a> Sqlx4k<'a> {
    fn tx_begin(&mut self) -> i64 {
        let tx = self.runtime.block_on(self.pool.begin()).unwrap();
        let id = { self.tx_id.write().unwrap().pop().unwrap() };
        let tx = Box::new(tx);
        let tx = Box::leak(tx);
        self.tx[id as usize] = tx;
        id.into()
    }

    fn tx_commit(&mut self, tx: i64) {
        let id = tx;
        let tx = unsafe { *Box::from_raw(self.tx[id as usize]) };
        self.tx[id as usize] = null_mut();
        self.runtime.block_on(tx.commit()).unwrap();
        self.tx_id.write().unwrap().push(id as u8)
    }

    fn tx_rollback(&mut self, tx: i64) {
        let id = tx;
        let tx = unsafe { *Box::from_raw(self.tx[id as usize]) };
        self.tx[id as usize] = null_mut();
        self.runtime.block_on(tx.rollback()).unwrap();
        self.tx_id.write().unwrap().push(id as u8)
    }

    fn tx_query(&mut self, tx: i64, sql: &str) {
        let id = tx;
        unsafe {
            let mut tx = Box::from_raw(self.tx[id as usize]);
            let query = tx.fetch_optional(sql);
            let _result = self.runtime.block_on(query);
        };
    }
}

The main concept is that I have a static memory space that I store all the necessary parts of the custom wrapper driver.

Then I expose a C function like:

#[no_mangle]
pub extern "C" fn sqlx4k_tx_begin() -> c_long {
    unsafe { SQLX4K.get_mut().unwrap() }.tx_begin().into()
}

#[no_mangle]
pub extern "C" fn sqlx4k_tx_commit(tx: c_long) {
    unsafe { SQLX4K.get_mut().unwrap() }.tx_commit(tx);
}

#[no_mangle]
pub extern "C" fn sqlx4k_tx_rollback(tx: c_long) {
    unsafe { SQLX4K.get_mut().unwrap() }.tx_rollback(tx);
}

#[no_mangle]
pub extern "C" fn sqlx4k_tx_query(tx: c_long, sql: *const c_char) -> *mut Sqlx4kResult {
    let sql = c_chars_to_str(sql).unwrap();
    unsafe { SQLX4K.get_mut().unwrap() }.tx_query(tx, sql);
    ok()
}

My main goal is to support transactions.
So for this particular reason I decided to create a mutable slice and store all the generated transactions. Also, for each transaction I have an id that I return to the C code as a reference.

The problem is that each time I call the tx_query method I get this functionality requires a Tokio context error

Also my Cargo.toml:

[dependencies]
once_cell = { version = "1.19.0" }
tokio = { version = "1.38.0", features = ["full"] }
sqlx = { version = "0.7.4", features = [
    "runtime-tokio", # Use the tokio runtime without enabling a TLS backend.
    "postgres",      # Add support for the Postgres database server.
] }

Here is the backtrace:

thread '<unnamed>' panicked at /Users/smyrgeorge/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sqlx-core-0.7.4/src/pool/connection.rs:169:13:
this functionality requires a Tokio context
stack backtrace:
   0:        0x101065ff4 - std::backtrace_rs::backtrace::libunwind::trace::h6de1cbf3f672a4f8
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/../../backtrace/src/backtrace/libunwind.rs:105:5
   1:        0x101065ff4 - std::backtrace_rs::backtrace::trace_unsynchronized::hd0de2d5ef13b6f4d
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:        0x101065ff4 - std::sys_common::backtrace::_print_fmt::h2a33510d9b3bb866
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/sys_common/backtrace.rs:68:5
   3:        0x101065ff4 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h01b2beffade888b2
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/sys_common/backtrace.rs:44:22
   4:        0x10100048c - core::fmt::rt::Argument::fmt::h5ddc0f22b2928899
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/core/src/fmt/rt.rs:142:9
   5:        0x10100048c - core::fmt::write::hbadb443a71b75f23
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/core/src/fmt/mod.rs:1153:17
   6:        0x10104988c - std::io::Write::write_fmt::hc09d7755e3ead5f0
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/io/mod.rs:1843:15
   7:        0x101069a48 - std::sys_common::backtrace::_print::h3cd1786cbb1caf0f
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/sys_common/backtrace.rs:47:5
   8:        0x101069a48 - std::sys_common::backtrace::print::h28349e5c25acbac7
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/sys_common/backtrace.rs:34:9
   9:        0x101069394 - std::panicking::default_hook::{{closure}}::hd24b6196784d991e
  10:        0x101068f60 - std::panicking::default_hook::hfcec80a2720c8c73
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:292:9
  11:        0x10106a2a4 - std::panicking::rust_panic_with_hook::h84760468187ddc85
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:779:13
  12:        0x101069d20 - std::panicking::begin_panic_handler::{{closure}}::he666a5eb600a7203
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:649:13
  13:        0x101069cb0 - std::sys_common::backtrace::__rust_end_short_backtrace::h592f44d2bf9f843f
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/sys_common/backtrace.rs:171:18
  14:        0x101069ca4 - rust_begin_unwind
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:645:5
  15:        0x1010849b4 - core::panicking::panic_fmt::h98bbf7bdf4994454
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/core/src/panicking.rs:72:14
  16:        0x101033624 - sqlx_core::rt::missing_rt::hd58e9fd585cd27b3
  17:        0x1010474e8 - <sqlx_core::pool::connection::PoolConnection<DB> as core::ops::drop::Drop>::drop::hbaea548330ec54f2
  18:        0x1010142f8 - core::ptr::drop_in_place<alloc::boxed::Box<sqlx_core::transaction::Transaction<sqlx_postgres::database::Postgres>>>::h65e711f5dba2104f
  19:        0x101014498 - _sqlx4k_tx_fetch_all
  20:        0x100fd7ea0 - kfun:#main(){}
                               at /Users/smyrgeorge/dev/projects/test/sqlx4k/src/nativeMain/kotlin/Main.kt:59:5
  21:        0x100ff8040 - _Init_and_run_start
  22:        0x100ff820c - _main

The strange is that the tx_commit and tx_rollback function work ok.

What is the origin of the problem.

Also I have to mention that I started this project just to obtain experience in rust ffi.
So, there is a lot of unsafe code.

I also have an implementation that makes use of a HashMap (to store the transactions).
But, i just wanted to try something another approach (with less locks)

PS: I understand that may be some memory issues in this piece of code. I’m just trying to understand what is happening

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật