Skip to content

Commit

Permalink
feat: implement Send for Scanner and some related types.
Browse files Browse the repository at this point in the history
  • Loading branch information
plusvic committed Oct 21, 2024
1 parent 1b7fc5a commit 7576f30
Showing 1 changed file with 29 additions and 0 deletions.
29 changes: 29 additions & 0 deletions lib/src/scanner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,23 @@ pub struct Scanner<'r> {
timeout: Option<Duration>,
}

/// `Scanner` implements [`Send`] but does not implement [`Sync`]. This means
/// that transferring ownership of a `Scanner` between threads is safe, but
/// accessing a `Scanner` from multiple threads concurrently is not.
///
/// Note that `&Scanner` (a shared reference) is not [`Send`] because allowing
/// multiple threads to hold a reference to the same `Scanner` would be unsafe,
/// as `Scanner` does not implement [`Sync`]. Without `Sync`, it is not
/// guaranteed that shared access to the `Scanner` is thread-safe.
///
/// The reason `Scanner` does not automatically implement [`Send`] is due to the
/// underlying [`ScanContext`] type, which contains some [`Rc`] instances. Since
/// [`Rc`] is not thread-safe, `ScanContext` cannot be used safely by multiple
/// threads. However, these non-thread-safe references are confined within the
/// scanner and cannot be cloned or accessed from multiple threads at the same
/// time.
unsafe impl Send for Scanner<'_> {}

impl<'r> Scanner<'r> {
const DEFAULT_SCAN_TIMEOUT: u64 = 315_360_000;

Expand Down Expand Up @@ -867,6 +884,9 @@ pub struct ScanResults<'a, 'r> {
data: ScannedData<'a>,
}

/// See the implementation of [`Send`] for [`Scanner`].
unsafe impl Send for ScanResults<'_, '_> {}

impl<'a, 'r> ScanResults<'a, 'r> {
fn new(ctx: &'a ScanContext<'r>, data: ScannedData<'a>) -> Self {
Self { ctx, data }
Expand Down Expand Up @@ -917,6 +937,9 @@ pub struct MatchingRules<'a, 'r> {
iterator: Iter<'a, RuleId>,
}

/// See the implementation of [`Send`] for [`Scanner`].
unsafe impl Send for MatchingRules<'_, '_> {}

impl<'a, 'r> MatchingRules<'a, 'r> {
fn new(ctx: &'a ScanContext<'r>, data: &'a ScannedData<'a>) -> Self {
Self { ctx, data, iterator: ctx.non_private_matching_rules.iter() }
Expand Down Expand Up @@ -954,6 +977,9 @@ pub struct NonMatchingRules<'a, 'r> {
len: usize,
}

/// See the implementation of [`Send`] for [`Scanner`].
unsafe impl Send for NonMatchingRules<'_, '_> {}

impl<'a, 'r> NonMatchingRules<'a, 'r> {
fn new(ctx: &'a ScanContext<'r>, data: &'a ScannedData<'a>) -> Self {
let num_rules = ctx.compiled_rules.num_rules();
Expand Down Expand Up @@ -1024,6 +1050,9 @@ pub struct ModuleOutputs<'a, 'r> {
iterator: hash_map::Iter<'a, &'a str, Module>,
}

/// See the implementation of [`Send`] for [`Scanner`].
unsafe impl Send for ModuleOutputs<'_, '_> {}

impl<'a, 'r> ModuleOutputs<'a, 'r> {
fn new(ctx: &'a ScanContext<'r>) -> Self {
Self {
Expand Down

0 comments on commit 7576f30

Please sign in to comment.