Giter Club home page Giter Club logo

compio's People

Contributors

asakuramizu avatar bdbai avatar berrysoft avatar bokket avatar clslaid avatar dependabot[bot] avatar dxist avatar george-miao avatar ho-229 avatar kompl3xpr avatar mivik avatar nazar-pc avatar oluceps avatar sherlock-holo avatar ssfdust avatar valpackett avatar xuanwo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

compio's Issues

Consider redesign buffer logic?

Now the write series method only operates with the initialized part of the buffer, and read series method only operates with the uninitialized part. This may lead to some confusement, see #107 .

Do we need redesign to make read series method operate with the whole buffer?

Unsoundness with IOCP driver

On Windows, one file/socket handle could only be attached to one IOCP, and could not be changed through documented APIs. (Yes it could be changed with undocumented API, but don't know ensure the safety.) There are two main issues:

Multi-proactor in one thread

Consider there are two runtime created. A file handle is attached to one runtime but unfortunately used in another runtime:

let r1 = Runtime::new().unwrap();
let r2 = Runtime::new().unwrap();

let file = r1.block_on(async {
    let file = File::open("foo.txt").await.unwrap();
    file.read_at(Vec::with_capacity(1024), 0).await.unwrap();
    file
});

let task = file.read_at(Vec::with_capacity(1024), 0);

r2.block_on(async move {
    poll_once(task).await;
    // The op is submitted to r2 as user_data == 0,
    // but it is executed in IOCP of r1.
    // We cannot wait for its completion because it won't complete until r1 being started.
});

r1.block_on(async move {
    let (_, buffer) = file.read_at([0u8; 1024], 0).await.unwrap(); // The op is submitted to r1 as user_data == 0
    // Which is the correct type of buffer?
});

In this example, an operation is submitted to one proactor, while it will notify another proactor.

Multi-threading send

let file = File::open("foo.txt").await.unwrap();
let file2 = file.try_clone().unwrap();

let file = Unattached::new(file).unwrap();
let file2 = Unattached::new(file2).unwrap();

std::thread::spawn(|| Runtime::new().unwrap().block_on(async move{
    let file = file.into_inner();
    file.read_at(Vec::with_capacity(1024), 0).await.unwrap();
    let (_, buffer) = file.read_at(Vec::with_capacity(1024), 0).await.unwrap();
    // Which is the correct type of buffer?
}));

std::thread::spawn(|| Runtime::new().unwrap().block_on(async move{
    let file2 = file2.into_inner();
    file2.read_at(Vec::with_capacity(1024), 0).await.unwrap();
    let (_, buffer) = file.read_at(Vec::with_capacity(1024), 0).await.unwrap();
    // Which is the correct type of buffer?
}));

In this example, a file handle is duplicated and sent to a different thread. We don't know which runtime will the handle being attached, but anyway that runtime will receive 2 completed notify with user_data == 0.

Solutions?

@bdbai suggests removing the try_clone method, but it will only solve the second issue.

As a dirty solution, we can record a unique id in each proactor and each overlapped struct. If IOCP receives entry with different id, just ignore it.

Another solution is #200 . It creates a global IOCP and a separate thread to run the query loop. There would be overhead to synchornize the threads.

Why not glommio?

You only mentioned tokio in the readme, while the biggest thread per core async executor is actually glommio.

The only thing I can think of is that you support windows.

I there must be a section on that in the readme.

add more async support for File

consider add more async support for File

for now, some File methods are sync, consider make them async:

for now close a File by drop it simply, io-uring also support async close, rust doesn't support async drop yet, so maybe can add a new method async fn close(self) to let user close file asynchronously

Make futures channel work across thread

As you can imagine it will not be uncommon to use anything async other than compio's APIs in a typical application:

fn main() {
    let (tx, rx) = futures::channel::oneshot::channel::<()>();

    std::thread::spawn(move || {
        std::thread::sleep(std::time::Duration::from_millis(100));
        tx.send(()).unwrap();
    });

    compio::runtime::block_on(async move {
        rx.await.unwrap();
    });
}

However, in case of compio unless anything io_uring-related is happening, it just hangs:

#0  syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
#1  0x000055555559f5e7 in io_uring::sys::io_uring_enter (fd=3, to_submit=0, min_complete=1, flags=1, arg=0x0, size=128) at /home/nazar-pc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/io-uring-0.6.2/src/sys/mod.rs:114
#2  0x000055555559f273 in io_uring::submit::Submitter::enter<libc::unix::linux_like::linux::gnu::b64::sigset_t> (self=0x7ffffffeba90, to_submit=0, min_complete=1, flag=1, arg=...) at /home/nazar-pc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/io-uring-0.6.2/src/submit.rs:95
#3  0x000055555559f3b0 in io_uring::submit::Submitter::submit_and_wait (self=0x7ffffffeba90, want=1) at /home/nazar-pc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/io-uring-0.6.2/src/submit.rs:137
#4  0x000055555559d81d in io_uring::IoUring<io_uring::squeue::Entry, io_uring::cqueue::Entry>::submit_and_wait<io_uring::squeue::Entry, io_uring::cqueue::Entry> (self=0x7ffff7f7b730, want=1) at /home/nazar-pc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/io-uring-0.6.2/src/lib.rs:194
#5  0x000055555559bd47 in compio_driver::sys::Driver::submit_auto (self=0x7ffff7f7b730, timeout=..., wait=true) at /home/nazar-pc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/compio-driver-0.1.0/src/iour/mod.rs:54
#6  0x00005555555885e1 in compio_driver::sys::Driver::poll<smallvec::SmallVec<[compio_driver::Entry; 1024]>> (self=0x7ffff7f7b730, timeout=..., entries=0x7ffffffebd68, registry=0x7ffff7f7b880) at /home/nazar-pc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/compio-driver-0.1.0/src/iour/mod.rs:136
#7  0x0000555555592247 in compio_driver::Proactor::poll<smallvec::SmallVec<[compio_driver::Entry; 1024]>> (self=0x7ffff7f7b730, timeout=..., entries=0x7ffffffebd68) at /home/nazar-pc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/compio-driver-0.1.0/src/lib.rs:216
#8  0x0000555555596443 in compio_runtime::runtime::Runtime::poll (self=0x7ffff7f7b728) at /home/nazar-pc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/compio-runtime-0.1.0/src/runtime/mod.rs:151
#9  0x000055555557b75c in compio_runtime::runtime::Runtime::block_on<compio_hang::main::{async_block_env#1}> (self=0x7ffff7f7b728, future=...) at /home/nazar-pc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/compio-runtime-0.1.0/src/runtime/mod.rs:67
#10 0x0000555555585958 in compio_runtime::block_on::{closure#0}<compio_hang::main::{async_block_env#1}> (runtime=0x7ffff7f7b728) at /home/nazar-pc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/compio-runtime-0.1.0/src/lib.rs:40
#11 0x00005555555801f0 in std::thread::local::LocalKey<compio_runtime::runtime::Runtime>::try_with<compio_runtime::runtime::Runtime, compio_runtime::block_on::{closure_env#0}<compio_hang::main::{async_block_env#1}>, ()> (self=0x5555555ed208, f=...) at /rustc/42b1224e9eb37177f608d3f6a6f2be2ee13902e4/library/std/src/thread/local.rs:270
#12 0x00005555555800aa in std::thread::local::LocalKey<compio_runtime::runtime::Runtime>::with<compio_runtime::runtime::Runtime, compio_runtime::block_on::{closure_env#0}<compio_hang::main::{async_block_env#1}>, ()> (self=0x5555555ed208, f=<error reading variable: Cannot access memory at address 0x10>) at /rustc/42b1224e9eb37177f608d3f6a6f2be2ee13902e4/library/std/src/thread/local.rs:246
#13 0x000055555558590c in compio_runtime::block_on<compio_hang::main::{async_block_env#1}> (future=...) at /home/nazar-pc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/compio-runtime-0.1.0/src/lib.rs:40
#14 0x0000555555584ebe in compio_hang::main () at crates/subspace-farmer/examples/compio-hang.rs:9

This is certainly unexpected and I think should be fixed, otherwise it is painful and less performant to combine compio with anything async at all since io_uring is not the only reason async task could be polled. Looks like waker handling is broken/missing right now.

compio casuing rust-analyzer to crash and freeze randomly!?

rust analyzer is crashing even on a simple project after adding compio. I dont know where I should start looking to fix this issue, the rust analyzer errors are very vague. Any help?

env: 
rustc 1.76.0-nightly (a96d57bdb 2023-12-15)
nightly-x86_64-unknown-linux-gnu
rust-analyzer v0.3.1766
[package]
name = "compiotest"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
compio = { version = "0.9.0-beta.3", features = ["runtime", "macros"] }
// src/main.rs
use compio::net::TcpStream;
use compio::io::AsyncWrite;

#[compio::main]
async fn main() {
    let mut sub = TcpStream::connect("127.0.0.1:2222").await.unwrap();
    let vec = Vec::with_capacity(1200);
    let res = sub.write(vec);
}
Panic context:
> 
version: 0.3.1766-standalone
request: textDocument/semanticTokens/full SemanticTokensParams {
    work_done_progress_params: WorkDoneProgressParams {
        work_done_token: None,
    },
    partial_result_params: PartialResultParams {
        partial_result_token: None,
    },
    text_document: TextDocumentIdentifier {
        uri: Url {
            scheme: "file",
            cannot_be_a_base: false,
            username: "",
            password: None,
            host: None,
            port: None,
            path: "/workspaces/compiotest/src/main.rs",
            query: None,
            fragment: None,
        },
    },
}

thread 'Worker' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.95.0/src/lib.rs:2974:1:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
   3: hir_ty::infer::unify::InferenceTable::run_in_snapshot
   4: hir_ty::method_resolution::is_valid_candidate
   5: hir_ty::method_resolution::iterate_trait_method_candidates
   6: hir_ty::method_resolution::iterate_method_candidates_with_autoref::{{closure}}
   7: hir_ty::method_resolution::iterate_method_candidates_dyn
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  15: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
  16: hir_ty::infer::infer_query
  17: salsa::Cycle::catch
  18: salsa::derived::slot::Slot<Q,MP>::execute
  19: salsa::derived::slot::Slot<Q,MP>::read
  20: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  21: hir_ty::db::infer_wait
  22: hir::source_analyzer::SourceAnalyzer::new_for_body
  23: hir::semantics::SemanticsImpl::analyze_impl
  24: ide_db::defs::NameRefClass::classify
  25: ide::syntax_highlighting::highlight::name_like
  26: ide::syntax_highlighting::traverse
  27: ide::syntax_highlighting::highlight
  28: salsa::Cancelled::catch
  29: rust_analyzer::handlers::request::handle_semantic_tokens_full
  30: std::panicking::try
  31: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[Error - 11:50:10 AM] Request textDocument/semanticTokens/full failed.
  Message: request handler panicked: index out of bounds: the len is 0 but the index is 0
  Code: -32603 
Panic context:
> fetch_native_diagnostics

thread 'Worker' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.95.0/src/lib.rs:2974:1:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
   3: hir_ty::infer::unify::InferenceTable::run_in_snapshot
   4: hir_ty::method_resolution::is_valid_candidate
   5: hir_ty::method_resolution::iterate_trait_method_candidates
   6: hir_ty::method_resolution::iterate_method_candidates_with_autoref::{{closure}}
   7: hir_ty::method_resolution::iterate_method_candidates_dyn
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  15: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
  16: hir_ty::infer::infer_query
  17: salsa::Cycle::catch
  18: salsa::derived::slot::Slot<Q,MP>::execute
  19: salsa::derived::slot::Slot<Q,MP>::read
  20: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  21: hir_ty::db::infer_wait
  22: hir::DefWithBody::diagnostics
  23: hir::ModuleDef::diagnostics
  24: hir::Module::diagnostics
  25: ide_diagnostics::diagnostics
  26: salsa::Cancelled::catch
  27: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
  28: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  29: rust_analyzer::diagnostics::fetch_native_diagnostics
  30: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'LspServer' panicked at /__w/rust-analyzer/rust-analyzer/crates/stdx/src/thread/pool.rs:86:35:
called `Result::unwrap()` on an `Err` value: "SendError(..)"
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::result::unwrap_failed
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/result.rs:1652:5
   3: rust_analyzer::task_pool::TaskPool<T>::spawn
   4: rust_analyzer::dispatch::RequestDispatcher::on_with_thread_intent
   5: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::on_request
   6: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::handle_event
   7: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::run
   8: rust_analyzer::main_loop::main_loop
   9: rust_analyzer::run_server
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'main' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/jod-thread-0.1.2/src/lib.rs:33:22:
called `Result::unwrap()` on an `Err` value: Any { .. }
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::result::unwrap_failed
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/result.rs:1652:5
   3: stdx::thread::JoinHandle<T>::join
   4: rust_analyzer::with_extra_thread
   5: rust_analyzer::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[Info  - 11:50:11 AM] Connection to server got closed. Server will restart.
true
Panic context:
> 
version: 0.3.1766-standalone
request: textDocument/semanticTokens/full SemanticTokensParams {
    work_done_progress_params: WorkDoneProgressParams {
        work_done_token: None,
    },
    partial_result_params: PartialResultParams {
        partial_result_token: None,
    },
    text_document: TextDocumentIdentifier {
        uri: Url {
            scheme: "file",
            cannot_be_a_base: false,
            username: "",
            password: None,
            host: None,
            port: None,
            path: "/workspaces/compiotest/src/main.rs",
            query: None,
            fragment: None,
        },
    },
}

thread 'Worker' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.95.0/src/lib.rs:2974:1:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
   3: hir_ty::infer::unify::InferenceTable::run_in_snapshot
   4: hir_ty::method_resolution::is_valid_candidate
   5: hir_ty::method_resolution::iterate_trait_method_candidates
   6: hir_ty::method_resolution::iterate_method_candidates_with_autoref::{{closure}}
   7: hir_ty::method_resolution::iterate_method_candidates_dyn
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  15: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
  16: hir_ty::infer::infer_query
  17: salsa::Cycle::catch
  18: salsa::derived::slot::Slot<Q,MP>::execute
  19: salsa::derived::slot::Slot<Q,MP>::read
  20: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  21: hir_ty::db::infer_wait
  22: hir::source_analyzer::SourceAnalyzer::new_for_body
  23: hir::semantics::SemanticsImpl::analyze_impl
  24: ide_db::defs::NameRefClass::classify
  25: ide::syntax_highlighting::highlight::name_like
  26: ide::syntax_highlighting::traverse
  27: ide::syntax_highlighting::highlight
  28: salsa::Cancelled::catch
  29: rust_analyzer::handlers::request::handle_semantic_tokens_full
  30: std::panicking::try
  31: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[Error - 11:50:19 AM] Request textDocument/semanticTokens/full failed.
  Message: request handler panicked: index out of bounds: the len is 0 but the index is 0
  Code: -32603 
Panic context:
> fetch_native_diagnostics

thread 'Worker' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.95.0/src/lib.rs:2974:1:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
   3: hir_ty::infer::unify::InferenceTable::run_in_snapshot
   4: hir_ty::method_resolution::is_valid_candidate
   5: hir_ty::method_resolution::iterate_trait_method_candidates
   6: hir_ty::method_resolution::iterate_method_candidates_with_autoref::{{closure}}
   7: hir_ty::method_resolution::iterate_method_candidates_dyn
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  15: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
  16: hir_ty::infer::infer_query
  17: salsa::Cycle::catch
  18: salsa::derived::slot::Slot<Q,MP>::execute
  19: salsa::derived::slot::Slot<Q,MP>::read
  20: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  21: hir_ty::db::infer_wait
  22: hir::DefWithBody::diagnostics
  23: hir::ModuleDef::diagnostics
  24: hir::Module::diagnostics
  25: ide_diagnostics::diagnostics
  26: salsa::Cancelled::catch
  27: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
  28: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  29: rust_analyzer::diagnostics::fetch_native_diagnostics
  30: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'LspServer' panicked at /__w/rust-analyzer/rust-analyzer/crates/stdx/src/thread/pool.rs:86:35:
called `Result::unwrap()` on an `Err` value: "SendError(..)"
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::result::unwrap_failed
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/result.rs:1652:5
   3: rust_analyzer::task_pool::TaskPool<T>::spawn
   4: rust_analyzer::dispatch::RequestDispatcher::on_with_thread_intent
   5: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::on_request
   6: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::handle_event
   7: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::run
   8: rust_analyzer::main_loop::main_loop
   9: rust_analyzer::run_server
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'main' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/jod-thread-0.1.2/src/lib.rs:33:22:
called `Result::unwrap()` on an `Err` value: Any { .. }
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::result::unwrap_failed
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/result.rs:1652:5
   3: stdx::thread::JoinHandle<T>::join
   4: rust_analyzer::with_extra_thread
   5: rust_analyzer::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[Info  - 11:50:21 AM] Connection to server got closed. Server will restart.
true
Panic context:
> 
version: 0.3.1766-standalone
request: textDocument/codeAction CodeActionParams {
    text_document: TextDocumentIdentifier {
        uri: Url {
            scheme: "file",
            cannot_be_a_base: false,
            username: "",
            password: None,
            host: None,
            port: None,
            path: "/workspaces/compiotest/src/main.rs",
            query: None,
            fragment: None,
        },
    },
    range: Range {
        start: Position {
            line: 10,
            character: 35,
        },
        end: Position {
            line: 10,
            character: 35,
        },
    },
    context: CodeActionContext {
        diagnostics: [],
        only: None,
        trigger_kind: Some(
            Automatic,
        ),
    },
    work_done_progress_params: WorkDoneProgressParams {
        work_done_token: None,
    },
    partial_result_params: PartialResultParams {
        partial_result_token: None,
    },
}

thread 'Worker' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.95.0/src/lib.rs:2974:1:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
   3: hir_ty::infer::unify::InferenceTable::run_in_snapshot
   4: hir_ty::method_resolution::is_valid_candidate
   5: hir_ty::method_resolution::iterate_trait_method_candidates
   6: hir_ty::method_resolution::iterate_method_candidates_with_autoref::{{closure}}
   7: hir_ty::method_resolution::iterate_method_candidates_dyn
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  15: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
  16: hir_ty::infer::infer_query
  17: salsa::Cycle::catch
  18: salsa::derived::slot::Slot<Q,MP>::execute
  19: salsa::derived::slot::Slot<Q,MP>::read
  20: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  21: hir_ty::db::infer_wait
  22: hir::DefWithBody::diagnostics
  23: hir::ModuleDef::diagnostics
  24: hir::Module::diagnostics
  25: ide_diagnostics::diagnostics
  26: salsa::Cancelled::catch
  27: rust_analyzer::handlers::request::handle_code_action
  28: std::panicking::try
  29: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Panic context:
> 
version: 0.3.1766-standalone
request: textDocument/semanticTokens/full SemanticTokensParams {
    work_done_progress_params: WorkDoneProgressParams {
        work_done_token: None,
    },
    partial_result_params: PartialResultParams {
        partial_result_token: None,
    },
    text_document: TextDocumentIdentifier {
        uri: Url {
            scheme: "file",
            cannot_be_a_base: false,
            username: "",
            password: None,
            host: None,
            port: None,
            path: "/workspaces/compiotest/src/main.rs",
            query: None,
            fragment: None,
        },
    },
}

thread 'Worker' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.95.0/src/lib.rs:2974:1:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
   3: hir_ty::infer::unify::InferenceTable::run_in_snapshot
   4: hir_ty::method_resolution::is_valid_candidate
   5: hir_ty::method_resolution::iterate_trait_method_candidates
   6: hir_ty::method_resolution::iterate_method_candidates_with_autoref::{{closure}}
   7: hir_ty::method_resolution::iterate_method_candidates_dyn
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  15: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
  16: hir_ty::infer::infer_query
  17: salsa::Cycle::catch
  18: salsa::derived::slot::Slot<Q,MP>::execute
  19: salsa::derived::slot::Slot<Q,MP>::read
  20: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  21: hir_ty::db::infer_wait
  22: hir::source_analyzer::SourceAnalyzer::new_for_body
  23: hir::semantics::SemanticsImpl::analyze_impl
  24: ide_db::defs::NameRefClass::classify
  25: ide::syntax_highlighting::highlight::name_like
  26: ide::syntax_highlighting::traverse
  27: ide::syntax_highlighting::highlight
  28: salsa::Cancelled::catch
  29: rust_analyzer::handlers::request::handle_semantic_tokens_full
  30: std::panicking::try
  31: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[Error - 11:50:29 AM] Request textDocument/semanticTokens/full failed.
  Message: request handler panicked: index out of bounds: the len is 0 but the index is 0
  Code: -32603 
Panic context:
> fetch_native_diagnostics

thread 'Worker' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.95.0/src/lib.rs:2974:1:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
   3: hir_ty::infer::unify::InferenceTable::run_in_snapshot
   4: hir_ty::method_resolution::is_valid_candidate
   5: hir_ty::method_resolution::iterate_trait_method_candidates
   6: hir_ty::method_resolution::iterate_method_candidates_with_autoref::{{closure}}
   7: hir_ty::method_resolution::iterate_method_candidates_dyn
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  15: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
  16: hir_ty::infer::infer_query
  17: salsa::Cycle::catch
  18: salsa::derived::slot::Slot<Q,MP>::execute
  19: salsa::derived::slot::Slot<Q,MP>::read
  20: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  21: hir_ty::db::infer_wait
  22: hir::DefWithBody::diagnostics
  23: hir::ModuleDef::diagnostics
  24: hir::Module::diagnostics
  25: ide_diagnostics::diagnostics
  26: salsa::Cancelled::catch
  27: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
  28: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  29: rust_analyzer::diagnostics::fetch_native_diagnostics
  30: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'LspServer' panicked at /__w/rust-analyzer/rust-analyzer/crates/stdx/src/thread/pool.rs:86:35:
called `Result::unwrap()` on an `Err` value: "SendError(..)"
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::result::unwrap_failed
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/result.rs:1652:5
   3: rust_analyzer::task_pool::TaskPool<T>::spawn
   4: rust_analyzer::dispatch::RequestDispatcher::on_with_thread_intent
   5: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::on_request
   6: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::handle_event
   7: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::run
   8: rust_analyzer::main_loop::main_loop
   9: rust_analyzer::run_server
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'main' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/jod-thread-0.1.2/src/lib.rs:33:22:
called `Result::unwrap()` on an `Err` value: Any { .. }
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::result::unwrap_failed
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/result.rs:1652:5
   3: stdx::thread::JoinHandle<T>::join
   4: rust_analyzer::with_extra_thread
   5: rust_analyzer::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[Info  - 11:50:31 AM] Connection to server got closed. Server will restart.
true
Panic context:
> 
version: 0.3.1766-standalone
request: textDocument/codeAction CodeActionParams {
    text_document: TextDocumentIdentifier {
        uri: Url {
            scheme: "file",
            cannot_be_a_base: false,
            username: "",
            password: None,
            host: None,
            port: None,
            path: "/workspaces/compiotest/src/main.rs",
            query: None,
            fragment: None,
        },
    },
    range: Range {
        start: Position {
            line: 10,
            character: 35,
        },
        end: Position {
            line: 10,
            character: 35,
        },
    },
    context: CodeActionContext {
        diagnostics: [],
        only: None,
        trigger_kind: Some(
            Automatic,
        ),
    },
    work_done_progress_params: WorkDoneProgressParams {
        work_done_token: None,
    },
    partial_result_params: PartialResultParams {
        partial_result_token: None,
    },
}

thread 'Worker' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.95.0/src/lib.rs:2974:1:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
   3: hir_ty::infer::unify::InferenceTable::run_in_snapshot
   4: hir_ty::method_resolution::is_valid_candidate
   5: hir_ty::method_resolution::iterate_trait_method_candidates
   6: hir_ty::method_resolution::iterate_method_candidates_with_autoref::{{closure}}
   7: hir_ty::method_resolution::iterate_method_candidates_dyn
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  15: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
  16: hir_ty::infer::infer_query
  17: salsa::Cycle::catch
  18: salsa::derived::slot::Slot<Q,MP>::execute
  19: salsa::derived::slot::Slot<Q,MP>::read
  20: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  21: hir_ty::db::infer_wait
  22: hir::DefWithBody::diagnostics
  23: hir::ModuleDef::diagnostics
  24: hir::Module::diagnostics
  25: ide_diagnostics::diagnostics
  26: salsa::Cancelled::catch
  27: rust_analyzer::handlers::request::handle_code_action
  28: std::panicking::try
  29: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Panic context:
> 
version: 0.3.1766-standalone
request: textDocument/semanticTokens/full SemanticTokensParams {
    work_done_progress_params: WorkDoneProgressParams {
        work_done_token: None,
    },
    partial_result_params: PartialResultParams {
        partial_result_token: None,
    },
    text_document: TextDocumentIdentifier {
        uri: Url {
            scheme: "file",
            cannot_be_a_base: false,
            username: "",
            password: None,
            host: None,
            port: None,
            path: "/workspaces/compiotest/src/main.rs",
            query: None,
            fragment: None,
        },
    },
}

thread 'Worker' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.95.0/src/lib.rs:2974:1:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
   3: hir_ty::infer::unify::InferenceTable::run_in_snapshot
   4: hir_ty::method_resolution::is_valid_candidate
   5: hir_ty::method_resolution::iterate_trait_method_candidates
   6: hir_ty::method_resolution::iterate_method_candidates_with_autoref::{{closure}}
   7: hir_ty::method_resolution::iterate_method_candidates_dyn
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  15: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
  16: hir_ty::infer::infer_query
  17: salsa::Cycle::catch
  18: salsa::derived::slot::Slot<Q,MP>::execute
  19: salsa::derived::slot::Slot<Q,MP>::read
  20: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  21: hir_ty::db::infer_wait
  22: hir::source_analyzer::SourceAnalyzer::new_for_body
  23: hir::semantics::SemanticsImpl::analyze_impl
  24: ide_db::defs::NameRefClass::classify
  25: ide::syntax_highlighting::highlight::name_like
  26: ide::syntax_highlighting::traverse
  27: ide::syntax_highlighting::highlight
  28: salsa::Cancelled::catch
  29: rust_analyzer::handlers::request::handle_semantic_tokens_full
  30: std::panicking::try
  31: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Panic context:
> fetch_native_diagnostics

thread 'Worker' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.95.0/src/lib.rs:2974:1:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
   3: hir_ty::infer::unify::InferenceTable::run_in_snapshot
   4: hir_ty::method_resolution::is_valid_candidate
   5: hir_ty::method_resolution::iterate_trait_method_candidates
   6: hir_ty::method_resolution::iterate_method_candidates_with_autoref::{{closure}}
   7: hir_ty::method_resolution::iterate_method_candidates_dyn
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  15: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
  16: hir_ty::infer::infer_query
  17: salsa::Cycle::catch
  18: salsa::derived::slot::Slot<Q,MP>::execute
  19: salsa::derived::slot::Slot<Q,MP>::read
  20: <salsa::derived::[Error - 11:50:39 AM] Request textDocument/semanticTokens/full failed.
  Message: request handler panicked: index out of bounds: the len is 0 but the index is 0
  Code: -32603 
DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  21: hir_ty::db::infer_wait
  22: hir::DefWithBody::diagnostics
  23: hir::ModuleDef::diagnostics
  24: hir::Module::diagnostics
  25: ide_diagnostics::diagnostics
  26: salsa::Cancelled::catch
  27: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
  28: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  29: rust_analyzer::diagnostics::fetch_native_diagnostics
  30: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'LspServer' panicked at /__w/rust-analyzer/rust-analyzer/crates/stdx/src/thread/pool.rs:86:35:
called `Result::unwrap()` on an `Err` value: "SendError(..)"
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::result::unwrap_failed
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/result.rs:1652:5
   3: rust_analyzer::task_pool::TaskPool<T>::spawn
   4: rust_analyzer::dispatch::RequestDispatcher::on_with_thread_intent
   5: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::on_request
   6: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::handle_event
   7: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::run
   8: rust_analyzer::main_loop::main_loop
   9: rust_analyzer::run_server
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'main' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/jod-thread-0.1.2/src/lib.rs:33:22:
called `Result::unwrap()` on an `Err` value: Any { .. }
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::result::unwrap_failed
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/result.rs:1652:5
   3: stdx::thread::JoinHandle<T>::join
   4: rust_analyzer::with_extra_thread
   5: rust_analyzer::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[Info  - 11:50:41 AM] Connection to server got closed. Server will restart.
true
Panic context:
> 
version: 0.3.1766-standalone
request: textDocument/codeAction CodeActionParams {
    text_document: TextDocumentIdentifier {
        uri: Url {
            scheme: "file",
            cannot_be_a_base: false,
            username: "",
            password: None,
            host: None,
            port: None,
            path: "/workspaces/compiotest/src/main.rs",
            query: None,
            fragment: None,
        },
    },
    range: Range {
        start: Position {
            line: 10,
            character: 35,
        },
        end: Position {
            line: 10,
            character: 35,
        },
    },
    context: CodeActionContext {
        diagnostics: [],
        only: None,
        trigger_kind: Some(
            Automatic,
        ),
    },
    work_done_progress_params: WorkDoneProgressParams {
        work_done_token: None,
    },
    partial_result_params: PartialResultParams {
        partial_result_token: None,
    },
}

thread 'Worker' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.95.0/src/lib.rs:2974:1:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
   3: hir_ty::infer::unify::InferenceTable::run_in_snapshot
   4: hir_ty::method_resolution::is_valid_candidate
   5: hir_ty::method_resolution::iterate_trait_method_candidates
   6: hir_ty::method_resolution::iterate_method_candidates_with_autoref::{{closure}}
   7: hir_ty::method_resolution::iterate_method_candidates_dyn
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  15: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
  16: hir_ty::infer::infer_query
  17: salsa::Cycle::catch
  18: salsa::derived::slot::Slot<Q,MP>::execute
  19: salsa::derived::slot::Slot<Q,MP>::read
  20: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  21: hir_ty::db::infer_wait
  22: hir::DefWithBody::diagnostics
  23: hir::ModuleDef::diagnostics
  24: hir::Module::diagnostics
  25: ide_diagnostics::diagnostics
  26: salsa::Cancelled::catch
  27: rust_analyzer::handlers::request::handle_code_action
  28: std::panicking::try
  29: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Panic context:
> 
version: 0.3.1766-standalone
request: textDocument/semanticTokens/full SemanticTokensParams {
    work_done_progress_params: WorkDoneProgressParams {
        work_done_token: None,
    },
    partial_result_params: PartialResultParams {
        partial_result_token: None,
    },
    text_document: TextDocumentIdentifier {
        uri: Url {
            scheme: "file",
            cannot_be_a_base: false,
            username: "",
            password: None,
            host: None,
            port: None,
            path: "/workspaces/compiotest/src/main.rs",
            query: None,
            fragment: None,
        },
    },
}

thread 'Worker' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.95.0/src/lib.rs:2974:1:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
   3: hir_ty::infer::unify::InferenceTable::run_in_snapshot
   4: hir_ty::method_resolution::is_valid_candidate
   5: hir_ty::method_resolution::iterate_trait_method_candidates
   6: hir_ty::method_resolution::iterate_method_candidates_with_autoref::{{closure}}
   7: hir_ty::method_resolution::iterate_method_candidates_dyn
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  15: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
  16: hir_ty::infer::infer_query
  17: salsa::Cycle::catch
  18: salsa::derived::slot::Slot<Q,MP>::execute
  19: salsa::derived::slot::Slot<Q,MP>::read
  20: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  21: hir_ty::db::infer_wait
  22: hir::source_analyzer::SourceAnalyzer::new_for_body
  23: hir::semantics::SemanticsImpl::analyze_impl
  24: ide_db::defs::NameRefClass::classify
  25: ide::syntax_highlighting::highlight::name_like
  26: ide::syntax_highlighting::traverse
  27: ide::syntax_highlighting::highlight
  28: salsa::Cancelled::catch
  29: rust_analyzer::handlers::request::handle_semantic_tokens_full
  30: std::panicking::try
  31: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Panic context:
> fetch_native_diagnostics

thread 'Worker' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.95.0/src/lib.rs:2974:1:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:180:5
   3: hir_ty::infer::unify::InferenceTable::run_in_snapshot
   4: hir_ty::method_resolution::is_valid_candidate
   5: hir_ty::method_resolution::iterate_trait_method_candidates
   6: hir_ty::method_resolution::iterate_method_candidates_with_autoref::{{closure}}
   7: hir_ty::method_resolution::iterate_method_candidates_dyn
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  15: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
  16: hir_ty::infer::infer_query
  17: salsa::Cycle::catch
  18: salsa::derived::slot::Slot<Q,MP>::execute
  19: salsa::derived::slot::Slot<Q,MP>::read
  20: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  21: hir_ty::db[Error - 11:50:49 AM] Request textDocument/semanticTokens/full failed.
  Message: request handler panicked: index out of bounds: the len is 0 but the index is 0
  Code: -32603 
::infer_wait
  22: hir::DefWithBody::diagnostics
  23: hir::ModuleDef::diagnostics
  24: hir::Module::diagnostics
  25: ide_diagnostics::diagnostics
  26: salsa::Cancelled::catch
  27: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
  28: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  29: rust_analyzer::diagnostics::fetch_native_diagnostics
  30: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'LspServer' panicked at /__w/rust-analyzer/rust-analyzer/crates/stdx/src/thread/pool.rs:86:35:
called `Result::unwrap()` on an `Err` value: "SendError(..)"
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::result::unwrap_failed
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/result.rs:1652:5
   3: rust_analyzer::task_pool::TaskPool<T>::spawn
   4: rust_analyzer::dispatch::RequestDispatcher::on_with_thread_intent
   5: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::on_request
   6: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::handle_event
   7: rust_analyzer::main_loop::<impl rust_analyzer::global_state::GlobalState>::run
   8: rust_analyzer::main_loop::main_loop
   9: rust_analyzer::run_server
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'main' panicked at /github/home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/jod-thread-0.1.2/src/lib.rs:33:22:
called `Result::unwrap()` on an `Err` value: Any { .. }
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::result::unwrap_failed
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/result.rs:1652:5
   3: stdx::thread::JoinHandle<T>::join
   4: rust_analyzer::with_extra_thread
   5: rust_analyzer::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[Error - 11:50:51 AM] The Rust Analyzer Language Server server crashed 5 times in the last 3 minutes. The server will not be restarted. See the output for more information.

[Error] Function Not Found

error[E0599]: no method named `protocol` found for struct `socket2::Socket` in the current scope
   --> src\net\socket.rs:118:25
    |
118 |             self.socket.protocol()?,
    |                         ^^^^^^^^ method not found in `Socket`

For more information about this error, try `rustc --explain E0599`.

Possible unsound in polling driver?

In FileStat, ReadAt, WriteAt, ReadVectoredAt, WriteVectoredAt, Sync, and possibly ShutdownSocket, the operation may perform on wrong fd, if the original fd is closed before the op is executed, and another fd is created with the same descriptor immediately.

Not sure if it will affect IOCP, because it seems that the value of handle will not recycle immediately.

Add a wrapper to initialized area of buffer as uninitialized for `read` methods

This is the first time when I see reading function like read_exact_at filling uninitialized memory. It might be desirable to allocate a fixed sized vector and reuse it for multiple variable sized pieces of data, but current API forces users to re-allocate in that case in order to shrink the capacity of the vector or doing some unsafe stuff or create otherwise unnecessary wrappers around Vec<u8> that will present themselves as having a custom capacity.

Please consider read_exact_at to have the same semantic as monoio or APIs in standard library that are filling contents of the provided buffer that is already used (which take &mut [u8], but the idea is the same).

Regression: cannot find `impl_raw_fd` when runtime feature is disabled

Caused by #27

The old macro was declared in net/mod.rs, which is imported into its submodules no matter what feature enabled. But now it's moved into lib.rs, and imports are only enabled when runtime feature is on. Also, in CI, all tests are conducted with the feature on, which should also be fixed.

Single thread driver queue

The README mentions thread-per-core architecture but driver code uses queue with thread synchronization.

Probably it's better to give users a choice?

I'm personally interested to drive IO from a single thread.

Proposal: Split compio into multiple crates

One thing people dislike about tokio is its cubersome footprint, and hard to use as a dependency when you're writing libraries depend on it, especially when you only need its io traits. I propose we make compio into a futures-like multi crate structure, which for now, consists of:

  • compio-driver
  • compio-runtime
  • compio-macros #77
  • compio-fs
  • compio-buf #72
  • compio-io #71
  • compio-tls (Maybe)
  • compio-http (Maybe)

And finally a big compio crate which (optionally) depend on all of these and use features to control which to re-export.

Adapt to new rustls alpha versions

Currently we're using alpha version of rustls 0.22, which is subject to breaking change at any time. The version of rustls is pin-pointed in #157, but follow up updates are required.

I also hope rustls 0.22 will be released before compio v0.9, see rustls issue. This issue should be kept open until rustls 0.22 is released.

Add general squeue Entry support for io-uring

Add a general operation for io-uring, to add squeue Entry support. It should only be available when io-uring feature enabled. If the fusion driver is enabled, it should panic when io-uring is not supported.

Handle EAGAIN on IO uring submit

io_uring_enter could return EAGAIN on temporal resource shortage.

Driver could handle it and retry submission.

EAGAIN
The kernel was unable to allocate memory for the request, or otherwise ran out of resources to handle it. The application should wait for some completions and try again.

Offtopic: I guess ENXIO
cannot happen because driver doesn't drop IoUring instance.

read_exact sometimes won't do anything

    /// Read the exact number of bytes required to fill the buf.
    async fn read_exact<T: IoBufMut>(&mut self, mut buf: T) -> BufResult<usize, T> {
        loop_read_exact!(buf, buf.buf_capacity() - buf.buf_len(), read, loop self.read(buf.slice(read..)));
    }

after expand the macro, it looks like

let mut read = 0;
let len = (buf.buf_capacity() - buf.buf_len());
while read < len {
        (read, buf) = {
            match ((self.read(buf.slice(read..))).await.into_inner().and_then(|n, b| {
                if n == 0 {
                    use ::std::io::{Error, ErrorKind};
                    (
                        Err(Error::new(
                            ErrorKind::UnexpectedEof,
                            "failed to fill whole buffer",
                        )),
                        b,
                    )
                } else {
                    (Ok(read + n), b)
                }
            })) {
                ::compio_buf::BufResult(Ok(res), buf) => (res, buf),
                ::compio_buf::BufResult(Err(e), buf) => return ::compio_buf::BufResult(Err(e), buf),
            }
        };
    }
return BufResult(Ok(read), buf);

when user pass vec![0; 4] as a IoBuf, let len = (buf.buf_capacity() - buf.buf_len()); will cause len is 0, then do nothing and return directly

Some IO impls are problematic

The impl of AsyncRead is incorrect.

  • Should not implement for String and &str.
  • Should not impl for arrays because they could not be updated.
  • Should update the slice in implementation.

(For newcomers:) more tests and benchmarks

We need more tests and benchmarks. They will help us debug and improve the code quality.

This issue is for newcomers of this project. If you would like to contribute, but don't know which work you can do, you can start with a test or a benchmark. The experience with compio will help you more familiar with the code.

See monoio and tokio-uring for reference of tests.

net bench panic

tcp/tokio               time:   [917.80 µs 943.99 µs 972.57 µs]
Found 3 outliers among 100 measurements (3.00%)
  2 (2.00%) high mild
  1 (1.00%) high severe
Benchmarking tcp/compio: Warming up for 3.0000 sthread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 52, kind: Uncategorized, message: "由于网络上有重名,没有连接。如果加
入域,请转到“控制面板”中的“系统”更改计算机名,然后重试。如果加入工作组,请选择其他工作组名。" }', benches\net.rs:48:65
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

thread 'main' panicked at 'cannot access a Thread Local Storage value during or after destruction: AccessError', /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\std\src\thread\local.rs:246:26  
thread 'main' panicked at 'aborting the process', C:\Users\neet\.cargo\registry\src\mirrors.ustc.edu.cn-61ef6e0cd06fb9b8\async-task-4.4.0\src\utils.rs:17:5
stack backtrace:
   0:     0x7ff656ef210c - std::sys_common::backtrace::_print::impl$0::fmt
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys_common\backtrace.rs:44
   1:     0x7ff656f15d1b - core::fmt::rt::Argument::fmt
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\core\src\fmt\rt.rs:138
   2:     0x7ff656f15d1b - core::fmt::write
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\core\src\fmt\mod.rs:1094
   3:     0x7ff656eec4bf - std::io::Write::write_fmt<std::sys::windows::stdio::Stderr>
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\io\mod.rs:1714
   4:     0x7ff656ef1ebb - std::sys_common::backtrace::_print
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys_common\backtrace.rs:47
   5:     0x7ff656ef1ebb - std::sys_common::backtrace::print
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys_common\backtrace.rs:34
   6:     0x7ff656ef498a - std::panicking::default_hook::closure$1
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\panicking.rs:269
   7:     0x7ff656ef45df - std::panicking::default_hook
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\panicking.rs:288
   8:     0x7ff656ef503e - std::panicking::rust_panic_with_hook
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\panicking.rs:705
   9:     0x7ff656d37779 - crossbeam_queue::seg_queue::SegQueue<T>::pop::h202a01f2630962d0
  10:     0x7ff656d37749 - crossbeam_queue::seg_queue::SegQueue<T>::pop::h202a01f2630962d0
  11:     0x7ff656f203f8 - core::panicking::assert_failed::hf7de5ebfb34e0a52
  12:     0x7ff656d3785e - async_task::utils::abort::hb66b0a56c5f5467a
  13:     0x7ff656d37889 - <async_task::utils::abort_on_panic::Bomb as core::ops::drop::Drop>::drop::h165c1df495236742
  14:     0x7ff656cc1978 - async_task::raw::RawTask<F,T,S,M>::drop_future::h0767c0314ff48410
  15:     0x7ff942db1030 - <unknown>
  16:     0x7ff942db4f5e - is_exception_typeof
  17:     0x7ff942dbf500 - _C_specific_handler
  18:     0x7ff942db416c - is_exception_typeof
  19:     0x7ff942dbfe41 - _CxxFrameHandler3
  20:     0x7ff9534d245f - _chkstk
  21:     0x7ff953460939 - RtlUnwindEx
  22:     0x7ff942dbf9ce - _C_specific_handler
  23:     0x7ff942db2e25 - is_exception_typeof
  24:     0x7ff942db3244 - is_exception_typeof
  25:     0x7ff942db4268 - is_exception_typeof
  26:     0x7ff942dbfe41 - _CxxFrameHandler3
  27:     0x7ff9534d23df - _chkstk
  28:     0x7ff9534814b4 - RtlRaiseException
  29:     0x7ff953481207 - RtlRaiseException
  30:     0x7ff950c3cf19 - RaiseException
  31:     0x7ff942db6720 - CxxThrowException
  32:     0x7ff656f0521e - panic_unwind::real_imp::panic
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\panic_unwind\src\seh.rs:322
  33:     0x7ff656f0521e - panic_unwind::__rust_start_panic
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\panic_unwind\src\lib.rs:103
  34:     0x7ff656ef53e9 - std::panicking::rust_panic
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\panicking.rs:755
  35:     0x7ff656ef5202 - std::panicking::rust_panic_with_hook
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\panicking.rs:727
  36:     0x7ff656ef4f2d - std::panicking::begin_panic_handler::closure$0
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\panicking.rs:597
  37:     0x7ff656ef2d59 - std::sys_common::backtrace::__rust_end_short_backtrace<std::panicking::begin_panic_handler::closure_env$0,never$>
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys_common\backtrace.rs:151
  38:     0x7ff656ef4c30 - std::panicking::begin_panic_handler
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\panicking.rs:593
  39:     0x7ff656f2e3e5 - core::panicking::panic_fmt
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\core\src\panicking.rs:67
  40:     0x7ff656f2e8f3 - core::result::unwrap_failed
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\core\src\result.rs:1651
  41:     0x7ff656cc1952 - async_task::raw::RawTask<F,T,S,M>::drop_future::h0767c0314ff48410
  42:     0x7ff656d0d96c - <alloc::collections::vec_deque::VecDeque<T,A> as core::ops::drop::Drop>::drop::h87e63025e70a03b7
  43:     0x7ff656d1923e - <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::h1680530e2c5b0aeb
  44:     0x7ff656d1b335 - std::sys::common::thread_local::fast_local::Key<T>::try_initialize::hef15d406f4d95345
  45:     0x7ff656f02240 - std::sys::windows::thread_local_dtor::run_keyless_dtors
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\thread_local_dtor.rs:28
  46:     0x7ff656f02470 - std::sys::windows::thread_local_key::on_tls_callback
                               at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\thread_local_key.rs:246
  47:     0x7ff953449a1d - RtlActivateActivationContextUnsafeFast
  48:     0x7ff953449aff - RtlActivateActivationContextUnsafeFast
  49:     0x7ff95348dda5 - LdrShutdownProcess
  50:     0x7ff95348da8d - RtlExitUserProcess
  51:     0x7ff951fce82b - FatalExit
  52:     0x7ff950b305bc - exit
  53:     0x7ff950b3045f - exit
  54:     0x7ff656f1d093 - __scrt_common_main_seh
                               at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:295
  55:     0x7ff951fc7614 - BaseThreadInitThunk
  56:     0x7ff9534826b1 - RtlUserThreadStart
error: bench failed, to rerun pass `--bench net`

Caused by:
  process didn't exit successfully: `E:\rust\compio\target\release\deps\net-bf4587aad27d5461.exe --bench` (exit code: 255)

compio panic with hyper 1.1

root@work:~# rustc -V
rustc 1.76.0-nightly (0e2dac837 2023-12-04)

compio 的代码:  master 分支

panic info

     Running `/dev/shm/cache/release/mesh-server 1`
thread 1
Hello, world!, suggest Ok(18)
RLIMIT_NOFILE Ok((1048576, 1048576)) 
RLIMIT_MEMLOCK Ok((6579408896, 18446744073709551615)) 
Hello, world main 127.0.0.1:9091 
Hello, world main
Hello, world main
thread '<unnamed>' panicked at /root/cobweb/mesh/mesh/3rd/compio/compio-driver/src/lib.rs:354:29:
invalid key
stack backtrace:
   0: std::panicking::begin_panic
             at /rustc/0e2dac8375950a12812ec65868e42b43ed214ef9/library/std/src/panicking.rs:686:12
   1: <slab::Slab<T> as core::ops::index::IndexMut<usize>>::index_mut
             at /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/slab-0.4.9/src/lib.rs:1220:18
   2: <compio_driver::OutEntries<E> as core::iter::traits::collect::Extend<compio_driver::Entry>>::extend::{{closure}}
             at /root/cobweb/mesh/mesh/3rd/compio/compio-driver/src/lib.rs:354:29
   3: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &mut F>::call_once
             at /rustc/0e2dac8375950a12812ec65868e42b43ed214ef9/library/core/src/ops/function.rs:305:13
   4: core::option::Option<T>::map
             at /rustc/0e2dac8375950a12812ec65868e42b43ed214ef9/library/core/src/option.rs:1072:29
   5: <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::next
             at /rustc/0e2dac8375950a12812ec65868e42b43ed214ef9/library/core/src/iter/adapters/map.rs:104:26
   6: <smallvec::SmallVec<A> as core::iter::traits::collect::Extend<<A as smallvec::Array>::Item>>::extend
   7: <compio_driver::OutEntries<E> as core::iter::traits::collect::Extend<compio_driver::Entry>>::extend
             at /root/cobweb/mesh/mesh/3rd/compio/compio-driver/src/lib.rs:353:9
   8: compio_driver::sys::iour::Driver::poll_entries
             at /root/cobweb/mesh/mesh/3rd/compio/compio-driver/src/fusion/../iour/mod.rs:163:9
   9: compio_driver::sys::iour::Driver::poll
             at /root/cobweb/mesh/mesh/3rd/compio/compio-driver/src/fusion/../iour/mod.rs:241:13
  10: compio_driver::sys::Driver::poll
             at /root/cobweb/mesh/mesh/3rd/compio/compio-driver/src/fusion/mod.rs:160:44
  11: compio_driver::Proactor::poll
             at /root/cobweb/mesh/mesh/3rd/compio/compio-driver/src/lib.rs:239:13
  12: compio_runtime::runtime::RuntimeInner::poll
             at /root/cobweb/mesh/mesh/3rd/compio/compio-runtime/src/runtime/mod.rs:203:15
  13: compio_runtime::runtime::RuntimeInner::block_on
             at /root/cobweb/mesh/mesh/3rd/compio/compio-runtime/src/runtime/mod.rs:98:13
  14: compio_runtime::runtime::EnterGuard::block_on
             at /root/cobweb/mesh/mesh/3rd/compio/compio-runtime/src/runtime/mod.rs:450:9
  15: compio_runtime::runtime::Runtime::block_on
             at /root/cobweb/mesh/mesh/3rd/compio/compio-runtime/src/runtime/mod.rs:332:9
  16: mesh_server::main::{{closure}}
             at ./src/main.rs:114:29
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Aborted (core dumped)

test code:

https://github.com/Berrysoft/cyper/blob/update-hyper-with-util/cyper/tests/server/mod.rs

pub async fn new_http_server<F, Fut>(listener: compio::net::TcpListener, func: F) 
where 
    F: Fn(http::Request<Incoming>) -> Fut + Clone + Send + 'static,
    Fut: Future<Output = http::Response<String>> + Send + 'static,
{
    let hyper_builder = hyper_util::server::conn::auto::Builder::new(CompioExecutor);
  
    loop {
        let (client, addr) = listener.accept().await.unwrap();
        if let Err(ret) = hyper_builder.serve_connection(
            HyperStream::new(client),
            hyper::service::service_fn({                
                let func = func.clone();
                move |req| {
                    let fut = func(req);
                    async move { Ok::<_, Infallible>(fut.await) }
                }
            }),
        ).await {
            println!("error = {:?}", ret);
        }
    }
}



async fn serve(req: ::http::Request<Incoming>) -> hyper::Response<String> {
    return hyper::Response::builder()
            .status(hyper::StatusCode::OK)
            .header("Connection", "Close")
            .body("gggsnsfsdf".to_string()).unwrap();
}

async fn run_main() -> anyhow::Result<()> {
    let socket = Socket::new(Domain::IPV4, Type::STREAM, None)?;
    socket.set_nonblocking(true)?;

    #[cfg(unix)]
    {
        socket.set_reuse_address(true)?;
        socket.set_reuse_port(true)?;
    }

    let addr = format!("{}:{}", "127.0.0.1", 9091).parse::<SocketAddrV4>()?;
    println!("Hello, world main {} ", addr);
    socket.bind(&addr.into())?;
    println!("Hello, world main");
    socket.listen(1024)?;

    let socket = compio::net::TcpListener::from_socket2(socket);
    println!("Hello, world main");

    compio_http::new_http_server(socket, serve).await;

    // 换成下面的代码就没有任何问题
    // while let Ok((mut client, addr)) = socket.accept().await {
    //     compio::runtime::spawn(async move {
    //         //println!("Hello, world {}!", addr);

    //         let buffer = Vec::with_capacity(128);
    //         let ret = client.read(buffer).await;
    //         //println!("Hello, world recv {:?}!", ret.0);

    //         let ret = client
    //             .write_all("HTTP/1.1 200 OK\r\nConnection: close\r\n\r\ngggsnsfsdf")
    //             .await;
    //         //println!("Hello, world write {:?}!", ret.0);
    //     })
    //     .detach();
    // }

    Ok(())
}

fn main() {
    let threads_num = std::env::args()
        .nth(1)
        .and_then(|arg| {
            println!("thread {}", arg);
            arg.parse().ok()
        })
        .unwrap_or(4);

    println!(
        "Hello, world!, suggest {:?}",
        std::thread::available_parallelism()
    );

    #[cfg(unix)]
    {
        let ret = utils::raise_fd_limit(libc::RLIMIT_NOFILE, false);
        println!("RLIMIT_NOFILE {:?} ", ret);

        let ret = utils::raise_fd_limit(libc::RLIMIT_MEMLOCK, true);
        println!("RLIMIT_MEMLOCK {:?} ", ret);
    }

    let core_ids = core_affinity::get_core_ids();
    let mut threads = Vec::with_capacity(4);
    let mut cur_id = 0;

    for _ in 0..threads_num {
        cur_id += 2;

        let mut thread_core_id = None;
        if let Some(core_ids) = &core_ids {
            if let Some(core_id) = core_ids.get(cur_id) {
                thread_core_id = Some(*core_id);
            }
        }

        let thread = std::thread::spawn(move || {
            if let Some(thread_core_id) = thread_core_id {
                core_affinity::set_for_current(thread_core_id);
            }

            let mut proactor = compio::driver::ProactorBuilder::new();
            proactor.capacity(4096);

            let mut mutruntime_builder = compio::runtime::RuntimeBuilder::new();
            let runtime = mutruntime_builder.with_proactor(proactor).build().unwrap();
            if let Err(e) = runtime.block_on(run_main()) {
                println!("block error {e}");
            }
        });

        threads.push(thread);
    }

    for thread in threads {
        let _ = thread.join();
    }
}

CQEs processing is not batched?

I might be reading code wrong, but it seems that Driver::Poll makes syscall to fetch next CQEs, which partially negates benefits of using io_uring where multiple submissions and completions all can be handled in just one syscall.

Fix CI

I'm sorry to forget authorize this repo to Azure Pipelines. Now the CI is enabled and we need to fix the errors.

submit might require flushing CQEs

If CQ is full, no more submissions can happen (io_uring_enter returns EBUSY) until CQE are processed to make room in CQ. Currently it doesn't seem to be handled.

Async DNS resolve

We need to use GetAddrInfoExW on Windows and getaddrinfo_a on Linux.

Lazy-attach/re-attach the handles.

Currently the file handles are attached immediately after created. That makes it impossible to write a multi-threading web server: listen in one thread, and spawn the accepted socket to other threads. The solution is:

  • Make it attach lazily. Maybe at the first submission.
  • Make it be aware of thread sending. If the thread id is changed, it should automatically attach itself to the current runtime.

Cargo test fails with the default feature

❯ cargo test
   Compiling compio v0.5.0 (/home/ssfdust/Programming/develop/rust/compio)
error[E0432]: unresolved import `compio::event`
 --> tests/event.rs:1:13
  |
1 | use compio::event::Event;
  |             ^^^^^ could not find `event` in `compio`
                                                                                                                                                            
For more information about this error, try `rustc --explain E0432`.
error: could not compile `compio` (test "event") due to previous error

The event feature seems to the basic feature, how about enabling it on default?

Relax IOBuf lifetime to driver's lifetime

'static lifetime bound for IOBuf is too restrictive and doesn't play nicely with buffers allocated from an arena allocator.

Is it possible to relax it to driver's lifetime? The expectation is that buffer pool lifetime is larger than driver's lifetime.

Multishot opcode support

We need to discuss about the design of drivers if we want multishot opcode support. It's related to all drivers and the runtime.

Consider batching of pop/push operations in Driver::submit

pop from submission queue checks of deque len and push into IO Uring buffer checks whether it's full.

IO_uring allows to push_multiple entries to amortize is_full check. VecDeque is trickier since it could be uncontiguous and doesn't provide range slice interface.

We could optimize the case when squeue.len() <= io_queue.len().

If vecdeque is contiguous, i.e. deque.as_slices returns a pair of empty and nonempty slice. Then we could use a single io_uring::push_multiple with nonempty slice.

When VecDeque is not contiguous we could do 2 push_multiple operations - first with the second slice, because we queue operations from the back and second with the first slice.

After pushing we can clear the deque because we consider squeue.len() <= io_queue.len() case.

I think the latency potential of optimization is much less then the duration of syscall. But with batching we optimize for throughput and the goal is to decrease driver CPU overhead to enable more useful application work with fully utilized CPU core.

It's possible to document this optimization and recommend user to design application in a way that bounds scheduled io_work to the configured number of submission queue entries.

Support of registered file descriptors

IO Uring supports registration of file descriptors. Instead of maintaining reference counts for each IO operation Linux constructs user provided indirection array for each thread.

Registration is beneficial for long lived descriptors. Refcounting overhead is relatively significant for small submit batches.

I'm personally interested in driver-level support of registered file descriptors.

I see the following approaches:

  1. define driver specific operations with registered fds. User either prefers a single platform or writes 2 IO data paths for regular and registered file descriptors. IO Uring could expose tokio-uring Fd or FixedFd, platform independent ops code wraps RawFd into Fd.
  2. define common registration interface. For platforms that don't support registration driver could maintain indirection array in userspace.
    1. separate operations for regular/registered fds, no runtime overhead (branching) at operation construction time, more duplicate code
    2. generic interface with enum and 2 newtype wrappers like in tokio-uring - regular/registered enum, macro enum handling, macro param with implicit type that wraps either regular or registered fd - less duplication, but more complex macro-based code, branching runtime overhead

macOS support?

I see docs are compiled for macOS, but no explicit mention otherwise.

What are your plans and what kind of performance you expect there?

I'm quite happy with monoio, but need Windows support, so compio could be the crate that supports all 3 platforms with excellent performance (about to try how compio compares with monoio) for async file operations.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.