mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-19 06:55:18 +01:00
only ever call callbacks once
This commit is contained in:
@@ -3,6 +3,7 @@ use crate::storage::sqlite3_ondisk::WAL_FRAME_HEADER_SIZE;
|
||||
use crate::{BufferPool, CompletionError, Result};
|
||||
use bitflags::bitflags;
|
||||
use cfg_block::cfg_block;
|
||||
use parking_lot::Once;
|
||||
use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::ptr::NonNull;
|
||||
@@ -142,6 +143,8 @@ struct CompletionInner {
|
||||
// Thread safe with OnceLock
|
||||
result: std::sync::OnceLock<Option<CompletionError>>,
|
||||
needs_link: bool,
|
||||
/// before calling callback we check if done is true
|
||||
done: Once,
|
||||
}
|
||||
|
||||
impl Debug for CompletionType {
|
||||
@@ -169,6 +172,7 @@ impl Completion {
|
||||
completion_type,
|
||||
result: OnceLock::new(),
|
||||
needs_link: false,
|
||||
done: Once::new(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -179,6 +183,7 @@ impl Completion {
|
||||
completion_type,
|
||||
result: OnceLock::new(),
|
||||
needs_link: true,
|
||||
done: Once::new(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -258,36 +263,33 @@ impl Completion {
|
||||
|
||||
pub fn complete(&self, result: i32) {
|
||||
let result = Ok(result);
|
||||
match &self.inner.completion_type {
|
||||
CompletionType::Read(r) => r.callback(result),
|
||||
CompletionType::Write(w) => w.callback(result),
|
||||
CompletionType::Sync(s) => s.callback(result), // fix
|
||||
CompletionType::Truncate(t) => t.callback(result),
|
||||
};
|
||||
self.inner
|
||||
.result
|
||||
.set(None)
|
||||
.expect("result must be set only once");
|
||||
self.callback(result);
|
||||
}
|
||||
|
||||
pub fn error(&self, err: CompletionError) {
|
||||
let result = Err(err);
|
||||
match &self.inner.completion_type {
|
||||
CompletionType::Read(r) => r.callback(result),
|
||||
CompletionType::Write(w) => w.callback(result),
|
||||
CompletionType::Sync(s) => s.callback(result), // fix
|
||||
CompletionType::Truncate(t) => t.callback(result),
|
||||
};
|
||||
self.inner
|
||||
.result
|
||||
.set(Some(err))
|
||||
.expect("result must be set only once");
|
||||
self.callback(result);
|
||||
}
|
||||
|
||||
pub fn abort(&self) {
|
||||
self.error(CompletionError::Aborted);
|
||||
}
|
||||
|
||||
fn callback(&self, result: Result<i32, CompletionError>) {
|
||||
self.inner.done.call_once(|| {
|
||||
match &self.inner.completion_type {
|
||||
CompletionType::Read(r) => r.callback(result),
|
||||
CompletionType::Write(w) => w.callback(result),
|
||||
CompletionType::Sync(s) => s.callback(result), // fix
|
||||
CompletionType::Truncate(t) => t.callback(result),
|
||||
};
|
||||
self.inner
|
||||
.result
|
||||
.set(result.err())
|
||||
.expect("result must be set only once");
|
||||
});
|
||||
}
|
||||
|
||||
/// only call this method if you are sure that the completion is
|
||||
/// a ReadCompletion, panics otherwise
|
||||
pub fn as_read(&self) -> &ReadCompletion {
|
||||
|
||||
Reference in New Issue
Block a user