-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
14d22cb
commit 147e59b
Showing
5 changed files
with
202 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
use std::io; | ||
use std::ops::Deref; | ||
use std::sync::atomic::Ordering; | ||
|
||
use super::super::{co_io_result, from_nix_error, IoData}; | ||
use coroutine_impl::{co_cancel_data, CoroutineImpl, EventSource}; | ||
use io::AsIoData; | ||
use nix::unistd::read; | ||
use sync::delay_drop::DelayDrop; | ||
use yield_now::yield_with; | ||
|
||
pub struct FileRead<'a> { | ||
io_data: &'a IoData, | ||
buf: &'a mut [u8], | ||
can_drop: DelayDrop, | ||
} | ||
|
||
impl<'a> FileRead<'a> { | ||
pub fn new<T: AsIoData>(s: &'a T, offset: u64, buf: &'a mut [u8]) -> Self { | ||
FileRead { | ||
io_data: s.as_io_data(), | ||
buf, | ||
can_drop: DelayDrop::new(), | ||
} | ||
} | ||
|
||
#[inline] | ||
pub fn done(self) -> io::Result<usize> { | ||
loop { | ||
co_io_result()?; | ||
|
||
// clear the io_flag | ||
self.io_data.io_flag.store(false, Ordering::Relaxed); | ||
|
||
// finish the read operation | ||
match read(self.io_data.fd, self.buf).map_err(from_nix_error) { | ||
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {} | ||
ret => return ret, | ||
} | ||
|
||
if self.io_data.io_flag.swap(false, Ordering::Relaxed) { | ||
continue; | ||
} | ||
|
||
// the result is still WouldBlock, need to try again | ||
self.can_drop.reset(); | ||
yield_with(&self); | ||
} | ||
} | ||
} | ||
|
||
impl<'a> EventSource for FileRead<'a> { | ||
fn subscribe(&mut self, co: CoroutineImpl) { | ||
// when exit the scope the `can_drop` will be set to true | ||
let _g = self.can_drop.delay_drop(); | ||
|
||
let cancel = co_cancel_data(&co); | ||
// after register the coroutine, it's possible that other thread run it immediately | ||
// and cause the process after it invalid, this is kind of user and kernel competition | ||
// so we need to delay the drop of the EventSource, that's why _g is here | ||
self.io_data.co.swap(co, Ordering::Release); | ||
|
||
// there is event, re-run the coroutine | ||
if self.io_data.io_flag.load(Ordering::Acquire) { | ||
return self.io_data.schedule(); | ||
} | ||
|
||
// register the cancel io data | ||
cancel.set_io(self.io_data.deref().clone()); | ||
// re-check the cancel status | ||
if cancel.is_canceled() { | ||
unsafe { cancel.cancel() }; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
use std::io; | ||
use std::sync::atomic::Ordering; | ||
|
||
use super::super::{co_io_result, from_nix_error, IoData}; | ||
use coroutine_impl::{CoroutineImpl, EventSource}; | ||
use io::AsIoData; | ||
use nix::unistd::write; | ||
use sync::delay_drop::DelayDrop; | ||
use yield_now::yield_with; | ||
|
||
pub struct FileWrite<'a> { | ||
io_data: &'a IoData, | ||
buf: &'a [u8], | ||
can_drop: DelayDrop, | ||
} | ||
|
||
impl<'a> FileWrite<'a> { | ||
pub fn new<T: AsIoData>(s: &'a T, offset: u64, buf: &'a [u8]) -> Self { | ||
FileWrite { | ||
io_data: s.as_io_data(), | ||
buf, | ||
can_drop: DelayDrop::new(), | ||
} | ||
} | ||
|
||
#[inline] | ||
pub fn done(self) -> io::Result<usize> { | ||
loop { | ||
co_io_result()?; | ||
|
||
// clear the io_flag | ||
self.io_data.io_flag.store(false, Ordering::Relaxed); | ||
|
||
match write(self.io_data.fd, self.buf).map_err(from_nix_error) { | ||
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {} | ||
ret => return ret, | ||
} | ||
|
||
if self.io_data.io_flag.swap(false, Ordering::Relaxed) { | ||
continue; | ||
} | ||
|
||
// the result is still WouldBlock, need to try again | ||
self.can_drop.reset(); | ||
yield_with(&self); | ||
} | ||
} | ||
} | ||
|
||
impl<'a> EventSource for FileWrite<'a> { | ||
fn subscribe(&mut self, co: CoroutineImpl) { | ||
let _g = self.can_drop.delay_drop(); | ||
self.io_data.co.swap(co, Ordering::Release); | ||
|
||
// there is event, re-run the coroutine | ||
if self.io_data.io_flag.load(Ordering::Acquire) { | ||
self.io_data.schedule(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
mod fs_read; | ||
mod fs_write; | ||
|
||
pub use self::fs_read::FileRead; | ||
pub use self::fs_write::FileWrite; | ||
|
||
use std::fs::{File, OpenOptions}; | ||
use std::io; | ||
use std::path::Path; | ||
|
||
pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> { | ||
File::open(path) | ||
} | ||
|
||
pub fn create<P: AsRef<Path>>(path: P) -> io::Result<File> { | ||
File::create(path) | ||
} | ||
|
||
pub fn open_with_options<P: AsRef<Path>>(options: &mut OpenOptions, path: P) -> io::Result<File> { | ||
options.open(path.as_ref()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters