From e21959d80e24b48906a57c1ae573517116a22686 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 17 Sep 2025 11:00:30 +0300 Subject: [PATCH] core/vtab: Use AtomicPtr for table_ptr Make it Send. --- core/vtab.rs | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/core/vtab.rs b/core/vtab.rs index bc3da6d9a..1545150a9 100644 --- a/core/vtab.rs +++ b/core/vtab.rs @@ -6,6 +6,7 @@ use crate::{Connection, LimboError, SymbolTable, Value}; use std::cell::RefCell; use std::ffi::c_void; use std::ptr::NonNull; +use std::sync::atomic::AtomicPtr; use std::sync::Arc; use turso_ext::{ConstraintInfo, IndexInfo, OrderByInfo, ResultCode, VTabKind, VTabModuleImpl}; use turso_parser::{ast, parser::Parser}; @@ -214,10 +215,19 @@ impl VirtualTableCursor { } } -#[derive(Clone, Debug)] +#[derive(Debug)] pub(crate) struct ExtVirtualTable { implementation: Arc, - table_ptr: *const c_void, + table_ptr: AtomicPtr, +} + +impl Clone for ExtVirtualTable { + fn clone(&self) -> Self { + Self { + implementation: self.implementation.clone(), + table_ptr: AtomicPtr::new(self.table_ptr.load(std::sync::atomic::Ordering::Relaxed)), + } + } } impl ExtVirtualTable { @@ -261,7 +271,7 @@ impl ExtVirtualTable { let (schema, table_ptr) = module.implementation.create(args)?; let vtab = ExtVirtualTable { implementation: module.implementation.clone(), - table_ptr, + table_ptr: AtomicPtr::new(table_ptr as *mut c_void), }; Ok((vtab, schema)) } @@ -280,7 +290,10 @@ impl ExtVirtualTable { let ext_conn_ptr = NonNull::new(Box::into_raw(Box::new(conn))).expect("null pointer"); // store the leaked connection pointer on the table so it can be freed on drop let Some(cursor) = NonNull::new(unsafe { - (self.implementation.open)(self.table_ptr, ext_conn_ptr.as_ptr()) as *mut c_void + (self.implementation.open)( + self.table_ptr.load(std::sync::atomic::Ordering::Relaxed) as *const c_void, + ext_conn_ptr.as_ptr(), + ) as *mut c_void }) else { return Err(LimboError::ExtensionError("Open returned null".to_string())); }; @@ -293,7 +306,7 @@ impl ExtVirtualTable { let newrowid = 0i64; let rc = unsafe { (self.implementation.update)( - self.table_ptr, + self.table_ptr.load(std::sync::atomic::Ordering::Relaxed) as *const c_void, arg_count as i32, ext_args.as_ptr(), &newrowid as *const _ as *mut i64, @@ -312,7 +325,11 @@ impl ExtVirtualTable { } fn destroy(&self) -> crate::Result<()> { - let rc = unsafe { (self.implementation.destroy)(self.table_ptr) }; + let rc = unsafe { + (self.implementation.destroy)( + self.table_ptr.load(std::sync::atomic::Ordering::Relaxed) as *const c_void + ) + }; match rc { ResultCode::OK => Ok(()), _ => Err(LimboError::ExtensionError(rc.to_string())),