1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
//! [![crates.io version](https://img.shields.io/crates/v/safina-sync.svg)](https://crates.io/crates/safina-sync) //! [![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) //! //! Structs for sharing or sending data between async tasks. //! //! It is part of [`safina`](https://crates.io/crates/safina), a safe async runtime. //! //! # Features //! - [`safina_sync::Mutex`](https://docs.rs/safina-sync/0.1.4/safina_sync/struct.Mutex.html) //! has an async lock method //! - [`safina_sync::Promise`](https://docs.rs/safina-sync/0.1.4/safina_sync/struct.Promise.html) //! is a one-shot channel which you can await //! - `forbid(unsafe_code)` //! - Depends only on `std` //! - 100% test coverage //! - Works with [`safina-executor`](https://crates.io/crates/safina-executor) or any async executor //! //! # Limitations //! - Allocates //! - No const constructor. //! Uses `std::sync::Mutex` internally, which does not have a const constructor. //! See [rust#66806](https://github.com/rust-lang/rust/issues/66806) //! and [const-eval#3](https://github.com/rust-lang/const-eval/issues/3). //! You can work around this with unstable //! [`core::lazy::OnceCell`](https://doc.rust-lang.org/core/lazy/struct.OnceCell.html) //! or various `unsafe` crates: //! [`lazy_static`](https://crates.io/crates/lazy_static), //! [`once_cell`](https://crates.io/crates/once_cell), //! [`lazycell`](https://crates.io/crates/lazycell), and //! [`conquer-once`](https://crates.io/crates/conquer-once). //! //! # Documentation //! <https://docs.rs/safina-sync> //! //! # Examples //! ```rust //! use std::sync::Arc; //! use safina_async_test::async_test; //! use safina_sync::Mutex; //! # async fn some_async_fn() {} //! # fn get_shared_data() -> Arc<Mutex<u32>> { //! # Arc::new(Mutex::new(0)) //! # } //! # #[async_test] //! # async fn test1() { //! # let addr = String::new(); //! let shared_counter: Arc<Mutex<u32>> = get_shared_data(); //! { //! let mut counter_guard = shared_counter.lock().await; //! *counter_guard += 1; //! // some_async_fn().await; // Cannot await while holding a MutexGuard. //! } //! some_async_fn().await; // Await is ok after releasing MutexGuard. //! # } //! ``` //! //! # Alternatives //! - [async-lock](https://crates.io/crates/async-lock) //! - Contains a little `unsafe` code //! - [futures-locks](https://crates.io/crates/futures-locks) //! - Contains a little `unsafe` code //! - [futures-util](https://crates.io/crates/futures-util) //! - Very popular //! - Full of `unsafe` //! - [tokio-sync](https://crates.io/crates/tokio-sync) //! - Very popular //! - Fast //! - Internally incredibly complicated //! - Full of `unsafe` //! //! # Changelog //! - v0.1.5 - Update docs //! - v0.1.4 - Update docs, make `MutexGuard::new` non-public //! - v0.1.3 - Fix Promise type parameter //! - v0.1.2 - Add Promise //! - v0.1.1 - Improve Mutex performance when there are many waiters //! - v0.1.0 - First published version //! //! # TO DO //! - DONE - Implement `Mutex` with tests & docs //! - DONE - Publish on crates.io //! - DONE - Add `Promise` //! - Add `Barrier` //! - Add `RwLock` //! - Add `WaitableBool` //! - Add `Channel` (single receiver) //! - Add `UnboundedChannel` //! - Add `WaitableQueue` (multiple receivers) //! - Add `UnboundedWaitableQueue` //! - Add `Topic` (copies message to every receiver) //! //! # Release Process //! 1. Edit `Cargo.toml` and bump version number. //! 1. Run `./release.sh` #![forbid(unsafe_code)] mod mutex; pub use mutex::*; mod promise; pub use promise::*;