| Crates.io | prism3-concurrent |
| lib.rs | prism3-concurrent |
| version | 0.1.1 |
| created_at | 2025-10-14 06:46:05.978717+00 |
| updated_at | 2025-10-14 07:29:03.823613+00 |
| description | Concurrent utilities library providing thread pools, task scheduling, synchronization primitives and other concurrent programming tools |
| homepage | https://github.com/3-prism/prism3-rust-concurrent |
| repository | https://github.com/3-prism/prism3-rust-concurrent |
| max_upload_size | |
| id | 1881760 |
| size | 78,064 |
A comprehensive Rust concurrent utilities library providing thread-safe lock wrappers and synchronization primitives for the Prism3 ecosystem.
Prism3 Concurrent provides easy-to-use wrappers around both synchronous and asynchronous locks, offering a unified interface for concurrent programming in Rust. All lock types have Arc built-in internally, so you can clone and share them across threads or tasks directly without additional wrapping. The library provides convenient helper methods for common locking patterns with a closure-based API that ensures proper lock management.
Arc integrationwith_lock and try_with_lock methods for cleaner lock handlingClone for easy sharing across threadsAdd this to your Cargo.toml:
[dependencies]
prism3-concurrent = "0.1.0"
use prism3_concurrent::ArcMutex;
use std::thread;
fn main() {
let counter = ArcMutex::new(0);
let mut handles = vec![];
// Spawn multiple threads that increment the counter
for _ in 0..10 {
let counter = counter.clone();
let handle = thread::spawn(move || {
counter.with_lock(|value| {
*value += 1;
});
});
handles.push(handle);
}
// Wait for all threads
for handle in handles {
handle.join().unwrap();
}
// Read final value
let result = counter.with_lock(|value| *value);
println!("Final counter: {}", result); // Prints: Final counter: 10
}
use prism3_concurrent::ArcRwLock;
fn main() {
let data = ArcRwLock::new(vec![1, 2, 3]);
// Multiple concurrent reads
let data1 = data.clone();
let data2 = data.clone();
let handle1 = std::thread::spawn(move || {
let len = data1.with_read_lock(|v| v.len());
println!("Length from thread 1: {}", len);
});
let handle2 = std::thread::spawn(move || {
let len = data2.with_read_lock(|v| v.len());
println!("Length from thread 2: {}", len);
});
// Exclusive write access
data.with_write_lock(|v| {
v.push(4);
println!("Added element, new length: {}", v.len());
});
handle1.join().unwrap();
handle2.join().unwrap();
}
use prism3_concurrent::ArcAsyncMutex;
#[tokio::main]
async fn main() {
let counter = ArcAsyncMutex::new(0);
let mut handles = vec![];
// Spawn multiple async tasks
for _ in 0..10 {
let counter = counter.clone();
let handle = tokio::spawn(async move {
counter.with_lock(|value| {
*value += 1;
}).await;
});
handles.push(handle);
}
// Wait for all tasks
for handle in handles {
handle.await.unwrap();
}
// Read final value
let result = counter.with_lock(|value| *value).await;
println!("Final counter: {}", result); // Prints: Final counter: 10
}
use prism3_concurrent::ArcAsyncRwLock;
#[tokio::main]
async fn main() {
let data = ArcAsyncRwLock::new(String::from("Hello"));
// Concurrent async reads
let data1 = data.clone();
let data2 = data.clone();
let handle1 = tokio::spawn(async move {
let content = data1.with_read_lock(|s| s.clone()).await;
println!("Read from task 1: {}", content);
});
let handle2 = tokio::spawn(async move {
let content = data2.with_read_lock(|s| s.clone()).await;
println!("Read from task 2: {}", content);
});
// Exclusive async write
data.with_write_lock(|s| {
s.push_str(" World!");
println!("Updated string: {}", s);
}).await;
handle1.await.unwrap();
handle2.await.unwrap();
}
use prism3_concurrent::ArcMutex;
fn main() {
let mutex = ArcMutex::new(42);
// Try to acquire lock without blocking
match mutex.try_with_lock(|value| *value) {
Some(v) => println!("Got value: {}", v),
None => println!("Lock is busy"),
}
}
A synchronous mutual exclusion lock wrapper with Arc integration.
Methods:
new(data: T) -> Self - Create a new mutexwith_lock<F, R>(&self, f: F) -> R - Acquire lock and execute closuretry_with_lock<F, R>(&self, f: F) -> Option<R> - Try to acquire lock without blockingclone(&self) -> Self - Clone the Arc referenceA synchronous read-write lock wrapper supporting multiple concurrent readers.
Methods:
new(data: T) -> Self - Create a new read-write lockwith_read_lock<F, R>(&self, f: F) -> R - Acquire read lockwith_write_lock<F, R>(&self, f: F) -> R - Acquire write lockclone(&self) -> Self - Clone the Arc referenceAn asynchronous mutual exclusion lock for Tokio runtime.
Methods:
new(data: T) -> Self - Create a new async mutexasync with_lock<F, R>(&self, f: F) -> R - Asynchronously acquire locktry_with_lock<F, R>(&self, f: F) -> Option<R> - Try to acquire lock (non-blocking)clone(&self) -> Self - Clone the Arc referenceAn asynchronous read-write lock for Tokio runtime.
Methods:
new(data: T) -> Self - Create a new async read-write lockasync with_read_lock<F, R>(&self, f: F) -> R - Asynchronously acquire read lockasync with_write_lock<F, R>(&self, f: F) -> R - Asynchronously acquire write lockclone(&self) -> Self - Clone the Arc referenceAll locks use closure-based access patterns for several benefits:
Important: All ArcMutex, ArcRwLock, ArcAsyncMutex, and ArcAsyncRwLock types already have Arc integrated internally. You don't need to wrap them with Arc again.
// β
Correct - use directly
let lock = ArcMutex::new(0);
let lock_clone = lock.clone(); // Clones the internal Arc
// β Wrong - unnecessary double wrapping
let lock = Arc::new(ArcMutex::new(0)); // Don't do this!
This design provides several benefits:
.clone()Arc allocationPerfect for maintaining shared state across multiple threads:
let counter = ArcMutex::new(0);
// Share counter across threads
let counter_clone = counter.clone();
thread::spawn(move || {
counter_clone.with_lock(|c| *c += 1);
});
Read-write locks are ideal for configuration that's read frequently but written rarely:
let config = ArcRwLock::new(Config::default());
// Many readers
config.with_read_lock(|cfg| println!("Port: {}", cfg.port));
// Occasional writer
config.with_write_lock(|cfg| cfg.port = 8080);
Coordinate state between async tasks without blocking threads:
let state = ArcAsyncMutex::new(TaskState::Idle);
let state_clone = state.clone();
tokio::spawn(async move {
state_clone.with_lock(|s| *s = TaskState::Running).await;
// ... do work ...
state_clone.with_lock(|s| *s = TaskState::Complete).await;
});
sync)Mutex, RwLock, Arc)This project maintains comprehensive test coverage with detailed validation of all functionality.
Current test coverage statistics:
| Module | Region Coverage | Line Coverage | Function Coverage |
|---|---|---|---|
| lock.rs | 100.00% | 100.00% | 100.00% |
| Total | 100.00% | 100.00% | 100.00% |
The test suite covers:
# Run all tests
cargo test
# Run with coverage report
./coverage.sh
# Generate text format report
./coverage.sh text
# Generate detailed HTML report
./coverage.sh html
The coverage statistics are generated using cargo-llvm-cov. For more details on how to run coverage tests and interpret results, see:
target/llvm-cov/html/ArcMutex, ArcRwLock): Use for CPU-bound operations or when already in a thread-based contextArcAsyncMutex, ArcAsyncRwLock): Use within async contexts to avoid blocking the executorRead-write locks (ArcRwLock, ArcAsyncRwLock) are beneficial when:
For simple, fast operations or equal read/write patterns, regular mutexes may be simpler and faster.
Copyright (c) 2025 3-Prism Co. Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
See LICENSE for the full license text.
Contributions are welcome! Please feel free to submit a Pull Request.
When contributing tests, ensure:
Hu Haixing - 3-Prism Co. Ltd.
For more information about the Prism3 ecosystem, visit our GitHub homepage.