I'm trying to implement a memory mapped file by combining os::MemoryMap
and fs::File
in some kind of RAII style. Consider the following example:
#![feature(fs, os, io, path, std_misc, core)]
use std::{io, os, mem, raw};
use std::io::{Seek};
use std::fs::{File};
use std::path::{Path};
use std::os::{MemoryMap};
use std::borrow::{Cow};
use std::error::{FromError};
use std::os::unix::{AsRawFd};
struct Mmapped {
file: File,
map: MemoryMap,
map_len: usize,
}
#[derive(Debug)]
enum Error {
IoError(io::Error),
MmapError(os::MapError),
}
impl FromError<io::Error> for Error {
fn from_error(err: io::Error) -> Error { Error::IoError(err) }
}
impl FromError<os::MapError> for Error {
fn from_error(err: os::MapError) -> Error { Error::MmapError(err) }
}
impl Mmapped {
fn new(filename: &str) -> Result<Mmapped, Error> {
let mut file = try!(File::open(Path::new(filename)));
let map_len = try!(file.seek(io::SeekFrom::End(0))) as usize;
let map = try!(MemoryMap::new(map_len, &[os::MapOption::MapReadable, os::MapOption::MapFd(file.as_raw_fd())]));
Ok(Mmapped { file: file, map: map, map_len: map_len })
}
unsafe fn as_string<'a>(&self) -> Cow<'a, String, str> {
String::from_utf8_lossy(mem::transmute(raw::Slice { data: self.map.data() as *const u8,
len: self.map_len }))
}
}
fn main() {
let m = Mmapped::new("test.txt").unwrap();
println!("File contents: {:?}", unsafe { m.as_string() });
}
It works, but compiler treats the file field in Mmapped object as dead code:
<anon>:13:5: 13:15 warning: struct field is never used: `file`, #[warn(dead_code)] on by default
<anon>:13 file: File,
^~~~~~~~~~
Could I be sure that it will not optimize it out, and file will be closed in new method? And is there any standard way to mark my field "not dead" code?
You can annotate the specific field to ignore the dead-code warning:
struct Mmapped {
#[allow(dead_code)]
file: File,
map: MemoryMap,
map_len: usize,
}
I don't believe that the optimizer will completely drop the field from the struct, and a quick look at the LLVM IR for a struct that has an unused String field shows that there is still space for that field and even calls the drop glue for that String.