aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2020-07-08 12:08:26 +0200
committerRobin Krahl <robin.krahl@ireas.org>2020-07-08 23:02:49 +0200
commit98232c7bc262dd3902b8f3e299196ab9c83fb355 (patch)
tree0f2a1ce830abf2378e78c7c74016f774f46fac7e
parentcf460cbb5e616d12f5e6b1f64acddf3ec0e7b087 (diff)
downloadnitrokey-rs-98232c7bc262dd3902b8f3e299196ab9c83fb355.tar.gz
nitrokey-rs-98232c7bc262dd3902b8f3e299196ab9c83fb355.tar.bz2
Remove sync::PoisonError from Error::PoisonError
Previously, the Error::PoisonError contained the sync::PoisonError that caused the error. This is problematic as sync::PoisonError does not implement Send, making it impossible to use the Error enum with the anyhow crate. At the same time, storing the sync::PoisonError is not very useful. If a user wants to access the poisoned lock, they can call the force_take function. Therefore we remove the sync::PoisonError value from the Error:: PoisonError variant. This also allows us to simplify the From<sync::PoisonError<…>> and From<sync::TryLockError<…>> implementations as we no longer need to know the type of the mutex that caused the error. For more information, see this thread: https://lists.sr.ht/~ireas/nitrokey-rs-dev/%3C68ed0f3f-d98f-63bc-04d2-81b6d6cde560%40posteo.net%3E
-rw-r--r--CHANGELOG.md4
-rw-r--r--src/error.rs16
-rw-r--r--src/lib.rs11
3 files changed, 16 insertions, 15 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e2dd8a7..dddccb1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,10 @@ Copyright (C) 2019-2020 Robin Krahl <robin.krahl@ireas.org>
SPDX-License-Identifier: CC0-1.0
-->
+# Unreleased
+- Refactor the `Error` enum so that it is `Send`, `Sync` and `'static`:
+ - Remove the `sync::PoisonError` from the `PoisonError` variant.
+
# v0.6.0 (2020-02-03)
- Add `String` value to the `Error::UnexpectedError` variant.
- Always store serial numbers as structs:
diff --git a/src/error.rs b/src/error.rs
index 7bea3f2..e0698a2 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -21,7 +21,7 @@ pub enum Error {
/// A library usage error.
LibraryError(LibraryError),
/// An error that occurred due to a poisoned lock.
- PoisonError(sync::PoisonError<sync::MutexGuard<'static, crate::Manager>>),
+ PoisonError,
/// An error that occurred during random number generation.
RandError(Box<dyn error::Error>),
/// An error that is caused by an unexpected value returned by libnitrokey.
@@ -72,14 +72,14 @@ impl From<str::Utf8Error> for Error {
}
}
-impl From<sync::PoisonError<sync::MutexGuard<'static, crate::Manager>>> for Error {
- fn from(error: sync::PoisonError<sync::MutexGuard<'static, crate::Manager>>) -> Self {
- Error::PoisonError(error)
+impl<T> From<sync::PoisonError<T>> for Error {
+ fn from(_error: sync::PoisonError<T>) -> Self {
+ Error::PoisonError
}
}
-impl From<sync::TryLockError<sync::MutexGuard<'static, crate::Manager>>> for Error {
- fn from(error: sync::TryLockError<sync::MutexGuard<'static, crate::Manager>>) -> Self {
+impl<T> From<sync::TryLockError<T>> for Error {
+ fn from(error: sync::TryLockError<T>) -> Self {
match error {
sync::TryLockError::Poisoned(err) => err.into(),
sync::TryLockError::WouldBlock => Error::ConcurrentAccessError,
@@ -100,7 +100,7 @@ impl error::Error for Error {
Error::CommunicationError(ref err) => Some(err),
Error::ConcurrentAccessError => None,
Error::LibraryError(ref err) => Some(err),
- Error::PoisonError(ref err) => Some(err),
+ Error::PoisonError => None,
Error::RandError(ref err) => Some(err.as_ref()),
Error::UnexpectedError(_) => None,
Error::UnknownError(_) => None,
@@ -117,7 +117,7 @@ impl fmt::Display for Error {
Error::CommunicationError(ref err) => write!(f, "Communication error: {}", err),
Error::ConcurrentAccessError => write!(f, "Internal error: concurrent access"),
Error::LibraryError(ref err) => write!(f, "Library error: {}", err),
- Error::PoisonError(_) => write!(f, "Internal error: poisoned lock"),
+ Error::PoisonError => write!(f, "Internal error: poisoned lock"),
Error::RandError(ref err) => write!(f, "RNG error: {}", err),
Error::UnexpectedError(ref s) => write!(f, "An unexpected error occurred: {}", s),
Error::UnknownError(ref err) => write!(f, "Unknown error: {}", err),
diff --git a/src/lib.rs b/src/lib.rs
index 3fa3ae3..5b72d63 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -470,13 +470,10 @@ pub fn take() -> Result<sync::MutexGuard<'static, Manager>, Error> {
/// [`ConcurrentAccessError`]: struct.Error.html#variant.ConcurrentAccessError
/// [`Manager`]: struct.Manager.html
pub fn force_take() -> Result<sync::MutexGuard<'static, Manager>, Error> {
- match take() {
- Ok(guard) => Ok(guard),
- Err(err) => match err {
- Error::PoisonError(err) => Ok(err.into_inner()),
- err => Err(err),
- },
- }
+ MANAGER.try_lock().or_else(|err| match err {
+ sync::TryLockError::Poisoned(err) => Ok(err.into_inner()),
+ sync::TryLockError::WouldBlock => Err(Error::ConcurrentAccessError),
+ })
}
/// List all connected Nitrokey devices.