diff --git a/src/msf/mod.rs b/src/msf/mod.rs index e00ca44..92b6db3 100644 --- a/src/msf/mod.rs +++ b/src/msf/mod.rs @@ -55,11 +55,14 @@ enum StreamTable<'s> { // Given the table location, we can access the stream table itself Available { - stream_table_view: Box>, + stream_table_view: Box + Send>, }, } -fn view<'s>(source: &mut dyn Source<'s>, page_list: &PageList) -> Result>> { +fn view<'s>( + source: &mut dyn Source<'s>, + page_list: &PageList, +) -> Result + Send + Sync>> { // view it let view = source.view(page_list.source_slices())?; @@ -120,7 +123,10 @@ mod big { } impl<'s, S: Source<'s>> BigMSF<'s, S> { - pub fn new(source: S, header_view: Box>) -> Result> { + pub fn new( + source: S, + header_view: Box + Send>, + ) -> Result> { let mut buf = ParseBuffer::from(header_view.as_slice()); let header: RawHeader = buf.parse()?; @@ -345,7 +351,7 @@ mod small { /// Represents a single Stream within the multi-stream file. #[derive(Debug)] pub struct Stream<'s> { - source_view: Box>, + source_view: Box + Send + Sync>, } impl<'s> Stream<'s> { @@ -380,7 +386,9 @@ fn header_matches(actual: &[u8], expected: &[u8]) -> bool { actual.len() >= expected.len() && &actual[0..expected.len()] == expected } -pub fn open_msf<'s, S: Source<'s> + 's>(mut source: S) -> Result + 's>> { +pub fn open_msf<'s, S: Source<'s> + Send + 's>( + mut source: S, +) -> Result + Send + 's>> { // map the header let mut header_location = PageList::new(4096); header_location.push(0); diff --git a/src/pdb.rs b/src/pdb.rs index b92f671..762ff82 100644 --- a/src/pdb.rs +++ b/src/pdb.rs @@ -34,7 +34,7 @@ const IPI_STREAM: u32 = 4; #[derive(Debug)] pub struct PDB<'s, S> { /// `msf` provides access to the underlying data streams - msf: Box + 's>, + msf: Box + Send + 's>, /// Memoize the `dbi::Header`, since it contains stream numbers we sometimes need dbi_header: Option, @@ -43,6 +43,14 @@ pub struct PDB<'s, S> { dbi_extra_streams: Option, } +// Assert that the PDB type is Send. +const _: fn() = || { + fn assert() {} + // Use a dummy *const () for `S` as that will be !Send and !Sync. + // In practice (e.g. to make a PDB) `S` will need to be Send, but it doesn't matter here. + assert::>(); +}; + impl<'s, S: Source<'s> + 's> PDB<'s, S> { /// Create a new `PDB` for a `Source`. /// @@ -56,7 +64,10 @@ impl<'s, S: Source<'s> + 's> PDB<'s, S> { /// * `Error::UnrecognizedFileFormat` if the `Source` does not appear to be a PDB file /// * `Error::IoError` if returned by the `Source` /// * `Error::PageReferenceOutOfRange`, `Error::InvalidPageSize` if the PDB file seems corrupt - pub fn open(source: S) -> Result> { + pub fn open(source: S) -> Result> + where + S: Send, + { Ok(PDB { msf: msf::open_msf(source)?, dbi_header: None, diff --git a/src/source.rs b/src/source.rs index 69dae13..47453ac 100644 --- a/src/source.rs +++ b/src/source.rs @@ -51,7 +51,10 @@ pub trait Source<'s>: fmt::Debug { /// /// Note that the SourceView's as_slice() method cannot fail, so `view()` is the time to raise /// IO errors. - fn view(&mut self, slices: &[SourceSlice]) -> Result>, io::Error>; + fn view( + &mut self, + slices: &[SourceSlice], + ) -> Result + Send + Sync>, io::Error>; } /// An owned, droppable, read-only view of the source file which can be referenced as a byte slice. @@ -81,7 +84,10 @@ impl<'s, T> Source<'s> for T where T: io::Read + io::Seek + fmt::Debug + 's, { - fn view(&mut self, slices: &[SourceSlice]) -> Result>, io::Error> { + fn view( + &mut self, + slices: &[SourceSlice], + ) -> Result + Send + Sync>, io::Error> { let len = slices.iter().fold(0, |acc, s| acc + s.size); let mut v = ReadView {