safina 0.7.1

Safe async runtime
Documentation
[![crates.io version](https://img.shields.io/crates/v/safina.svg)](https://crates.io/crates/safina)
[![license: Apache 2.0](https://gitlab.com/leonhard-llc/safina-rs/-/raw/main/license-apache-2.0.svg)](http://www.apache.org/licenses/LICENSE-2.0)
[![unsafe forbidden](https://gitlab.com/leonhard-llc/safina-rs/-/raw/main/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/)
[![pipeline status](https://gitlab.com/leonhard-llc/safina-rs/badges/main/pipeline.svg)](https://gitlab.com/leonhard-llc/safina-rs/-/pipelines)

A safe Rust async runtime.

# Features
- `forbid(unsafe_code)`
- Depends only on `std` at runtime
- Good test coverage (>80%)
- Good performance

# Limitations
- No `fs` module yet.
  [async-fs]https://crates.io/crates/async-fs is a fast async networking library
  that works well with Safina.  It contains some unsafe code.
- The `net` module has poor performance.
  [async-net]https://crates.io/crates/async-net is a fast async networking library
  that works well with Safina.  It contains some unsafe code.

# Benchmark
```
% ulimit -n 100000 && cargo run --release --package bench
          safina   tokio
schedule   554ns   635ns
yield     1150ns   729ns
sleep      814ns   842ns
mutex    14201ns 14768ns
oneshot   2510ns   810ns
channel   2526ns   863ns
tcp_echo 28502ns  8187ns
```
[safina-rs/bench/src/main.rs](https://gitlab.com/leonhard-llc/safina-rs/-/blob/main/bench/src/main.rs)

# Examples
```rust
use std::sync::Arc;
use safina::executor::Executor;

let executor: Arc<Executor> = Arc::default();
let (sender, receiver) = std::sync::mpsc::channel();
executor.spawn(async move {
    sender.send(()).unwrap();
});
receiver.recv().unwrap();
```

```rust
let result = safina::executor::block_on(async {
    prepare_request().await?;
    execute_request().await
})?;
```

# Alternatives
- [smol]https://crates.io/crates/smol
  - Popular
  - Contains some `unsafe` code
- [async-std]https://crates.io/crates/async-std
  - Very popular
  - Contains generous amounts of `unsafe` code
- [futures]https://crates.io/crates/futures
  - Very popular
  - Contains generous amounts of `unsafe` code
- [tokio]https://crates.io/crates/tokio
  - Very popular
  - Fast
  - Internally extremely complicated
  - Full of `unsafe` code
- [bastion]https://crates.io/crates/bastion
  - Generous amounts of `unsafe` code
- [`nostd_async`]https://crates.io/crates/nostd_async

# Cargo Geiger Safety Report
```

Metric output format: x/y
    x = unsafe code used by the build
    y = total unsafe code found in the crate

Symbols:
    🔒  = No `unsafe` usage found, declares #![forbid(unsafe_code)]
    ❓  = No `unsafe` usage found, missing #![forbid(unsafe_code)]
    ☢️  = `unsafe` usage found

Functions  Expressions  Impls  Traits  Methods  Dependency

0/0        0/0          0/0    0/0     0/0      🔒  safina 0.7.1
0/0        0/0          0/0    0/0     0/0      🔒  └── safina-macros 0.1.3
0/0        0/0          0/0    0/0     0/0      🔒      ├── safe-proc-macro2 1.0.95
0/0        0/0          0/0    0/0     0/0      🔒      │   └── unicode-xid 0.2.6
0/0        0/0          0/0    0/0     0/0      🔒      └── safe-quote 1.0.40
0/0        0/0          0/0    0/0     0/0      🔒          └── safe-proc-macro2 1.0.95

0/0        0/0          0/0    0/0     0/0

```
# Changelog
<details>
<summary>Changelog</summary>

- v0.7.1 2025-07-01
   - Add `yield_once()`
- v0.7.0 2025-06-30
   - Require Rust 2024 edition.
   - Add `OptionAb::into_a`, etc.
   - Threadpool queue is now unbounded, removed `TryScheduleError::QueueFull`.
   - `SyncSender` no longer requires `Clone`.
   - After Executor drops, silently discard new tasks and don't panic.
   - Add `Executor::get_thread_executor_weak`.
- v0.6.0 2024-11-02 - Simplify `ExecutorBuilder`.
- v0.5.0 2024-10-27 - Add `ExecutorBuilder` and simplify `Executor` constructors.
- v0.4.1 2024-10-27 - Improve `async_test`:
   - Make `async_test` a default feature so it shows up in docs.rs.
   - Timeout after 5s.
   - Override timeout with `#[async_test(timeout_sec = 1)]`.
   - Support `#[should_panic]` and other test modifier macros.
   - Stop adding `_` to the end of the test name.
- v0.4.0 2024-10-26 - Merge crates into this crate.
   - [safina-async-test]https://crates.io/crates/safina-async-test
   - [safina-async-test-core]https://crates.io/crates/safina-async-test-core
     (to [safina-macros]https://crates.io/crates/safina-macros crate)
   - [safina-executor]https://crates.io/crates/safina-executor
   - [safina-net]https://crates.io/crates/safina-net
   - [safina-select]https://crates.io/crates/safina-select
   - [safina-sync]https://crates.io/crates/safina-sync
   - [safina-threadpool]https://crates.io/crates/safina-threadpool
   - [safina-timer]https://crates.io/crates/safina-timer
- v0.3.3 - Update docs.
- v0.3.2 - Add `threadpool` module.
- v0.3.1
  - Add `sync_channel` and `SyncSender`.
  - Add `Receiver::async_recv` to let users await without writing ugly `(&mut receiver).await`.
  - Remove `Receiver::blocking` and add `try_recv`, `recv`, etc.
- v0.3.0
  - Move structs into sub-modules.
  - Replace `Promise` with `oneshot`, `OneSender`, and `Receiver` that supports async and blocking reads.
  - `schedule_blocking` to return new `sync::Receiver`.
- v0.2.1 - Update docs.
- v0.2.0
  - `Executor::new` and `Executor::with_name` to return `Result`.
  - `ThreadPool::new` to return `Result`.
  - `ThreadPool::try_schedule` to return an error when it fails to restart panicked threads.
  - `ThreadPool::schedule` to handle failure starting replacement threads.
- v0.1.10 - `block_on` functions to take futures that are not `Send`.
- v0.1.9 - Use `once_cell` by default.
- v0.1.8 - Support stable with rust 1.51 and `once_cell`.
- v0.1.7 - Add [safina-net]https://crates.io/crates/safina-net
- v0.1.6 - Use [safina-executor]https://crates.io/crates/safina-executor v0.1.3 API
- v0.1.5 - Add [`safina::sync::Mutex`]https://docs.rs/safina-sync/latest/safina::sync/struct.Mutex.html
- v0.1.4 - Upgrade to new safina-executor version which removes need for `Box::pin`.
- v0.1.3 - Update docs
- v0.1.2 - Renamed `safina` crate to `safina-executor`.
  Added new `safina` crate with re-exports, examples, and integration tests.
- v0.1.1 - Add badges to readme
- v0.1.0 - First published version

</details>

# TO DO
- Add `init` function that makes an executor and starts the timer thread.
- Add an `#[async_main]` macro
- `safina::sync::unbounded_channel()`
- Make [`safina::sync::MutexGuard`] Send.

License: Apache-2.0