Skip to content

Commit

Permalink
Allow PDB to impl Send.
Browse files Browse the repository at this point in the history
  • Loading branch information
afranchuk committed Jul 6, 2023
1 parent b052964 commit 4a1f8f0
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 12 deletions.
22 changes: 15 additions & 7 deletions src/msf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,14 @@ enum StreamTable<'s> {

// Given the table location, we can access the stream table itself
Available {
stream_table_view: Box<dyn SourceView<'s>>,
stream_table_view: Box<dyn SourceView<'s> + Send>,
},
}

fn view<'s>(source: &mut dyn Source<'s>, page_list: &PageList) -> Result<Box<dyn SourceView<'s>>> {
fn view<'s>(
source: &mut dyn Source<'s>,
page_list: &PageList,
) -> Result<Box<dyn SourceView<'s> + Send + Sync>> {
// view it
let view = source.view(page_list.source_slices())?;

Expand Down Expand Up @@ -119,8 +122,11 @@ mod big {
stream_table: StreamTable<'s>,
}

impl<'s, S: Source<'s>> BigMSF<'s, S> {
pub fn new(source: S, header_view: Box<dyn SourceView<'_>>) -> Result<BigMSF<'s, S>> {
impl<'s, S: Source<'s> + Send> BigMSF<'s, S> {
pub fn new(
source: S,
header_view: Box<dyn SourceView<'_> + Send>,
) -> Result<BigMSF<'s, S>> {
let mut buf = ParseBuffer::from(header_view.as_slice());
let header: RawHeader = buf.parse()?;

Expand Down Expand Up @@ -316,7 +322,7 @@ mod big {
}
}

impl<'s, S: Source<'s>> Msf<'s, S> for BigMSF<'s, S> {
impl<'s, S: Source<'s> + Send> Msf<'s, S> for BigMSF<'s, S> {
fn get(&mut self, stream_number: u32, limit: Option<usize>) -> Result<Stream<'s>> {
// look up the stream
let mut page_list = self.look_up_stream(stream_number)?;
Expand Down Expand Up @@ -345,7 +351,7 @@ mod small {
/// Represents a single Stream within the multi-stream file.
#[derive(Debug)]
pub struct Stream<'s> {
source_view: Box<dyn SourceView<'s>>,
source_view: Box<dyn SourceView<'s> + Send + Sync>,
}

impl<'s> Stream<'s> {
Expand Down Expand Up @@ -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<Box<dyn Msf<'s, S> + 's>> {
pub fn open_msf<'s, S: Source<'s> + Send + 's>(
mut source: S,
) -> Result<Box<dyn Msf<'s, S> + Send + 's>> {
// map the header
let mut header_location = PageList::new(4096);
header_location.push(0);
Expand Down
14 changes: 11 additions & 3 deletions src/pdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<dyn Msf<'s, S> + 's>,
msf: Box<dyn Msf<'s, S> + Send + 's>,

/// Memoize the `dbi::Header`, since it contains stream numbers we sometimes need
dbi_header: Option<DBIHeader>,
Expand All @@ -43,7 +43,15 @@ pub struct PDB<'s, S> {
dbi_extra_streams: Option<DBIExtraStreams>,
}

impl<'s, S: Source<'s> + 's> PDB<'s, S> {
// Assert that the PDB type is Send.
const _: fn() = || {
fn assert<T: ?Sized + Send>() {}
// Use a dummy *const () for `S` as that will be !Send and !Sync.
// In practice to make a PDB `S` will need to be Send, but it doesn't matter here.
assert::<PDB<*const ()>>();
};

impl<'s, S: Source<'s> + Send + 's> PDB<'s, S> {
/// Create a new `PDB` for a `Source`.
///
/// `open()` accesses enough of the source file to find the MSF stream table. This usually
Expand Down Expand Up @@ -529,7 +537,7 @@ impl StreamIndex {
/// * `Error::PageReferenceOutOfRange` if the PDB file seems corrupt
pub fn get<'s, S>(self, pdb: &mut PDB<'s, S>) -> Result<Option<Stream<'s>>>
where
S: Source<'s> + 's,
S: Source<'s> + Send + 's,
{
pdb.raw_stream(self)
}
Expand Down
10 changes: 8 additions & 2 deletions src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Box<dyn SourceView<'s>>, io::Error>;
fn view(
&mut self,
slices: &[SourceSlice],
) -> Result<Box<dyn SourceView<'s> + Send + Sync>, io::Error>;
}

/// An owned, droppable, read-only view of the source file which can be referenced as a byte slice.
Expand Down Expand Up @@ -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<Box<dyn SourceView<'s>>, io::Error> {
fn view(
&mut self,
slices: &[SourceSlice],
) -> Result<Box<dyn SourceView<'s> + Send + Sync>, io::Error> {
let len = slices.iter().fold(0, |acc, s| acc + s.size);

let mut v = ReadView {
Expand Down

0 comments on commit 4a1f8f0

Please sign in to comment.